Use mdb_op_info consistently

This commit is contained in:
Howard Chu 2011-08-24 04:03:10 -07:00
parent e7768b12ab
commit 2b77736c24
14 changed files with 355 additions and 218 deletions

View file

@ -33,7 +33,7 @@ mdb_add(Operation *op, SlapReply *rs )
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;
@ -119,7 +119,7 @@ txnReturn:
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,
@ -130,9 +130,7 @@ txnReturn:
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.
@ -371,26 +369,27 @@ txnReturn:
}
}
if ( op->o_noop ) {
mdb_txn_abort( txn );
rs->sr_err = LDAP_X_NO_OPERATION;
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;
}
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;
}
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",
op->o_noop ? " (no-op)" : "",
@ -403,11 +402,13 @@ return_results:
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 ) {

View file

@ -98,12 +98,14 @@ struct mdb_info {
#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 ) \

View file

@ -32,6 +32,7 @@ mdb_bind( Operation *op, SlapReply *rs )
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",
@ -53,7 +54,7 @@ mdb_bind( Operation *op, SlapReply *rs )
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;
@ -63,22 +64,24 @@ mdb_bind( Operation *op, SlapReply *rs )
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 );
@ -132,6 +135,16 @@ mdb_bind( Operation *op, SlapReply *rs )
}
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 );

View file

@ -29,8 +29,9 @@ mdb_compare( Operation *op, SlapReply *rs )
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;
@ -39,6 +40,8 @@ mdb_compare( Operation *op, SlapReply *rs )
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 ) {
@ -120,6 +123,16 @@ return_results:
}
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 );

View file

@ -33,7 +33,7 @@ mdb_delete( Operation *op, SlapReply *rs )
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];
@ -100,7 +100,7 @@ txnReturn:
}
/* 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,
@ -111,9 +111,7 @@ txnReturn:
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 );
@ -389,17 +387,19 @@ txnReturn:
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,
@ -434,11 +434,13 @@ return_results:
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 );

View file

@ -154,60 +154,33 @@ int mdb_entry_release(
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;
rc = mdb_opinfo_get( op, mdb, 1, &moi );
if ( rc )
return rc;
/* 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;
}
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.
@ -233,25 +206,10 @@ int mdb_entry_get(
"=> 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 );
@ -304,3 +262,129 @@ return_results:
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;
}

View file

@ -247,11 +247,9 @@ mdb_db_close( BackendDB *be, ConfigReply *cr )
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] ) {

@ -1 +1 @@
Subproject commit 55a9c362261183ee455fa5fd4a7e4009ea353077
Subproject commit 96aa7f066185995c6465448661217ede44d6b2ef

View file

@ -402,7 +402,7 @@ mdb_modify( Operation *op, SlapReply *rs )
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;
@ -466,7 +466,7 @@ txnReturn:
}
/* 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,
@ -477,9 +477,7 @@ txnReturn:
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 );
@ -610,21 +608,23 @@ txnReturn:
}
}
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,
@ -662,11 +662,13 @@ return_results:
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 ) {

View file

@ -35,7 +35,7 @@ mdb_modrdn( Operation *op, SlapReply *rs )
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 */
@ -105,7 +105,7 @@ txnReturn:
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,
@ -116,9 +116,7 @@ txnReturn:
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
@ -551,30 +549,31 @@ txnReturn:
}
}
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( 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;
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;
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",
@ -631,11 +630,13 @@ done:
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 ) {

View file

@ -35,29 +35,23 @@ mdb_hasSubordinates(
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 ) {
@ -79,6 +73,16 @@ mdb_hasSubordinates(
}
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;
}

View file

@ -174,6 +174,8 @@ int mdb_entry_return( Entry *e );
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

View file

@ -28,6 +28,7 @@ mdb_referrals( Operation *op, SlapReply *rs )
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 */
@ -39,7 +40,7 @@ mdb_referrals( Operation *op, SlapReply *rs )
return rc;
}
rc = mdb_reader_get(op, mdb->mi_dbenv, &rtxn);
rc = mdb_opinfo_get(op, mdb, 1, &moi);
switch(rc) {
case 0:
break;
@ -47,6 +48,8 @@ mdb_referrals( Operation *op, SlapReply *rs )
return LDAP_OTHER;
}
rtxn = moi->moi_txn;
/* get entry */
rc = mdb_dn2entry( op, rtxn, &op->o_req_ndn, &e, 1 );
@ -56,14 +59,15 @@ mdb_referrals( Operation *op, SlapReply *rs )
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 ) {
@ -105,7 +109,7 @@ mdb_referrals( Operation *op, SlapReply *rs )
op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
rs->sr_matched = NULL;
}
return rc;
goto done;
}
if ( is_entry_referral( e ) ) {
@ -134,6 +138,17 @@ mdb_referrals( Operation *op, SlapReply *rs )
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;
}

View file

@ -293,36 +293,26 @@ mdb_search( Operation *op, SlapReply *rs )
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, &ltid );
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);
}
@ -338,10 +328,10 @@ dn2entry_retry:
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 ) {
@ -415,7 +405,7 @@ dn2entry_retry:
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
}
return rs->sr_err;
goto done;
}
/* NOTE: __NEW__ "search" access is required
@ -431,7 +421,7 @@ dn2entry_retry:
mdb_entry_return(e);
send_ldap_result( op, rs );
return rs->sr_err;
goto done;
}
if ( !manageDSAit && is_entry_referral( e ) ) {
@ -468,7 +458,7 @@ dn2entry_retry:
rs->sr_ref = NULL;
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
return 1;
goto done;
}
if ( get_assert( op ) &&
@ -477,7 +467,7 @@ dn2entry_retry:
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 */
@ -820,6 +810,16 @@ nochange:
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 ) {