Better fix for ITS#3365, manage back-bdb's read locks so frontend/etc.

don't need to worry about them.
This commit is contained in:
Howard Chu 2004-12-05 02:00:19 +00:00
parent 0c8851ff9b
commit 30a6f4d24d
8 changed files with 43 additions and 24 deletions

View File

@ -33,7 +33,7 @@ bdb_add(Operation *op, SlapReply *rs )
AttributeDescription *children = slap_schema.si_ad_children;
AttributeDescription *entry = slap_schema.si_ad_entry;
DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo;
struct bdb_op_info opinfo = {0};
#ifdef BDB_SUBENTRIES
int subentry;
#endif

View File

@ -194,13 +194,19 @@ struct bdb_info {
#define bi_id2entry bi_databases[BDB_ID2ENTRY]
#define bi_dn2id bi_databases[BDB_DN2ID]
struct bdb_lock_info {
struct bdb_lock_info *bli_next;
ID bli_id;
DB_LOCK bli_lock;
};
struct bdb_op_info {
BackendDB* boi_bdb;
DB_TXN* boi_txn;
DB_LOCK boi_lock; /* used when no txn */
u_int32_t boi_err;
u_int32_t boi_locker;
int boi_acl_cache;
struct bdb_lock_info *boi_locks; /* used when no txn */
};
#define DB_OPEN(db, file, name, type, flags, mode) \

View File

@ -34,7 +34,7 @@ bdb_delete( Operation *op, SlapReply *rs )
AttributeDescription *children = slap_schema.si_ad_children;
AttributeDescription *entry = slap_schema.si_ad_entry;
DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo;
struct bdb_op_info opinfo = {0};
ID eid;
u_int32_t locker = 0;

View File

@ -213,9 +213,21 @@ int bdb_entry_release(
if ( !boi || boi->boi_txn ) {
bdb_unlocked_cache_return_entry_rw( &bdb->bi_cache, e, rw );
} else {
bdb_cache_return_entry_rw( bdb->bi_dbenv, &bdb->bi_cache, e, rw, &boi->boi_lock );
o->o_tmpfree( boi, o->o_tmpmemctx );
o->o_private = NULL;
struct bdb_lock_info *bli, *prev;
for ( prev=(struct bdb_lock_info *)&boi->boi_locks,
bli = boi->boi_locks; bli; prev=bli, bli=bli->bli_next ) {
if ( bli->bli_id == e->e_id ) {
bdb_cache_return_entry_rw( bdb->bi_dbenv, &bdb->bi_cache,
e, rw, &bli->bli_lock );
prev->bli_next = bli->bli_next;
o->o_tmpfree( bli, o->o_tmpmemctx );
break;
}
}
if ( !boi->boi_locks ) {
o->o_tmpfree( boi, o->o_tmpmemctx );
o->o_private = NULL;
}
}
} else {
if (e->e_private != NULL)
@ -344,15 +356,25 @@ return_results:
if ( slapMode == SLAP_SERVER_MODE ) {
*ent = e;
/* big drag. we need a place to store a read lock so we can
* release it later??
* release it later?? If we're in a txn, nothing is needed
* here because the locks will go away with the txn.
*/
if ( op && !boi ) {
boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx);
boi->boi_lock = lock;
boi->boi_bdb = op->o_bd;
op->o_private = boi;
if ( op ) {
if ( !boi ) {
boi = op->o_tmpcalloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx);
boi->boi_bdb = op->o_bd;
op->o_private = boi;
}
if ( !boi->boi_txn ) {
struct bdb_lock_info *bli;
bli = op->o_tmpalloc( sizeof(struct bdb_lock_info),
op->o_tmpmemctx );
bli->bli_next = boi->boi_locks;
bli->bli_id = e->e_id;
bli->bli_lock = lock;
boi->boi_locks = bli;
}
}
} else {
*ent = entry_dup( e );
bdb_cache_return_entry_rw(bdb->bi_dbenv, &bdb->bi_cache, e, rw, &lock);

View File

@ -269,7 +269,7 @@ bdb_modify( Operation *op, SlapReply *rs )
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo;
struct bdb_op_info opinfo = {0};
Entry dummy = {0};
u_int32_t locker = 0;

View File

@ -39,7 +39,7 @@ bdb_modrdn( Operation *op, SlapReply *rs )
char textbuf[SLAP_TEXT_BUFLEN];
size_t textlen = sizeof textbuf;
DB_TXN *ltid = NULL, *lt2;
struct bdb_op_info opinfo;
struct bdb_op_info opinfo = {0};
Entry dummy = {0};
ID id;

View File

@ -1248,7 +1248,6 @@ backend_group(
Filter *filter;
Entry *user;
Backend *b2 = op->o_bd;
void *o_private = op->o_private;
if ( target && dn_match( &target->e_nname, op_ndn ) ) {
user = target;
@ -1256,7 +1255,6 @@ backend_group(
/* back-bdb stored lockinfo here, we saved it
* above. Clear it out so that a new lock can be used.
*/
op->o_private = NULL;
op->o_bd = select_backend( op_ndn, 0, 0 );
rc = be_entry_get_rw(op, op_ndn, NULL, NULL, 0, &user );
}
@ -1321,8 +1319,6 @@ loopit:
}
if ( user != target ) {
be_entry_release_r( op, user );
/* restore previous lockinfo, if any */
op->o_private = o_private;
}
}
op->o_bd = b2;

View File

@ -323,7 +323,6 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp )
const char *text;
AttributeDescription *ad;
struct berval bv;
void *opr = op->o_private;
memset( pp, 0, sizeof(PassPolicy) );
@ -346,8 +345,6 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp )
}
}
/* back-bdb stores lock info in o_private */
op->o_private = NULL;
op->o_bd->bd_info = (BackendInfo *)on->on_info;
rc = be_entry_get_rw( op, vals, NULL, NULL, 0, &pe );
op->o_bd->bd_info = (BackendInfo *)on;
@ -401,13 +398,11 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp )
be_entry_release_r( op, pe );
op->o_bd->bd_info = (BackendInfo *)on;
op->o_private = opr;
return;
defaultpol:
Debug( LDAP_DEBUG_ANY,
"ppolicy_get: using default policy\n", 0, 0, 0 );
op->o_private = opr;
return;
}