From 30a6f4d24d48708df5b9675476358d2adb397cc7 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Sun, 5 Dec 2004 02:00:19 +0000 Subject: [PATCH] Better fix for ITS#3365, manage back-bdb's read locks so frontend/etc. don't need to worry about them. --- servers/slapd/back-bdb/add.c | 2 +- servers/slapd/back-bdb/back-bdb.h | 8 +++++- servers/slapd/back-bdb/delete.c | 2 +- servers/slapd/back-bdb/id2entry.c | 42 +++++++++++++++++++++++-------- servers/slapd/back-bdb/modify.c | 2 +- servers/slapd/back-bdb/modrdn.c | 2 +- servers/slapd/backend.c | 4 --- servers/slapd/overlays/ppolicy.c | 5 ---- 8 files changed, 43 insertions(+), 24 deletions(-) diff --git a/servers/slapd/back-bdb/add.c b/servers/slapd/back-bdb/add.c index 40e9879b4b..1463e40031 100644 --- a/servers/slapd/back-bdb/add.c +++ b/servers/slapd/back-bdb/add.c @@ -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 diff --git a/servers/slapd/back-bdb/back-bdb.h b/servers/slapd/back-bdb/back-bdb.h index 21da1d0f21..ceb3eda2ab 100644 --- a/servers/slapd/back-bdb/back-bdb.h +++ b/servers/slapd/back-bdb/back-bdb.h @@ -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) \ diff --git a/servers/slapd/back-bdb/delete.c b/servers/slapd/back-bdb/delete.c index 59b4d90e72..e6008dc763 100644 --- a/servers/slapd/back-bdb/delete.c +++ b/servers/slapd/back-bdb/delete.c @@ -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; diff --git a/servers/slapd/back-bdb/id2entry.c b/servers/slapd/back-bdb/id2entry.c index d1cf0b747e..6157522192 100644 --- a/servers/slapd/back-bdb/id2entry.c +++ b/servers/slapd/back-bdb/id2entry.c @@ -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); diff --git a/servers/slapd/back-bdb/modify.c b/servers/slapd/back-bdb/modify.c index 6b2a6c7d4b..bb5208ede1 100644 --- a/servers/slapd/back-bdb/modify.c +++ b/servers/slapd/back-bdb/modify.c @@ -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; diff --git a/servers/slapd/back-bdb/modrdn.c b/servers/slapd/back-bdb/modrdn.c index 6349db8b06..217c76501d 100644 --- a/servers/slapd/back-bdb/modrdn.c +++ b/servers/slapd/back-bdb/modrdn.c @@ -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; diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c index 2b7f3eee54..322f4c6f48 100644 --- a/servers/slapd/backend.c +++ b/servers/slapd/backend.c @@ -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; diff --git a/servers/slapd/overlays/ppolicy.c b/servers/slapd/overlays/ppolicy.c index fc441f6d31..259870bdde 100644 --- a/servers/slapd/overlays/ppolicy.c +++ b/servers/slapd/overlays/ppolicy.c @@ -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; } -- 2.39.5