]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/add.c
Import ITS#4439 (slapd not responding) fix for BDB/HDB cache from HEAD
[openldap] / servers / slapd / back-bdb / add.c
index 227652077e1258978d857763b6d58426693c4226..cd37908a20a8f29e479e798f8d1af21a60d3884a 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2000-2005 The OpenLDAP Foundation.
+ * Copyright 2000-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -34,9 +34,7 @@ bdb_add(Operation *op, SlapReply *rs )
        AttributeDescription *entry = slap_schema.si_ad_entry;
        DB_TXN          *ltid = NULL, *lt2;
        struct bdb_op_info opinfo = {0};
-#ifdef BDB_SUBENTRIES
        int subentry;
-#endif
        u_int32_t       locker = 0;
        DB_LOCK         lock;
 
@@ -51,6 +49,10 @@ bdb_add(Operation *op, SlapReply *rs )
 
        ctrls[num_ctrls] = 0;
 
+       /* add opattrs to shadow as well, only missing attrs will actually
+        * be added; helps compatibility with older OL versions */
+       slap_add_opattrs( op, &rs->sr_text, textbuf, textlen, 1 );
+
        /* check entry's schema */
        rs->sr_err = entry_schema_check( op, op->oq_add.rs_e, NULL,
                get_manageDIT(op), &rs->sr_text, textbuf, textlen );
@@ -61,9 +63,7 @@ bdb_add(Operation *op, SlapReply *rs )
                goto return_results;
        }
 
-#ifdef BDB_SUBENTRIES
        subentry = is_entry_subentry( op->oq_add.rs_e );
-#endif
 
        /*
         * acquire an ID outside of the operation transaction
@@ -99,7 +99,6 @@ retry:        /* transaction retry */
                        rs->sr_err = SLAPD_ABANDON;
                        goto return_results;
                }
-               ldap_pvt_thread_yield();
                bdb_trans_backoff( ++num_retries );
        }
 
@@ -170,14 +169,8 @@ retry:     /* transaction retry */
                                "does not exist\n", 0, 0, 0 );
 
                        rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-
-                       ber_bvarray_free( rs->sr_ref );
-                       op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
-                       rs->sr_ref = NULL;
-                       rs->sr_matched = NULL;
-
-                       goto done;
+                       rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+                       goto return_results;
                }
 
                rs->sr_err = access_allowed( op, p,
@@ -198,7 +191,6 @@ retry:      /* transaction retry */
                        goto return_results;;
                }
 
-#ifdef BDB_SUBENTRIES
                if ( is_entry_subentry( p ) ) {
                        /* parent is a subentry, don't allow add */
                        Debug( LDAP_DEBUG_TRACE,
@@ -208,7 +200,6 @@ retry:      /* transaction retry */
                        rs->sr_text = "parent is a subentry";
                        goto return_results;;
                }
-#endif
                if ( is_entry_alias( p ) ) {
                        /* parent is an alias, don't allow add */
                        Debug( LDAP_DEBUG_TRACE,
@@ -221,30 +212,24 @@ retry:    /* transaction retry */
 
                if ( is_entry_referral( p ) ) {
                        /* parent is a referral, don't allow add */
-                       rs->sr_matched = p->e_name.bv_val;
+                       rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
+                               op->o_tmpmemctx );
                        rs->sr_ref = get_entry_referrals( op, p );
-
+                       bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
+                       p = NULL;
                        Debug( LDAP_DEBUG_TRACE,
                                LDAP_XSTRING(bdb_add) ": parent is referral\n",
                                0, 0, 0 );
 
                        rs->sr_err = LDAP_REFERRAL;
-                       send_ldap_result( op, rs );
-
-                       ber_bvarray_free( rs->sr_ref );
-                       bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
-                       rs->sr_ref = NULL;
-                       rs->sr_matched = NULL;
-                       p = NULL;
-                       goto done;
+                       rs->sr_flags = REP_MATCHED_MUSTBEFREED | REP_REF_MUSTBEFREED;
+                       goto return_results;
                }
 
-#ifdef BDB_SUBENTRIES
                if ( subentry ) {
                        /* FIXME: */
                        /* parent must be an administrative point of the required kind */
                }
-#endif
 
                /* free parent and reader lock */
                bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
@@ -267,14 +252,6 @@ retry:     /* transaction retry */
                }
        }
 
-       if ( get_assert( op ) &&
-               ( test_filter( op, op->oq_add.rs_e, get_assertion( op ))
-                       != LDAP_COMPARE_TRUE ))
-       {
-               rs->sr_err = LDAP_ASSERTION_FAILED;
-               goto return_results;
-       }
-
        rs->sr_err = access_allowed( op, op->oq_add.rs_e,
                entry, NULL, ACL_WADD, NULL );
 
@@ -326,11 +303,11 @@ retry:    /* transaction retry */
                goto return_results;
        }
 
-       /* id2entry index */
-       rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->oq_add.rs_e );
-       if ( rs->sr_err != 0 ) {
+       /* attribute indexes */
+       rs->sr_err = bdb_index_entry_add( op, lt2, op->oq_add.rs_e );
+       if ( rs->sr_err != LDAP_SUCCESS ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": id2entry_add failed\n",
+                       LDAP_XSTRING(bdb_add) ": index_entry_add failed\n",
                        0, 0, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
@@ -339,15 +316,15 @@ retry:    /* transaction retry */
                default:
                        rs->sr_err = LDAP_OTHER;
                }
-               rs->sr_text = "entry store failed";
+               rs->sr_text = "index generation failed";
                goto return_results;
        }
 
-       /* attribute indexes */
-       rs->sr_err = bdb_index_entry_add( op, lt2, op->oq_add.rs_e );
-       if ( rs->sr_err != LDAP_SUCCESS ) {
+       /* id2entry index */
+       rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->oq_add.rs_e );
+       if ( rs->sr_err != 0 ) {
                Debug( LDAP_DEBUG_TRACE,
-                       LDAP_XSTRING(bdb_add) ": index_entry_add failed\n",
+                       LDAP_XSTRING(bdb_add) ": id2entry_add failed\n",
                        0, 0, 0 );
                switch( rs->sr_err ) {
                case DB_LOCK_DEADLOCK:
@@ -356,9 +333,10 @@ retry:     /* transaction retry */
                default:
                        rs->sr_err = LDAP_OTHER;
                }
-               rs->sr_text = "index generation failed";
+               rs->sr_text = "entry store failed";
                goto return_results;
        }
+
        if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
                rs->sr_err = LDAP_OTHER;
                rs->sr_text = "txn_commit(2) failed";
@@ -385,7 +363,8 @@ retry:      /* transaction retry */
                if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
                        rs->sr_text = "txn_abort (no-op) failed";
                } else {
-                       rs->sr_err = LDAP_NO_OPERATION;
+                       rs->sr_err = LDAP_X_NO_OPERATION;
+                       ltid = NULL;
                        goto return_results;
                }
 
@@ -393,6 +372,7 @@ retry:      /* transaction retry */
                struct berval nrdn;
                Entry *e = entry_dup( op->ora_e );
 
+               /* pick the RDN if not suffix; otherwise pick the entire DN */
                if (pdn.bv_len) {
                        nrdn.bv_val = e->e_nname.bv_val;
                        nrdn.bv_len = pdn.bv_val - op->ora_e->e_nname.bv_val - 1;
@@ -430,22 +410,21 @@ retry:    /* transaction retry */
 
 return_results:
        send_ldap_result( op, rs );
+       slap_graduate_commit_csn( op );
 
-       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
-               ldap_pvt_thread_yield();
-               TXN_CHECKPOINT( bdb->bi_dbenv,
-                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
-       }
-
-done:
        if( ltid != NULL ) {
                TXN_ABORT( ltid );
-               op->o_private = NULL;
        }
+       op->o_private = NULL;
 
        if( postread_ctrl != NULL ) {
                slap_sl_free( (*postread_ctrl)->ldctl_value.bv_val, op->o_tmpmemctx );
                slap_sl_free( *postread_ctrl, op->o_tmpmemctx );
        }
+
+       if( rs->sr_err == LDAP_SUCCESS && bdb->bi_txn_cp ) {
+               TXN_CHECKPOINT( bdb->bi_dbenv,
+                       bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min, 0 );
+       }
        return rs->sr_err;
 }