X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;ds=sidebyside;f=servers%2Fslapd%2Fback-bdb%2Fmodrdn.c;h=c93897525a528b882676180f5c36d6d3949ead93;hb=95d472aa9830a031821f2c6274aff38aa4eb0990;hp=1497a19822f5ac2c82003eea9f37171ce3635837;hpb=da6d9eb0463255782f3fa70c61fd958d94c048cf;p=openldap diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 1497a19822..c93897525a 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -2,7 +2,7 @@ /* $OpenLDAP$ */ /* This work is part of OpenLDAP Software . * - * Copyright 2000-2007 The OpenLDAP Foundation. + * Copyright 2000-2008 The OpenLDAP Foundation. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -46,7 +46,6 @@ bdb_modrdn( Operation *op, SlapReply *rs ) int manageDSAit = get_manageDSAit( op ); - u_int32_t locker = 0; DB_LOCK lock, plock, nplock; int num_retries = 0; @@ -134,7 +133,8 @@ retry: /* transaction retry */ rs->sr_err = TXN_ABORT( ltid ); ltid = NULL; - op->o_private = NULL; + LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); + opinfo.boi_oe.oe_key = NULL; op->o_do_not_cache = opinfo.boi_acl_cache; if( rs->sr_err != 0 ) { rs->sr_err = LDAP_OTHER; @@ -163,18 +163,15 @@ retry: /* transaction retry */ goto return_results; } - locker = TXN_ID ( ltid ); - - opinfo.boi_bdb = op->o_bd; + opinfo.boi_oe.oe_key = bdb; opinfo.boi_txn = ltid; - opinfo.boi_locker = locker; opinfo.boi_err = 0; opinfo.boi_acl_cache = op->o_do_not_cache; - op->o_private = &opinfo; + LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.boi_oe, oe_next ); /* get entry */ rs->sr_err = bdb_dn2entry( op, ltid, &op->o_req_ndn, &ei, 1, - locker, &lock ); + &lock ); switch( rs->sr_err ) { case 0: @@ -303,13 +300,13 @@ retry: /* transaction retry */ dnParent( &e->e_nname, &p_ndn ); } np_ndn = &p_ndn; - if ( p_ndn.bv_len != 0 ) { + eip = ei->bei_parent; + if ( eip && eip->bei_id ) { /* Make sure parent entry exist and we can write its * children. */ - eip = ei->bei_parent; rs->sr_err = bdb_cache_find_id( op, ltid, - eip->bei_id, &eip, 0, locker, &plock ); + eip->bei_id, &eip, 0, &plock ); switch( rs->sr_err ) { case 0: @@ -418,7 +415,7 @@ retry: /* transaction retry */ /* Get Entry with dn=newSuperior. Does newSuperior exist? */ rs->sr_err = bdb_dn2entry( op, ltid, np_ndn, - &neip, 0, locker, &nplock ); + &neip, 0, &nplock ); switch( rs->sr_err ) { case 0: np = neip->bei_e; @@ -542,6 +539,8 @@ retry: /* transaction retry */ struct berval bv = {0, NULL}; dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx ); ber_dupbv( &new_ndn, &bv ); + /* FIXME: why not call dnNormalize() w/o ctx? */ + op->o_tmpfree( bv.bv_val, op->o_tmpmemctx ); } Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(bdb_modrdn) ": new ndn=%s\n", @@ -558,6 +557,9 @@ retry: /* transaction retry */ case DB_NOTFOUND: break; case 0: + /* Allow rename to same DN */ + if ( nei == ei ) + break; rs->sr_err = LDAP_ALREADY_EXISTS; goto return_results; default: @@ -735,12 +737,14 @@ retry: /* transaction retry */ } else { rs->sr_err = LDAP_X_NO_OPERATION; ltid = NULL; + /* Only free attrs if they were dup'd. */ + if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL; goto return_results; } } else { rc = bdb_cache_modrdn( bdb, e, &op->orr_nnewrdn, &dummy, neip, - locker, &lock ); + ltid, &lock ); switch( rc ) { case DB_LOCK_DEADLOCK: case DB_LOCK_NOTGRANTED: @@ -758,7 +762,8 @@ retry: /* transaction retry */ } ltid = NULL; - op->o_private = NULL; + LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); + opinfo.boi_oe.oe_key = NULL; if( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, @@ -817,7 +822,9 @@ done: if( ltid != NULL ) { TXN_ABORT( ltid ); } - op->o_private = NULL; + if ( opinfo.boi_oe.oe_key ) { + LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.boi_oe, OpExtra, oe_next ); + } if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) { slap_sl_free( (*preread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );