]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/modrdn.c
Fix prev cache.c commit
[openldap] / servers / slapd / back-bdb / modrdn.c
index 23d28810af3d4262c9c234a5a1bcab458ef72d71..117cb05c25b2d0b939799a98b2c21e8930f1104c 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2000-2006 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,7 @@ bdb_modrdn( Operation *op, SlapReply *rs )
 
        int             manageDSAit = get_manageDSAit( op );
 
-       u_int32_t       locker = 0;
+       BDB_LOCKER      locker = 0;
        DB_LOCK         lock, plock, nplock;
 
        int             num_retries = 0;
@@ -61,6 +61,10 @@ bdb_modrdn( Operation        *op, SlapReply *rs )
        int parent_is_glue = 0;
        int parent_is_leaf = 0;
 
+#ifdef LDAP_X_TXN
+       int settle = 0;
+#endif
+
        Debug( LDAP_DEBUG_TRACE, "==>" LDAP_XSTRING(bdb_modrdn) "(%s,%s,%s)\n",
                op->o_req_dn.bv_val,op->oq_modrdn.rs_newrdn.bv_val,
                op->oq_modrdn.rs_newSup ? op->oq_modrdn.rs_newSup->bv_val : "NULL" );
@@ -69,11 +73,15 @@ bdb_modrdn( Operation       *op, SlapReply *rs )
        if( op->o_txnSpec ) {
                /* acquire connection lock */
                ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
-               if( op->o_conn->c_txn == 0 ) {
+               if( op->o_conn->c_txn == CONN_TXN_INACTIVE ) {
                        rs->sr_text = "invalid transaction identifier";
                        rs->sr_err = LDAP_X_TXN_ID_INVALID;
                        goto txnReturn;
+               } else if( op->o_conn->c_txn == CONN_TXN_SETTLE ) {
+                       settle=1;
+                       goto txnReturn;
                }
+
                if( op->o_conn->c_txn_backend == NULL ) {
                        op->o_conn->c_txn_backend = op->o_bd;
 
@@ -86,14 +94,16 @@ bdb_modrdn( Operation       *op, SlapReply *rs )
                /* insert operation into transaction */
 
                rs->sr_text = "transaction specified";
-               rs->sr_err = LDAP_SUCCESS;
+               rs->sr_err = LDAP_X_TXN_SPECIFY_OKAY;
 
 txnReturn:
                /* release connection lock */
                ldap_pvt_thread_mutex_unlock( &op->o_conn->c_mutex );
 
-               send_ldap_result( op, rs );
-               return rs->sr_err;
+               if( !settle ) {
+                       send_ldap_result( op, rs );
+                       return rs->sr_err;
+               }
        }
 #endif
 
@@ -157,7 +167,6 @@ retry:      /* transaction retry */
 
        opinfo.boi_bdb = op->o_bd;
        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;
@@ -293,11 +302,11 @@ 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 );
 
@@ -532,6 +541,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",
@@ -539,7 +550,7 @@ retry:      /* transaction retry */
 
        /* Shortcut the search */
        nei = neip ? neip : eip;
-       rs->sr_err = bdb_cache_find_ndn ( op, ltid, &new_ndn, &nei );
+       rs->sr_err = bdb_cache_find_ndn ( op, locker, &new_ndn, &nei );
        if ( nei ) bdb_cache_entryinfo_unlock( nei );
        switch( rs->sr_err ) {
        case DB_LOCK_DEADLOCK:
@@ -548,6 +559,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:
@@ -568,8 +582,12 @@ retry:     /* transaction retry */
                {
                        Debug( LDAP_DEBUG_TRACE,        
                                "<=- " LDAP_XSTRING(bdb_modrdn)
-                               ": post-read failed!\n", 0, 0, 0 );
-                       goto return_results;
+                               ": pre-read failed!\n", 0, 0, 0 );
+                       if ( op->o_preread & SLAP_CONTROL_CRITICAL ) {
+                               /* FIXME: is it correct to abort
+                                * operation if control fails? */
+                               goto return_results;
+                       }
                }                   
        }
 
@@ -707,7 +725,11 @@ retry:     /* transaction retry */
                        Debug( LDAP_DEBUG_TRACE,        
                                "<=- " LDAP_XSTRING(bdb_modrdn)
                                ": post-read failed!\n", 0, 0, 0 );
-                       goto return_results;
+                       if ( op->o_postread & SLAP_CONTROL_CRITICAL ) {
+                               /* FIXME: is it correct to abort
+                                * operation if control fails? */
+                               goto return_results;
+                       }
                }                   
        }
 
@@ -717,6 +739,8 @@ 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;
                }
 
@@ -765,7 +789,7 @@ return_results:
        }
        send_ldap_result( op, rs );
 
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp_kbyte ) {
                TXN_CHECKPOINT( bdb->bi_dbenv,
                        bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
        }
@@ -801,11 +825,11 @@ done:
        }
        op->o_private = NULL;
 
-       if( preread_ctrl != NULL ) {
+       if( preread_ctrl != NULL && (*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 ) {
+       if( postread_ctrl != NULL && (*postread_ctrl) != NULL ) {
                slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
                slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
        }