AttributeDescription *entry = slap_schema.si_ad_entry;
MDB_txn *txn = NULL;
ID eid = NOID, pid = 0;
- struct mdb_op_info opinfo = {{{ 0 }}};
+ mdb_op_info opinfo = {{{ 0 }}}, *moi = &opinfo;
int subentry;
int success;
subentry = is_entry_subentry( op->ora_e );
/* begin transaction */
- rs->sr_err = mdb_txn_begin( mdb->mi_dbenv, 0, &txn );
+ rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
goto return_results;
}
- opinfo.moi_oe.oe_key = mdb;
- opinfo.moi_txn = txn;
- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
+ txn = moi->moi_txn;
/*
* Get the parent dn and see if the corresponding entry exists.
}
}
- if ( op->o_noop ) {
- mdb_txn_abort( txn );
- rs->sr_err = LDAP_X_NO_OPERATION;
- txn = NULL;
- goto return_results;
- }
+ if ( moi == &opinfo ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ opinfo.moi_oe.oe_key = NULL;
+ if ( op->o_noop ) {
+ mdb_txn_abort( txn );
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ txn = NULL;
+ goto return_results;
+ }
- if (( rs->sr_err = mdb_txn_commit( txn )) != 0 ) {
- rs->sr_text = "txn_commit failed";
- Debug( LDAP_DEBUG_TRACE,
- LDAP_XSTRING(mdb_add) ": %s : %s (%d)\n",
- rs->sr_text, mdb_strerror(rs->sr_err), rs->sr_err );
- rs->sr_err = LDAP_OTHER;
- goto return_results;
+ if (( rs->sr_err = mdb_txn_commit( txn )) != 0 ) {
+ rs->sr_text = "txn_commit failed";
+ Debug( LDAP_DEBUG_TRACE,
+ LDAP_XSTRING(mdb_add) ": %s : %s (%d)\n",
+ rs->sr_text, mdb_strerror(rs->sr_err), rs->sr_err );
+ rs->sr_err = LDAP_OTHER;
+ goto return_results;
+ }
+ txn = NULL;
}
- txn = NULL;
-
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
- opinfo.moi_oe.oe_key = NULL;
Debug(LDAP_DEBUG_TRACE,
LDAP_XSTRING(mdb_add) ": added%s id=%08lx dn=\"%s\"\n",
success = rs->sr_err;
send_ldap_result( op, rs );
- if( txn != NULL ) {
- mdb_txn_abort( txn );
- }
- if ( opinfo.moi_oe.oe_key ) {
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ if( moi == &opinfo ) {
+ if( txn != NULL ) {
+ mdb_txn_abort( txn );
+ }
+ if ( opinfo.moi_oe.oe_key ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ }
}
if( success == LDAP_SUCCESS ) {
#define mi_dn2id mi_dbis[MDB_DN2ID]
#define mi_ad2id mi_dbis[MDB_AD2ID]
-struct mdb_op_info {
+typedef struct mdb_op_info {
OpExtra moi_oe;
MDB_txn* moi_txn;
+ int moi_ref;
char moi_flag;
-};
-#define MOI_DONTFREE 1
+} mdb_op_info;
+#define MOI_READER 0x01
+#define MOI_FREEIT 0x02
/* Copy an ID "src" to pointer "dst" in big-endian byte order */
#define MDB_ID2DISK( src, dst ) \
AttributeDescription *password = slap_schema.si_ad_userPassword;
MDB_txn *rtxn;
+ mdb_op_info opinfo = {0}, *moi = &opinfo;
Debug( LDAP_DEBUG_ARGS,
"==> " LDAP_XSTRING(mdb_bind) ": dn: %s\n",
break;
}
- rs->sr_err = mdb_reader_get(op, mdb->mi_dbenv, &rtxn);
+ rs->sr_err = mdb_opinfo_get(op, mdb, 1, &moi);
switch(rs->sr_err) {
case 0:
break;
return rs->sr_err;
}
+ rtxn = moi->moi_txn;
+
/* get entry with reader lock */
rs->sr_err = mdb_dn2entry( op, rtxn, &op->o_req_ndn, &e, 0 );
switch(rs->sr_err) {
case MDB_NOTFOUND:
rs->sr_err = LDAP_INVALID_CREDENTIALS;
- send_ldap_result( op, rs );
- return rs->sr_err;
+ goto done;
case 0:
break;
case LDAP_BUSY:
- send_ldap_error( op, rs, LDAP_BUSY, "ldap_server_busy" );
- return LDAP_BUSY;
+ rs->sr_text = "ldap_server_busy";
+ goto done;
default:
- send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
- return rs->sr_err;
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "internal error";
+ goto done;
}
ber_dupbv( &op->oq_bind.rb_edn, &e->e_name );
}
done:
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
+ } /* writers can abort themselves */
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
+ }
+ }
/* free entry and reader lock */
if( e != NULL ) {
mdb_entry_return( e );
int manageDSAit = get_manageDSAit( op );
MDB_txn *rtxn;
+ mdb_op_info opinfo = {0}, *moi = &opinfo;
- rs->sr_err = mdb_reader_get(op, mdb->mi_dbenv, &rtxn);
+ rs->sr_err = mdb_opinfo_get(op, mdb, 1, &moi);
switch(rs->sr_err) {
case 0:
break;
return rs->sr_err;
}
+ rtxn = moi->moi_txn;
+
/* get entry */
rs->sr_err = mdb_dn2entry( op, rtxn, &op->o_req_ndn, &e, 1 );
switch( rs->sr_err ) {
}
done:
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
+ } /* writers can abort themselves */
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
+ }
+ }
/* free entry */
if ( e != NULL ) {
mdb_entry_return( e );
AttributeDescription *children = slap_schema.si_ad_children;
AttributeDescription *entry = slap_schema.si_ad_entry;
MDB_txn *txn = NULL;
- struct mdb_op_info opinfo = {{{ 0 }}};
+ mdb_op_info opinfo = {{{ 0 }}}, *moi = &opinfo;
LDAPControl **preread_ctrl = NULL;
LDAPControl *ctrls[SLAP_MAX_RESPONSE_CONTROLS];
}
/* begin transaction */
- rs->sr_err = mdb_txn_begin( mdb->mi_dbenv, 0, &txn );
+ rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
goto return_results;
}
- opinfo.moi_oe.oe_key = mdb;
- opinfo.moi_txn = txn;
- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
+ txn = moi->moi_txn;
if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
dnParent( &op->o_req_ndn, &pdn );
p = NULL;
}
- if( op->o_noop ) {
- mdb_txn_abort( txn );
- rs->sr_err = LDAP_X_NO_OPERATION;
- txn = NULL;
- goto return_results;
- } else {
- rs->sr_err = mdb_txn_commit( txn );
+ if( moi == &opinfo ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ opinfo.moi_oe.oe_key = NULL;
+ if( op->o_noop ) {
+ mdb_txn_abort( txn );
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ txn = NULL;
+ goto return_results;
+ } else {
+ rs->sr_err = mdb_txn_commit( txn );
+ }
txn = NULL;
}
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
- opinfo.moi_oe.oe_key = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
mdb_entry_return( e );
}
- if( txn != NULL ) {
- mdb_txn_abort( txn );
- }
- if ( opinfo.moi_oe.oe_key ) {
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ if( moi == &opinfo ) {
+ if( txn != NULL ) {
+ mdb_txn_abort( txn );
+ }
+ if ( opinfo.moi_oe.oe_key ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ }
}
send_ldap_result( op, rs );
Entry *e,
int rw )
{
-#if 0
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- struct mdb_op_info *moi;
- OpExtra *oex;
+ struct mdb_op_info *moi = NULL;
+ MDB_txn *txn = NULL;
+ int rc;
/* slapMode : SLAP_SERVER_MODE, SLAP_TOOL_MODE,
SLAP_TRUNCATE_MODE, SLAP_UNDEFINED_MODE */
+ mdb_entry_return ( e );
if ( slapMode == SLAP_SERVER_MODE ) {
- /* If not in our cache, just free it */
- if ( !e->e_private ) {
- return mdb_entry_return( e );
- }
- /* free entry and reader or writer lock */
- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
- if ( oex->oe_key == mdb ) break;
- }
- moi = (struct mdb_op_info *)oex;
-
- /* lock is freed with txn */
- if ( !moi || moi->moi_txn ) {
- mdb_unlocked_cache_return_entry_rw( mdb, e, rw );
- } else {
- struct mdb_lock_info *bli, *prev;
- for ( prev=(struct mdb_lock_info *)&moi->boi_locks,
- bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) {
- if ( bli->bli_id == e->e_id ) {
- mdb_cache_return_entry_rw( mdb, e, rw, &bli->bli_lock );
- prev->bli_next = bli->bli_next;
- /* Cleanup, or let caller know we unlocked */
- if ( bli->bli_flag & BLI_DONTFREE )
- bli->bli_flag = 0;
- else
- op->o_tmpfree( bli, op->o_tmpmemctx );
- break;
- }
+ rc = mdb_opinfo_get( op, mdb, 1, &moi );
+ if ( rc )
+ return rc;
+
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
}
- if ( !boi->boi_locks ) {
- LDAP_SLIST_REMOVE( &op->o_extra, &boi->boi_oe, OpExtra, oe_next );
- if ( !(boi->boi_flag & BOI_DONTFREE))
- op->o_tmpfree( boi, op->o_tmpmemctx );
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
}
}
- } else {
- if (e->e_private != NULL)
- BEI(e)->bei_e = NULL;
- e->e_private = NULL;
- mdb_entry_return ( e );
}
return 0;
-#else
- return mdb_entry_return( e );
-#endif
}
/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
"=> mdb_entry_get: oc: \"%s\", at: \"%s\"\n",
oc ? oc->soc_cname.bv_val : "(null)", at_name, 0);
- if( op ) {
- OpExtra *oex;
- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
- if ( oex->oe_key == mdb ) break;
- }
- moi = (struct mdb_op_info *)oex;
- if ( moi )
- txn = moi->moi_txn;
- }
-
- if ( !txn ) {
- rc = mdb_reader_get( op, mdb->mi_dbenv, &txn );
- switch(rc) {
- case 0:
- break;
- default:
- return LDAP_OTHER;
- }
- }
+ rc = mdb_opinfo_get( op, mdb, 0, &moi );
+ if ( rc )
+ return LDAP_OTHER;
+ txn = moi->moi_txn;
/* can we find entry */
rc = mdb_dn2entry( op, txn, ndn, &e, 0 );
rc, 0, 0 );
return(rc);
}
+
+static void
+mdb_reader_free( void *key, void *data )
+{
+ MDB_txn *txn = data;
+
+ if ( txn ) mdb_txn_abort( txn );
+}
+
+/* free up any keys used by the main thread */
+void
+mdb_reader_flush( MDB_env *env )
+{
+ void *data;
+ void *ctx = ldap_pvt_thread_pool_context();
+
+ if ( !ldap_pvt_thread_pool_getkey( ctx, env, &data, NULL ) ) {
+ ldap_pvt_thread_pool_setkey( ctx, env, NULL, 0, NULL, NULL );
+ mdb_reader_free( env, data );
+ }
+}
+
+int
+mdb_opinfo_get( Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **moip )
+{
+ int rc;
+ void *data;
+ void *ctx;
+ mdb_op_info *moi = NULL;
+ OpExtra *oex;
+
+ if ( !mdb || !moip ) return -1;
+
+ /* If no op was provided, try to find the ctx anyway... */
+ if ( op ) {
+ ctx = op->o_threadctx;
+ } else {
+ ctx = ldap_pvt_thread_pool_context();
+ }
+
+ if ( op ) {
+ LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
+ if ( oex->oe_key == mdb ) break;
+ }
+ moi = (mdb_op_info *)oex;
+ }
+
+ if ( !moi ) {
+ moi = *moip;
+
+ if ( !moi ) {
+ if ( op ) {
+ moi = op->o_tmpalloc(sizeof(struct mdb_op_info),op->o_tmpmemctx);
+ LDAP_SLIST_INSERT_HEAD( &op->o_extra, &moi->moi_oe, oe_next );
+ } else {
+ moi = ch_malloc(sizeof(mdb_op_info));
+ }
+ moi->moi_flag = MOI_FREEIT;
+ *moip = moi;
+ }
+ moi->moi_oe.oe_key = mdb;
+ moi->moi_ref = 0;
+ moi->moi_txn = NULL;
+ }
+
+ if ( !rdonly ) {
+ /* This op started as a reader, but now wants to write. */
+ if ( moi->moi_flag & MOI_READER ) {
+ moi = *moip;
+ LDAP_SLIST_INSERT_HEAD( &op->o_extra, &moi->moi_oe, oe_next );
+ } else {
+ /* This op is continuing an existing write txn */
+ *moip = moi;
+ }
+ moi->moi_ref++;
+ if ( !moi->moi_txn ) {
+ rc = mdb_txn_begin( mdb->mi_dbenv, 1, &moi->moi_txn );
+ if (rc) {
+ Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
+ mdb_strerror(rc), rc, 0 );
+ }
+ return rc;
+ }
+ return 0;
+ }
+
+ /* OK, this is a reader */
+ if ( !moi->moi_txn ) {
+ if ( !ctx ) {
+ /* Shouldn't happen unless we're single-threaded */
+ rc = mdb_txn_begin( mdb->mi_dbenv, 1, &moi->moi_txn );
+ if (rc) {
+ Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
+ mdb_strerror(rc), rc, 0 );
+ }
+ return rc;
+ }
+ if ( ldap_pvt_thread_pool_getkey( ctx, mdb->mi_dbenv, &data, NULL ) ) {
+ rc = mdb_txn_begin( mdb->mi_dbenv, 1, &moi->moi_txn );
+ if (rc) {
+ Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: err %s(%d)\n",
+ mdb_strerror(rc), rc, 0 );
+ return rc;
+ }
+ data = moi->moi_txn;
+ if ( ( rc = ldap_pvt_thread_pool_setkey( ctx, mdb->mi_dbenv,
+ data, mdb_reader_free, NULL, NULL ) ) ) {
+ mdb_txn_abort( moi->moi_txn );
+ moi->moi_txn = NULL;
+ Debug( LDAP_DEBUG_ANY, "mdb_opinfo_get: thread_pool_setkey failed err (%d)\n",
+ rc, 0, 0 );
+ return rc;
+ }
+ } else {
+ moi->moi_txn = data;
+ }
+ } else {
+ if ( moi->moi_ref < 1 ) {
+ moi->moi_ref = 0;
+ mdb_txn_renew( moi->moi_txn );
+ }
+ }
+ moi->moi_ref++;
+
+ return 0;
+}
mdb->mi_flags &= ~MDB_IS_OPEN;
-#if 0
if( mdb->mi_dbenv ) {
mdb_reader_flush( mdb->mi_dbenv );
}
-#endif
if ( mdb->mi_dbenv ) {
if ( mdb->mi_dbis[0] ) {
-Subproject commit 55a9c362261183ee455fa5fd4a7e4009ea353077
+Subproject commit 96aa7f066185995c6465448661217ede44d6b2ef
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
MDB_txn *txn = NULL;
- struct mdb_op_info opinfo = {{{ 0 }}};
+ mdb_op_info opinfo = {{{ 0 }}}, *moi = &opinfo;
Entry dummy = {0};
LDAPControl **preread_ctrl = NULL;
}
/* begin transaction */
- rs->sr_err = mdb_txn_begin( mdb->mi_dbenv, 0, &txn );
+ rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
goto return_results;
}
- opinfo.moi_oe.oe_key = mdb;
- opinfo.moi_txn = txn;
- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
+ txn = moi->moi_txn;
/* get entry or ancestor */
rs->sr_err = mdb_dn2entry( op, txn, &op->o_req_ndn, &e, 1 );
}
}
- if( op->o_noop ) {
- mdb_txn_abort( txn );
- rs->sr_err = LDAP_X_NO_OPERATION;
- txn = NULL;
- /* Only free attrs if they were dup'd. */
- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
- goto return_results;
- } else {
- dummy.e_attrs = NULL;
+ if( moi == &opinfo ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ opinfo.moi_oe.oe_key = NULL;
+ if( op->o_noop ) {
+ mdb_txn_abort( txn );
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ txn = NULL;
+ /* Only free attrs if they were dup'd. */
+ if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
+ goto return_results;
+ } else {
+ dummy.e_attrs = NULL;
- rs->sr_err = mdb_txn_commit( txn );
+ rs->sr_err = mdb_txn_commit( txn );
+ txn = NULL;
+ }
}
- txn = NULL;
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
- opinfo.moi_oe.oe_key = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
done:
slap_graduate_commit_csn( op );
- if( txn != NULL ) {
- mdb_txn_abort( txn );
- }
- if ( opinfo.moi_oe.oe_key ) {
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ if( moi == &opinfo ) {
+ if( txn != NULL ) {
+ mdb_txn_abort( txn );
+ }
+ if ( opinfo.moi_oe.oe_key ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ }
}
if( e != NULL ) {
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
MDB_txn *txn = NULL;
- struct mdb_op_info opinfo = {{{ 0 }}};
+ struct mdb_op_info opinfo = {{{ 0 }}}, *moi = &opinfo;
Entry dummy = {0};
Entry *np = NULL; /* newSuperior Entry */
slap_mods_opattrs( op, &op->orr_modlist, 1 );
/* begin transaction */
- rs->sr_err = mdb_txn_begin( mdb->mi_dbenv, 0, &txn );
+ rs->sr_err = mdb_opinfo_get( op, mdb, 0, &moi );
rs->sr_text = NULL;
if( rs->sr_err != 0 ) {
Debug( LDAP_DEBUG_TRACE,
goto return_results;
}
- opinfo.moi_oe.oe_key = mdb;
- opinfo.moi_txn = txn;
- LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
+ txn = moi->moi_txn;
if ( be_issuffix( op->o_bd, &e->e_nname ) ) {
#ifdef MDB_MULTIPLE_SUFFIXES
}
}
- if( op->o_noop ) {
- mdb_txn_abort( txn );
- rs->sr_err = LDAP_X_NO_OPERATION;
- txn = NULL;
- /* Only free attrs if they were dup'd. */
- if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
- goto return_results;
-
- } else {
- dummy.e_attrs = NULL;
- new_dn.bv_val = NULL;
- new_ndn.bv_val = NULL;
+ if( moi == &opinfo ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ opinfo.moi_oe.oe_key = NULL;
+ if( op->o_noop ) {
+ mdb_txn_abort( txn );
+ rs->sr_err = LDAP_X_NO_OPERATION;
+ txn = NULL;
+ /* Only free attrs if they were dup'd. */
+ if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
+ goto return_results;
- if(( rs->sr_err=mdb_txn_commit( txn )) != 0 ) {
- rs->sr_text = "txn_commit failed";
} else {
- rs->sr_err = LDAP_SUCCESS;
+ dummy.e_attrs = NULL;
+ new_dn.bv_val = NULL;
+ new_ndn.bv_val = NULL;
+
+ if(( rs->sr_err=mdb_txn_commit( txn )) != 0 ) {
+ rs->sr_text = "txn_commit failed";
+ } else {
+ rs->sr_err = LDAP_SUCCESS;
+ }
+ txn = NULL;
}
}
- txn = NULL;
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
- opinfo.moi_oe.oe_key = NULL;
-
if( rs->sr_err != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(mdb_modrdn) ": %s : %s (%d)\n",
mdb_entry_return( e );
}
- if( txn != NULL ) {
- mdb_txn_abort( txn );
- }
- if ( opinfo.moi_oe.oe_key ) {
- LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ if( moi == &opinfo ) {
+ if( txn != NULL ) {
+ mdb_txn_abort( txn );
+ }
+ if ( opinfo.moi_oe.oe_key ) {
+ LDAP_SLIST_REMOVE( &op->o_extra, &opinfo.moi_oe, OpExtra, oe_next );
+ }
}
if( preread_ctrl != NULL && (*preread_ctrl) != NULL ) {
int *hasSubordinates )
{
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
- struct mdb_op_info *opinfo;
- OpExtra *oex;
MDB_txn *rtxn;
+ mdb_op_info opinfo = {0}, *moi = &opinfo;
int rc;
assert( e != NULL );
- /* Check for a txn in a parent op, otherwise use reader txn */
- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
- if ( oex->oe_key == mdb )
- break;
- }
- opinfo = (struct mdb_op_info *) oex;
- if ( opinfo && opinfo->moi_txn ) {
- rtxn = opinfo->moi_txn;
- } else {
- rc = mdb_reader_get(op, mdb->mi_dbenv, &rtxn);
- if ( rc ) {
- rc = LDAP_OTHER;
- goto done;
- }
+ rc = mdb_opinfo_get(op, mdb, 1, &moi);
+ switch(rc) {
+ case 0:
+ break;
+ default:
+ rc = LDAP_OTHER;
+ goto done;
}
+ rtxn = moi->moi_txn;
+
rc = mdb_dn2id_children( op, rtxn, e );
switch( rc ) {
}
done:;
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
+ } /* writers can abort themselves */
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
+ }
+ }
return rc;
}
BI_entry_release_rw mdb_entry_release;
BI_entry_get_rw mdb_entry_get;
+void mdb_reader_flush( MDB_env *env );
+int mdb_opinfo_get( Operation *op, struct mdb_info *mdb, int rdonly, mdb_op_info **moi );
/*
* idl.c
int rc = LDAP_SUCCESS;
MDB_txn *rtxn;
+ mdb_op_info opinfo = {0}, *moi = &opinfo;
if( op->o_tag == LDAP_REQ_SEARCH ) {
/* let search take care of itself */
return rc;
}
- rc = mdb_reader_get(op, mdb->mi_dbenv, &rtxn);
+ rc = mdb_opinfo_get(op, mdb, 1, &moi);
switch(rc) {
case 0:
break;
return LDAP_OTHER;
}
+ rtxn = moi->moi_txn;
+
/* get entry */
rc = mdb_dn2entry( op, rtxn, &op->o_req_ndn, &e, 1 );
break;
case LDAP_BUSY:
rs->sr_text = "ldap server busy";
- return LDAP_BUSY;
+ goto done;
default:
Debug( LDAP_DEBUG_TRACE,
LDAP_XSTRING(mdb_referrals)
": dn2entry failed: %s (%d)\n",
mdb_strerror(rc), rc, 0 );
rs->sr_text = "internal error";
- return LDAP_OTHER;
+ rc = LDAP_OTHER;
+ goto done;
}
if ( rc == MDB_NOTFOUND ) {
op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
rs->sr_matched = NULL;
}
- return rc;
+ goto done;
}
if ( is_entry_referral( e ) ) {
ber_bvarray_free( refs );
}
+done:
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
+ } /* writers can abort themselves */
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
+ }
+ }
mdb_entry_return( e );
return rc;
}
int manageDSAit;
int tentries = 0;
- struct mdb_op_info *opinfo = NULL;
+ mdb_op_info opinfo = {0}, *moi = &opinfo;
MDB_txn *ltid = NULL;
MDB_cursor *idcursor = NULL;
- OpExtra *oex;
Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(mdb_search) "\n", 0, 0, 0);
attrs = op->oq_search.rs_attrs;
- LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
- if ( oex->oe_key == mdb )
- break;
- }
- opinfo = (struct mdb_op_info *) oex;
-
manageDSAit = get_manageDSAit( op );
- if ( opinfo && opinfo->moi_txn ) {
- ltid = opinfo->moi_txn;
- } else {
- rs->sr_err = mdb_reader_get( op, mdb->mi_dbenv, <id );
-
- switch(rs->sr_err) {
- case 0:
- break;
- default:
- send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
- return rs->sr_err;
- }
+ rs->sr_err = mdb_opinfo_get( op, mdb, 1, &moi );
+ switch(rs->sr_err) {
+ case 0:
+ break;
+ default:
+ send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
+ return rs->sr_err;
}
+ ltid = moi->moi_txn;
+
if ( op->ors_deref & LDAP_DEREF_FINDING ) {
MDB_IDL_ZERO(candidates);
}
break;
case LDAP_BUSY:
send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
- return LDAP_BUSY;
+ goto done;
default:
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
- return rs->sr_err;
+ goto done;
}
if ( op->ors_deref & LDAP_DEREF_FINDING ) {
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
}
- return rs->sr_err;
+ goto done;
}
/* NOTE: __NEW__ "search" access is required
mdb_entry_return(e);
send_ldap_result( op, rs );
- return rs->sr_err;
+ goto done;
}
if ( !manageDSAit && is_entry_referral( e ) ) {
rs->sr_ref = NULL;
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
- return 1;
+ goto done;
}
if ( get_assert( op ) &&
rs->sr_err = LDAP_ASSERTION_FAILED;
mdb_entry_return(e);
send_ldap_result( op, rs );
- return 1;
+ goto done;
}
/* compute it anyway; root does not use it */
rs->sr_err = LDAP_SUCCESS;
done:
+ moi->moi_ref--;
+ if ( moi->moi_ref < 1 ) {
+ if ( moi->moi_flag & MOI_READER ) {
+ mdb_txn_reset( moi->moi_txn );
+ } /* writers can abort themselves */
+ LDAP_SLIST_REMOVE( &op->o_extra, &moi->moi_oe, OpExtra, oe_next );
+ if ( moi->moi_flag & MOI_FREEIT ) {
+ op->o_tmpfree( moi, op->o_tmpmemctx );
+ }
+ }
if( idcursor )
mdb_cursor_close( idcursor );
if( rs->sr_v2ref ) {