mirror of
https://git.openldap.org/openldap/openldap.git
synced 2024-12-21 03:10:25 +08:00
ITS#5262 must protect dn2id between the time it's read from the DB
and it's inserted into EntryInfo cache.
This commit is contained in:
parent
c2a02618bb
commit
cb0e31fc65
@ -70,13 +70,15 @@ typedef struct __db_locker * BDB_LOCKER;
|
||||
extern int __lock_getlocker(DB_LOCKTAB *lt, u_int32_t locker, int create, DB_LOCKER **ret);
|
||||
|
||||
#define CURSOR_SETLOCKER(cursor, id) cursor->locker = id
|
||||
#define CURSOR_GETLOCKER(cursor) cursor->locker
|
||||
#define CURSOR_GETLOCKER(cursor) cursor->locker
|
||||
#define BDB_LOCKID(locker) locker->id
|
||||
#else
|
||||
|
||||
typedef u_int32_t BDB_LOCKER;
|
||||
|
||||
#define CURSOR_SETLOCKER(cursor, id) cursor->locker = id
|
||||
#define CURSOR_GETLOCKER(cursor) cursor->locker
|
||||
#define BDB_LOCKID(locker) locker
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -155,12 +155,6 @@ bdb_cache_lru_link( struct bdb_info *bdb, EntryInfo *ei )
|
||||
* alternatives though.
|
||||
*/
|
||||
|
||||
#if DB_VERSION_FULL >= 0x04060012
|
||||
#define BDB_LOCKID(locker) locker->id
|
||||
#else
|
||||
#define BDB_LOCKID(locker) locker
|
||||
#endif
|
||||
|
||||
/* Atomically release and reacquire a lock */
|
||||
int
|
||||
bdb_cache_entry_db_relock(
|
||||
@ -426,6 +420,7 @@ bdb_cache_find_ndn(
|
||||
ei.bei_parent = eip;
|
||||
ei2 = (EntryInfo *)avl_find( eip->bei_kids, &ei, bdb_rdn_cmp );
|
||||
if ( !ei2 ) {
|
||||
DB_LOCK lock;
|
||||
int len = ei.bei_nrdn.bv_len;
|
||||
|
||||
if ( BER_BVISEMPTY( ndn )) {
|
||||
@ -442,9 +437,11 @@ bdb_cache_find_ndn(
|
||||
ei.bei_nrdn.bv_val );
|
||||
#endif
|
||||
|
||||
rc = bdb_dn2id( op, locker, &ei.bei_nrdn, &ei );
|
||||
lock.mode = DB_LOCK_NG;
|
||||
rc = bdb_dn2id( op, &ei.bei_nrdn, &ei, locker, &lock );
|
||||
if (rc) {
|
||||
bdb_cache_entryinfo_lock( eip );
|
||||
bdb_cache_entry_db_unlock( bdb, &lock );
|
||||
*res = eip;
|
||||
return rc;
|
||||
}
|
||||
@ -461,6 +458,7 @@ bdb_cache_find_ndn(
|
||||
ei.bei_nrdn.bv_val, ei.bei_id, 0 );
|
||||
/* add_internal left eip and c_rwlock locked */
|
||||
ldap_pvt_thread_rdwr_wunlock( &bdb->bi_cache.c_rwlock );
|
||||
bdb_cache_entry_db_unlock( bdb, &lock );
|
||||
if ( rc ) {
|
||||
*res = eip;
|
||||
return rc;
|
||||
|
@ -23,6 +23,29 @@
|
||||
#include "idl.h"
|
||||
#include "lutil.h"
|
||||
|
||||
#define bdb_dn2id_lock BDB_SYMBOL(dn2id_lock)
|
||||
|
||||
static int
|
||||
bdb_dn2id_lock( struct bdb_info *bdb, struct berval *dn,
|
||||
int rw, BDB_LOCKER locker, DB_LOCK *lock )
|
||||
{
|
||||
int rc;
|
||||
DBT lockobj;
|
||||
int db_rw;
|
||||
|
||||
if (rw)
|
||||
db_rw = DB_LOCK_WRITE;
|
||||
else
|
||||
db_rw = DB_LOCK_READ;
|
||||
|
||||
lockobj.data = dn->bv_val;
|
||||
lockobj.size = dn->bv_len;
|
||||
|
||||
rc = LOCK_GET(bdb->bi_dbenv, BDB_LOCKID(locker), DB_LOCK_NOWAIT,
|
||||
&lockobj, db_rw, lock);
|
||||
return rc;
|
||||
}
|
||||
|
||||
#ifndef BDB_HIER
|
||||
int
|
||||
bdb_dn2id_add(
|
||||
@ -146,10 +169,11 @@ bdb_dn2id_delete(
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
DB *db = bdb->bi_dn2id->bdi_db;
|
||||
int rc;
|
||||
DBT key;
|
||||
char *buf;
|
||||
DBT key;
|
||||
DB_LOCK lock;
|
||||
struct berval pdn, ptr;
|
||||
int rc;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_delete( \"%s\", 0x%08lx )\n",
|
||||
e->e_ndn, e->e_id, 0 );
|
||||
@ -165,6 +189,10 @@ bdb_dn2id_delete(
|
||||
AC_MEMCPY( ptr.bv_val, e->e_nname.bv_val, e->e_nname.bv_len );
|
||||
ptr.bv_val[ptr.bv_len] = '\0';
|
||||
|
||||
/* We hold this lock until the TXN completes */
|
||||
rc = bdb_dn2id_lock( bdb, &e->e_nname, 1, TXN_ID( txn ), &lock );
|
||||
if ( rc ) return rc;
|
||||
|
||||
/* delete it */
|
||||
rc = db->del( db, txn, &key, 0 );
|
||||
if( rc != 0 ) {
|
||||
@ -244,9 +272,10 @@ done:
|
||||
int
|
||||
bdb_dn2id(
|
||||
Operation *op,
|
||||
BDB_LOCKER locker,
|
||||
struct berval *dn,
|
||||
EntryInfo *ei )
|
||||
EntryInfo *ei,
|
||||
BDB_LOCKER locker,
|
||||
DB_LOCK *lock )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
DB *db = bdb->bi_dn2id->bdi_db;
|
||||
@ -268,6 +297,9 @@ bdb_dn2id(
|
||||
data.ulen = sizeof(ID);
|
||||
data.flags = DB_DBT_USERMEM;
|
||||
|
||||
rc = bdb_dn2id_lock( bdb, dn, 0, locker, lock );
|
||||
if ( rc ) return rc;
|
||||
|
||||
rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
|
||||
if ( rc ) return rc;
|
||||
if ( locker ) {
|
||||
@ -576,6 +608,7 @@ hdb_dn2id_delete(
|
||||
int rc;
|
||||
ID nid;
|
||||
unsigned char dlen[2];
|
||||
DB_LOCK lock;
|
||||
|
||||
DBTzero(&key);
|
||||
key.size = sizeof(ID);
|
||||
@ -589,6 +622,10 @@ hdb_dn2id_delete(
|
||||
data.dlen = data.size;
|
||||
data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
|
||||
|
||||
/* We hold this lock until the TXN completes */
|
||||
rc = bdb_dn2id_lock( bdb, &e->e_nname, 1, TXN_ID( txn ), &lock );
|
||||
if ( rc ) return rc;
|
||||
|
||||
key.data = &nid;
|
||||
rc = db->cursor( db, txn, &cursor, bdb->bi_db_opflags );
|
||||
if ( rc ) return rc;
|
||||
@ -646,9 +683,10 @@ hdb_dn2id_delete(
|
||||
int
|
||||
hdb_dn2id(
|
||||
Operation *op,
|
||||
BDB_LOCKER locker,
|
||||
struct berval *in,
|
||||
EntryInfo *ei )
|
||||
EntryInfo *ei,
|
||||
BDB_LOCKER locker,
|
||||
DB_LOCK *lock )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
DB *db = bdb->bi_dn2id->bdi_db;
|
||||
@ -677,6 +715,9 @@ hdb_dn2id(
|
||||
data.dlen = data.ulen;
|
||||
data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
|
||||
|
||||
rc = bdb_dn2id_lock( bdb, in, 0, locker, lock );
|
||||
if ( rc ) return rc;
|
||||
|
||||
rc = db->cursor( db, NULL, &cursor, bdb->bi_db_opflags );
|
||||
if ( rc ) return rc;
|
||||
if ( locker ) {
|
||||
|
@ -97,9 +97,10 @@ int bdb_dn2entry LDAP_P(( Operation *op, DB_TXN *tid,
|
||||
|
||||
int bdb_dn2id(
|
||||
Operation *op,
|
||||
BDB_LOCKER locker,
|
||||
struct berval *dn,
|
||||
EntryInfo *ei );
|
||||
EntryInfo *ei,
|
||||
BDB_LOCKER locker,
|
||||
DB_LOCK *lock );
|
||||
|
||||
int bdb_dn2id_add(
|
||||
Operation *op,
|
||||
|
Loading…
Reference in New Issue
Block a user