mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-06-09 08:42:22 -04:00
Use mdb_op_info consistently
This commit is contained in:
parent
e7768b12ab
commit
2b77736c24
14 changed files with 355 additions and 218 deletions
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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 ) \
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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 );
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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 ) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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, <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);
|
||||
}
|
||||
|
|
@ -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 ) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue