size_t textlen = sizeof textbuf;
DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo;
- Entry dummy, *save;
+ Entry dummy = {0};
ID id;
int num_retries = 0;
+ LDAPControl **preread_ctrl = NULL;
+ LDAPControl **postread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
int num_ctrls = 0;
int parent_is_glue = 0;
int parent_is_leaf = 0;
+ ctrls[num_ctrls] = NULL;
+
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ENTRY, "==>bdb_modrdn(%s,%s,%s)\n",
op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
if( 0 ) {
retry: /* transaction retry */
+ if ( dummy.e_attrs ) {
+ attrs_free( dummy.e_attrs );
+ dummy.e_attrs = NULL;
+ }
if (e != NULL) {
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
e = NULL;
isroot = be_isroot( op );
if ( ! isroot ) {
if ( be_issuffix( op->o_bd, (struct berval *)&slap_empty_bv )
- || be_isupdate( op ) || syncrepl_isupdate( op ) ) {
+ || be_shadow_update( op ) ) {
p = (Entry *)&slap_entry_root;
}
if( op->o_preread ) {
+ if( preread_ctrl == NULL ) {
+ preread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
if( slap_read_controls( op, rs, e,
- &slap_pre_read_bv, &ctrls[num_ctrls] ) )
+ &slap_pre_read_bv, preread_ctrl ) )
{
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1,
#endif
goto return_results;
}
- ctrls[++num_ctrls] = NULL;
- op->o_preread = 0; /* prevent redo on retry */
}
/* nested transaction */
goto return_results;
}
- dummy = *e;
- save = e;
- e = &dummy;
-
- /* delete old one */
+ /* delete old DN */
rs->sr_err = bdb_dn2id_delete( op, lt2, eip, e );
if ( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
goto return_results;
}
- /* Binary format uses a single contiguous block, cannot
- * free individual fields. But if a previous modrdn has
- * already happened, must free the names. The frees are
- * done in bdb_cache_modrdn().
- */
- if( e->e_nname.bv_val < e->e_bv.bv_val ||
- e->e_nname.bv_val > e->e_bv.bv_val + e->e_bv.bv_len )
- {
- e->e_name.bv_val = NULL;
- e->e_nname.bv_val = NULL;
- }
- e->e_name = new_dn;
- e->e_nname = new_ndn;
- new_dn.bv_val = NULL;
- new_ndn.bv_val = NULL;
+ /* copy the entry, then override some fields */
+ dummy = *e;
+ dummy.e_name = new_dn;
+ dummy.e_nname = new_ndn;
+ dummy.e_attrs = NULL;
- /* add new one */
- rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, e );
+ /* add new DN */
+ rs->sr_err = bdb_dn2id_add( op, lt2, neip ? neip : eip, &dummy );
if ( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
goto return_results;
}
+ dummy.e_attrs = e->e_attrs;
+
if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop && !op->o_no_psearch ) {
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_PREMODIFY );
+ rc = bdb_psearch( op, rs, ps_list, &dummy, LDAP_PSEARCH_BY_PREMODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
+
/* modify entry */
- rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e,
+ rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], &dummy,
&rs->sr_text, textbuf, textlen );
if( rs->sr_err != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING
if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.boi_err ) {
rs->sr_err = opinfo.boi_err;
}
+ if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
switch( rs->sr_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto return_results;
}
- if( op->o_postread ) {
- if( slap_read_controls( op, rs, e,
- &slap_post_read_bv, &ctrls[num_ctrls] ) )
- {
-#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, DETAIL1,
- "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
-#else
- Debug( LDAP_DEBUG_TRACE,
- "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
-#endif
- goto return_results;
- }
- ctrls[++num_ctrls] = NULL;
- op->o_postread = 0; /* prevent redo on retry */
- /* FIXME: should read entry on the last retry */
- }
-
/* id2entry index */
- rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
+ rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
if ( rs->sr_err != 0 ) {
#ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, ERR,
goto return_results;
}
- bdb_cache_find_id( op, lt2, eip->bei_id, &eip, 0, locker, &plock );
- if ( eip ) p = eip->bei_e;
- if ( p_ndn.bv_len != 0 ) {
- parent_is_glue = is_entry_glue(p);
- rs->sr_err = bdb_cache_children( op, lt2, p );
- if ( rs->sr_err != DB_NOTFOUND ) {
- switch( rs->sr_err ) {
- case DB_LOCK_DEADLOCK:
- case DB_LOCK_NOTGRANTED:
- goto retry;
- case 0:
- break;
- default:
+ if ( p_ndn.bv_len != 0 ) {
+ parent_is_glue = is_entry_glue(p);
+ rs->sr_err = bdb_cache_children( op, lt2, p );
+ if ( rs->sr_err != DB_NOTFOUND ) {
+ switch( rs->sr_err ) {
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ goto retry;
+ case 0:
+ break;
+ default:
#ifdef NEW_LOGGING
- LDAP_LOG ( OPERATION, ERR,
- "<=- bdb_modrdn: has_children failed %s (%d)\n",
- db_strerror(rs->sr_err), rs->sr_err, 0 );
+ LDAP_LOG ( OPERATION, ERR,
+ "<=- bdb_modrdn: has_children failed %s (%d)\n",
+ db_strerror(rs->sr_err), rs->sr_err, 0 );
#else
- Debug(LDAP_DEBUG_ARGS,
- "<=- bdb_modrdn: has_children failed: %s (%d)\n",
- db_strerror(rs->sr_err), rs->sr_err, 0 );
+ Debug(LDAP_DEBUG_ARGS,
+ "<=- bdb_modrdn: has_children failed: %s (%d)\n",
+ db_strerror(rs->sr_err), rs->sr_err, 0 );
#endif
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "internal error";
- goto return_results;
- }
- parent_is_leaf = 1;
- }
- bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
- p = NULL;
- }
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto return_results;
+ }
+ parent_is_leaf = 1;
+ }
+ bdb_unlocked_cache_return_entry_r(&bdb->bi_cache, p);
+ p = NULL;
+ }
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
rs->sr_err = LDAP_OTHER;
}
}
+ if( op->o_postread ) {
+ if( postread_ctrl == NULL ) {
+ postread_ctrl = &ctrls[num_ctrls++];
+ ctrls[num_ctrls] = NULL;
+ }
+ if( slap_read_controls( op, rs, &dummy,
+ &slap_post_read_bv, postread_ctrl ) )
+ {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, DETAIL1,
+ "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "<=- bdb_modrdn: post-read failed!\n", 0, 0, 0 );
+#endif
+ goto return_results;
+ }
+ }
+
if( op->o_noop ) {
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
rs->sr_text = "txn_abort (no-op) failed";
}
} else {
- bdb_cache_modrdn( save, &op->orr_nnewrdn, e, neip,
+ rc = bdb_cache_modrdn( e, &op->orr_nnewrdn, &dummy, neip,
bdb->bi_dbenv, locker, &lock );
+ switch( rc ) {
+ case DB_LOCK_DEADLOCK:
+ case DB_LOCK_NOTGRANTED:
+ goto retry;
+ }
+ dummy.e_attrs = NULL;
+ new_dn.bv_val = NULL;
+ new_ndn.bv_val = NULL;
if ( LDAP_STAILQ_EMPTY( &op->o_bd->be_syncinfo )) {
if ( ctxcsn_added ) {
if ( rs->sr_err == LDAP_SUCCESS ) {
/* Loop through in-scope entries for each psearch spec */
- ldap_pvt_thread_rdwr_rlock( &bdb->bi_pslist_rwlock );
+ ldap_pvt_thread_rdwr_wlock( &bdb->bi_pslist_rwlock );
LDAP_LIST_FOREACH ( ps_list, &bdb->bi_psearch_list, o_ps_link ) {
- bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ rc = bdb_psearch( op, rs, ps_list, e, LDAP_PSEARCH_BY_MODIFY );
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
}
- ldap_pvt_thread_rdwr_runlock( &bdb->bi_pslist_rwlock );
pm_list = LDAP_LIST_FIRST(&op->o_pm_list);
while ( pm_list != NULL ) {
- bdb_psearch(op, rs, pm_list->ps_op,
+ rc = bdb_psearch(op, rs, pm_list->ps_op,
e, LDAP_PSEARCH_BY_SCOPEOUT);
+ if ( rc ) {
+#ifdef NEW_LOGGING
+ LDAP_LOG ( OPERATION, ERR,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#else
+ Debug( LDAP_DEBUG_TRACE,
+ "bdb_modrdn: persistent search failed (%d,%d)\n",
+ rc, rs->sr_err, 0 );
+#endif
+ }
pm_prev = pm_list;
LDAP_LIST_REMOVE ( pm_list, ps_link );
pm_list = LDAP_LIST_NEXT ( pm_list, ps_link );
ch_free( pm_prev );
}
+ ldap_pvt_thread_rdwr_wunlock( &bdb->bi_pslist_rwlock );
}
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
if( num_ctrls ) rs->sr_ctrls = ctrls;
return_results:
+ if ( dummy.e_attrs ) {
+ attrs_free( dummy.e_attrs );
+ }
send_ldap_result( op, rs );
if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
op->o_private = NULL;
}
+ if( preread_ctrl != NULL ) {
+ slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *preread_ctrl, &op->o_tmpmemctx );
+ }
+ if( postread_ctrl != NULL ) {
+ slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, &op->o_tmpmemctx );
+ slap_sl_free( *postread_ctrl, &op->o_tmpmemctx );
+ }
return rs->sr_err;
}