]> git.sur5r.net Git - openldap/commitdiff
ITS#6056 refint_repair can be called multiple times for the same
authorHoward Chu <hyc@openldap.org>
Thu, 4 Jun 2009 18:05:19 +0000 (18:05 +0000)
committerHoward Chu <hyc@openldap.org>
Thu, 4 Jun 2009 18:05:19 +0000 (18:05 +0000)
queued item, must not free queue itself

servers/slapd/overlays/refint.c

index 88ada0c49619f21714c65abf588288e43b17d989..a9c0e50c5be66dd42594a0be46713543148d85de 100644 (file)
@@ -547,7 +547,7 @@ refint_repair(
        refint_data     *id,
        refint_q        *rq )
 {
-       dependent_data  *dp, *dp_next;
+       dependent_data  *dp;
        int             rc;
 
        op->o_callback->sc_response = refint_search_cb;
@@ -586,13 +586,11 @@ refint_repair(
         *
         */
 
-       for ( dp = rq->attrs; dp; dp = dp_next ) {
+       for ( dp = rq->attrs; dp; dp = dp->next ) {
                Operation       op2 = *op;
                SlapReply       rs2 = { 0 };
                refint_attrs    *ra;
-               Modifications   *m, *first = NULL;
-
-               dp_next = dp->next;
+               Modifications   *m;
 
                op2.o_tag = LDAP_REQ_MODIFY;
                op2.orm_modlist = NULL;
@@ -603,21 +601,18 @@ refint_repair(
                        Debug( LDAP_DEBUG_TRACE,
                                "refint_repair: no backend for DN %s!\n",
                                dp->dn.bv_val, 0, 0 );
-                       return 0;
+                       continue;
                }
 
                rs2.sr_type = REP_RESULT;
-               for ( ra = dp->attrs; ra; ra = dp->attrs ) {
+               for ( ra = dp->attrs; ra; ra = ra->next ) {
                        size_t  len;
 
-                       dp->attrs = ra->next;
                        /* Set our ModifiersName */
                        if ( SLAP_LASTMOD( op->o_bd ) ) {
                                m = op2.o_tmpalloc( sizeof(Modifications) +
                                        4*sizeof(BerValue), op2.o_tmpmemctx );
                                m->sml_next = op2.orm_modlist;
-                               if ( !first )
-                                       first = m;
                                op2.orm_modlist = m;
                                m->sml_op = LDAP_MOD_REPLACE;
                                m->sml_flags = SLAP_MOD_INTERNAL;
@@ -642,8 +637,6 @@ refint_repair(
 
                                m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
                                m->sml_next = op2.orm_modlist;
-                               if ( !first )
-                                       first = m;
                                op2.orm_modlist = m;
                                m->sml_op = LDAP_MOD_ADD;
                                m->sml_flags = 0;
@@ -656,9 +649,6 @@ refint_repair(
                                        BER_BVZERO( &m->sml_nvalues[1] );
                                        m->sml_numvals = 1;
                                        if ( BER_BVISEMPTY( &rq->newdn ) ) {
-                                               op2.o_tmpfree( ra, op2.o_tmpmemctx );
-                                               ra = dp->attrs;
-                                               dp->attrs = ra->next;
                                                m->sml_values[0] = id->nothing;
                                                m->sml_nvalues[0] = id->nnothing;
                                        } else {
@@ -680,8 +670,6 @@ refint_repair(
                        m = op2.o_tmpalloc( len, op2.o_tmpmemctx );
                        m->sml_next = op2.orm_modlist;
                        op2.orm_modlist = m;
-                       if ( !first )
-                               first = m;
                        m->sml_op = LDAP_MOD_DELETE;
                        m->sml_flags = 0;
                        m->sml_desc = ra->attr;
@@ -699,7 +687,6 @@ refint_repair(
                                m->sml_nvalues = ra->old_nvals;
                                m->sml_numvals = ra->ra_numvals;
                        }
-                       op2.o_tmpfree( ra, op2.o_tmpmemctx );
                }
 
                op2.o_dn = op2.o_bd->be_rootdn;
@@ -713,17 +700,8 @@ refint_repair(
 
                while ( ( m = op2.orm_modlist ) ) {
                        op2.orm_modlist = m->sml_next;
-                       if ( m->sml_values && m->sml_values != (BerVarray)(m+1) ) {
-                               ber_bvarray_free_x( m->sml_values, op2.o_tmpmemctx );
-                               ber_bvarray_free_x( m->sml_nvalues, op2.o_tmpmemctx );
-                       }
                        op2.o_tmpfree( m, op2.o_tmpmemctx );
-                       if ( m == first ) break;
                }
-               slap_mods_free( op2.orm_modlist, 1 );
-               op2.o_tmpfree( dp->ndn.bv_val, op2.o_tmpmemctx );
-               op2.o_tmpfree( dp->dn.bv_val, op2.o_tmpmemctx );
-               op2.o_tmpfree( dp, op2.o_tmpmemctx );
        }
 
        return 0;
@@ -776,6 +754,9 @@ refint_qtask( void *ctx, void *arg )
        }
 
        for (;;) {
+               dependent_data  *dp, *dp_next;
+               refint_attrs *ra, *ra_next;
+
                /* Dequeue an op */
                ldap_pvt_thread_mutex_lock( &id->qmutex );
                rq = id->qhead;
@@ -829,6 +810,21 @@ refint_qtask( void *ctx, void *arg )
                        }
                }
 
+               for ( dp = rq->attrs; dp; dp = dp_next ) {
+                       dp_next = dp->next;
+                       for ( ra = dp->attrs; ra; ra = ra_next ) {
+                               ra_next = ra->next;
+                               ber_bvarray_free_x( ra->new_nvals, op->o_tmpmemctx );
+                               ber_bvarray_free_x( ra->new_vals, op->o_tmpmemctx );
+                               ber_bvarray_free_x( ra->old_nvals, op->o_tmpmemctx );
+                               ber_bvarray_free_x( ra->old_vals, op->o_tmpmemctx );
+                               op->o_tmpfree( ra, op->o_tmpmemctx );
+                       }
+                       op->o_tmpfree( dp->ndn.bv_val, op->o_tmpmemctx );
+                       op->o_tmpfree( dp->dn.bv_val, op->o_tmpmemctx );
+                       op->o_tmpfree( dp, op->o_tmpmemctx );
+               }
+
                if ( !BER_BVISNULL( &rq->newndn )) {
                        ch_free( rq->newndn.bv_val );
                        ch_free( rq->newdn.bv_val );