mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
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:
parent
0c8851ff9b
commit
30a6f4d24d
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user