mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-12-30 03:29:35 -05:00
Hierarchical cache management.
This commit is contained in:
parent
d9d5912383
commit
377bccbc6c
17 changed files with 1030 additions and 1445 deletions
|
|
@ -18,13 +18,13 @@ bdb_add(Operation *op, SlapReply *rs )
|
|||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
struct berval pdn;
|
||||
Entry *p = NULL;
|
||||
const char *text;
|
||||
Entry *p;
|
||||
EntryInfo *ei;
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
AttributeDescription *children = slap_schema.si_ad_children;
|
||||
AttributeDescription *entry = slap_schema.si_ad_entry;
|
||||
DB_TXN *ltid = NULL;
|
||||
DB_TXN *ltid = NULL, *lt2;
|
||||
struct bdb_op_info opinfo;
|
||||
#ifdef BDB_SUBENTRIES
|
||||
int subentry;
|
||||
|
|
@ -137,42 +137,37 @@ retry: /* transaction retry */
|
|||
dnParent( &op->oq_add.rs_e->e_nname, &pdn );
|
||||
}
|
||||
|
||||
if( pdn.bv_len != 0 ) {
|
||||
Entry *matched = NULL;
|
||||
|
||||
/* get parent */
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, ltid, &pdn, &p, &matched, 0, locker, &lock );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
case LDAP_BUSY:
|
||||
rs->sr_text = "ldap server busy";
|
||||
goto return_results;
|
||||
default:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( p == NULL ) {
|
||||
if ( matched != NULL ) {
|
||||
rs->sr_matched = ch_strdup( matched->e_dn );
|
||||
rs->sr_ref = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
: NULL;
|
||||
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, matched );
|
||||
matched = NULL;
|
||||
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
NULL, &op->oq_add.rs_e->e_name, LDAP_SCOPE_DEFAULT );
|
||||
}
|
||||
/* get entry or parent */
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, ltid, &op->ora_e->e_nname, &ei,
|
||||
1, locker, &lock, op->o_tmpmemctx );
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
rs->sr_err = LDAP_ALREADY_EXISTS;
|
||||
goto return_results;
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
case LDAP_BUSY:
|
||||
rs->sr_text = "ldap server busy";
|
||||
goto return_results;
|
||||
default:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
p = ei->bei_e;
|
||||
if ( p ) {
|
||||
if ( !bvmatch( &pdn, &p->e_nname ) ) {
|
||||
rs->sr_matched = ber_strdup_x( p->e_name.bv_val,
|
||||
op->o_tmpmemctx );
|
||||
rs->sr_ref = is_entry_referral( p )
|
||||
? get_entry_referrals( op, p )
|
||||
: NULL;
|
||||
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, p );
|
||||
p = NULL;
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, DETAIL1,
|
||||
"bdb_add: parent does not exist\n", 0, 0, 0 );
|
||||
|
|
@ -185,7 +180,7 @@ retry: /* transaction retry */
|
|||
send_ldap_result( op, rs );
|
||||
|
||||
ber_bvarray_free( rs->sr_ref );
|
||||
ch_free( (char *)rs->sr_matched );
|
||||
op->o_tmpfree( (char *)rs->sr_matched, op->o_tmpmemctx );
|
||||
rs->sr_ref = NULL;
|
||||
rs->sr_matched = NULL;
|
||||
|
||||
|
|
@ -370,8 +365,26 @@ retry: /* transaction retry */
|
|||
goto return_results;;
|
||||
}
|
||||
|
||||
/* nested transaction */
|
||||
rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
|
||||
bdb->bi_db_opflags );
|
||||
rs->sr_text = NULL;
|
||||
if( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
"bdb_add: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_add: txn_begin(2) failed: %s (%d)\n",
|
||||
db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#endif
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* dn2id index */
|
||||
rs->sr_err = bdb_dn2id_add( op->o_bd, ltid, &pdn, op->oq_add.rs_e );
|
||||
rs->sr_err = bdb_dn2id_add( op->o_bd, lt2, &pdn, op->oq_add.rs_e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
|
|
@ -395,7 +408,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* id2entry index */
|
||||
rs->sr_err = bdb_id2entry_add( op->o_bd, ltid, op->oq_add.rs_e );
|
||||
rs->sr_err = bdb_id2entry_add( op->o_bd, lt2, op->oq_add.rs_e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR, "bdb_add: id2entry_add failed\n", 0, 0, 0 );
|
||||
|
|
@ -415,7 +428,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* attribute indexes */
|
||||
rs->sr_err = bdb_index_entry_add( op, ltid, op->oq_add.rs_e );
|
||||
rs->sr_err = bdb_index_entry_add( op, lt2, op->oq_add.rs_e );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
|
|
@ -434,7 +447,11 @@ retry: /* transaction retry */
|
|||
rs->sr_text = "index generation failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "txn_commit(2) failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if( op->o_noop ) {
|
||||
if (( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
|
||||
|
|
@ -454,32 +471,21 @@ retry: /* transaction retry */
|
|||
rs->sr_text = "txn_prepare failed";
|
||||
|
||||
} else {
|
||||
int ret = bdb_cache_add_entry_rw(bdb->bi_dbenv,
|
||||
&bdb->bi_cache, op->oq_add.rs_e, CACHE_WRITE_LOCK,
|
||||
locker, &lock);
|
||||
switch ( ret ) {
|
||||
case 0:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
default:
|
||||
ret = LDAP_OTHER;
|
||||
struct berval nrdn;
|
||||
|
||||
if (pdn.bv_len) {
|
||||
nrdn.bv_val = op->ora_e->e_nname.bv_val;
|
||||
nrdn.bv_len = pdn.bv_val - nrdn.bv_val - 1;
|
||||
} else {
|
||||
nrdn = op->ora_e->e_nname;
|
||||
}
|
||||
|
||||
if ( ret ) {
|
||||
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
|
||||
rs->sr_text = "cache add & txn_abort failed";
|
||||
} else {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "cache add failed";
|
||||
}
|
||||
bdb_cache_add(bdb, ei, op->oq_add.rs_e, &nrdn, locker );
|
||||
|
||||
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
|
||||
rs->sr_text = "txn_commit failed";
|
||||
} else {
|
||||
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
|
||||
rs->sr_text = "txn_commit failed";
|
||||
} else {
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -497,9 +503,6 @@ retry: /* transaction retry */
|
|||
op->o_noop ? " (no-op)" : "", op->oq_add.rs_e->e_id, op->oq_add.rs_e->e_dn );
|
||||
#endif
|
||||
rs->sr_text = NULL;
|
||||
if ( !noop ) {
|
||||
bdb_cache_entry_commit( op->oq_add.rs_e );
|
||||
}
|
||||
}
|
||||
else {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
|
|||
|
|
@ -82,16 +82,39 @@ typedef struct bdb_idl_cache_entry_s {
|
|||
} bdb_idl_cache_entry_t;
|
||||
#endif
|
||||
|
||||
/* BDB backend specific entry info */
|
||||
typedef struct bdb_entry_info {
|
||||
struct bdb_entry_info *bei_parent;
|
||||
ID bei_id;
|
||||
|
||||
int bei_state;
|
||||
#define CACHE_ENTRY_DELETED 1
|
||||
|
||||
/*
|
||||
* remaining fields require backend cache lock to access
|
||||
*/
|
||||
struct berval bei_nrdn;
|
||||
struct berval bei_rdn;
|
||||
Entry *bei_e;
|
||||
Avlnode *bei_kids;
|
||||
ldap_pvt_thread_mutex_t bei_kids_mutex;
|
||||
|
||||
struct bdb_entry_info *bei_lrunext; /* for cache lru list */
|
||||
struct bdb_entry_info *bei_lruprev;
|
||||
} EntryInfo;
|
||||
#undef BEI
|
||||
#define BEI(e) ((EntryInfo *) ((e)->e_private))
|
||||
|
||||
/* for the in-core cache of entries */
|
||||
typedef struct bdb_cache {
|
||||
int c_maxsize;
|
||||
int c_cursize;
|
||||
Avlnode *c_dntree;
|
||||
Avlnode *c_idtree;
|
||||
Entry *c_lruhead; /* lru - add accessed entries here */
|
||||
Entry *c_lrutail; /* lru - rem lru entries from here */
|
||||
ldap_pvt_thread_rdwr_t c_rwlock;
|
||||
ldap_pvt_thread_mutex_t lru_mutex;
|
||||
int c_maxsize;
|
||||
int c_cursize;
|
||||
EntryInfo c_dntree;
|
||||
Avlnode *c_idtree;
|
||||
EntryInfo *c_lruhead; /* lru - add accessed entries here */
|
||||
EntryInfo *c_lrutail; /* lru - rem lru entries from here */
|
||||
ldap_pvt_thread_rdwr_t c_rwlock;
|
||||
ldap_pvt_thread_mutex_t lru_mutex;
|
||||
} Cache;
|
||||
|
||||
#define CACHE_READ_LOCK 0
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ bdb_bind( Operation *op, SlapReply *rs )
|
|||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
Entry *e;
|
||||
Attribute *a;
|
||||
Entry *matched;
|
||||
EntryInfo *ei;
|
||||
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
|
||||
char krbname[MAX_K_NAME_SZ + 1];
|
||||
AttributeDescription *krbattr = slap_schema.si_ad_krbName;
|
||||
|
|
@ -59,7 +59,8 @@ bdb_bind( Operation *op, SlapReply *rs )
|
|||
|
||||
dn2entry_retry:
|
||||
/* get entry with reader lock */
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, NULL, &op->o_req_ndn, &e, &matched, 0, locker, &lock );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, NULL, &op->o_req_ndn, &ei, 1,
|
||||
locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
switch(rs->sr_err) {
|
||||
case DB_NOTFOUND:
|
||||
|
|
@ -78,17 +79,17 @@ dn2entry_retry:
|
|||
return rs->sr_err;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if( matched != NULL ) {
|
||||
rs->sr_ref = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
e = ei->bei_e;
|
||||
if ( rs->sr_err == DB_NOTFOUND ) {
|
||||
if( e != NULL ) {
|
||||
rs->sr_ref = is_entry_referral( e )
|
||||
? get_entry_referrals( op, e )
|
||||
: NULL;
|
||||
if (rs->sr_ref)
|
||||
rs->sr_matched = ch_strdup( matched->e_name.bv_val );
|
||||
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
rs->sr_matched = ch_strdup( e->e_name.bv_val );
|
||||
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
e = NULL;
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
NULL, &op->o_req_dn, LDAP_SCOPE_DEFAULT );
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -17,8 +17,8 @@ int
|
|||
bdb_compare( Operation *op, SlapReply *rs )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
Entry *matched;
|
||||
Entry *e;
|
||||
EntryInfo *ei;
|
||||
Attribute *a;
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
|
||||
|
|
@ -36,7 +36,7 @@ bdb_compare( Operation *op, SlapReply *rs )
|
|||
|
||||
dn2entry_retry:
|
||||
/* get entry */
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, NULL, &op->o_req_ndn, &e, &matched, 0, locker, &lock );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, NULL, &op->o_req_ndn, &ei, 1, locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case DB_NOTFOUND:
|
||||
|
|
@ -54,14 +54,15 @@ dn2entry_retry:
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if ( matched != NULL ) {
|
||||
rs->sr_matched = ch_strdup( matched->e_dn );
|
||||
rs->sr_ref = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
e = ei->bei_e;
|
||||
if ( rs->sr_err == DB_NOTFOUND ) {
|
||||
if ( e != NULL ) {
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
rs->sr_ref = is_entry_referral( e )
|
||||
? get_entry_referrals( op, e )
|
||||
: NULL;
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, matched, &lock );
|
||||
matched = NULL;
|
||||
bdb_cache_return_entry_r( bdb->bi_dbenv, &bdb->bi_cache, e, &lock );
|
||||
e = NULL;
|
||||
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
|
|
|
|||
|
|
@ -21,14 +21,15 @@ bdb_delete( Operation *op, SlapReply *rs )
|
|||
struct berval pdn = {0, NULL};
|
||||
Entry *e = NULL;
|
||||
Entry *p = NULL;
|
||||
EntryInfo *ei = NULL, *eip = NULL;
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
AttributeDescription *children = slap_schema.si_ad_children;
|
||||
AttributeDescription *entry = slap_schema.si_ad_entry;
|
||||
DB_TXN *ltid = NULL;
|
||||
DB_TXN *ltid = NULL, *lt2;
|
||||
struct bdb_op_info opinfo;
|
||||
|
||||
u_int32_t locker = 0;
|
||||
DB_LOCK lock;
|
||||
DB_LOCK lock, plock;
|
||||
|
||||
int noop = 0;
|
||||
|
||||
|
|
@ -47,6 +48,7 @@ bdb_delete( Operation *op, SlapReply *rs )
|
|||
retry: /* transaction retry */
|
||||
if( e != NULL ) {
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
e = NULL;
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, DETAIL1,
|
||||
|
|
@ -99,27 +101,38 @@ retry: /* transaction retry */
|
|||
dnParent( &op->o_req_ndn, &pdn );
|
||||
}
|
||||
|
||||
if( pdn.bv_len != 0 ) {
|
||||
/* get parent */
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, ltid, &pdn, &p, NULL, 0, locker, &lock );
|
||||
/* get entry */
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, ltid, &op->o_req_ndn, &ei, 1,
|
||||
locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
case LDAP_BUSY:
|
||||
rs->sr_text = "ldap server busy";
|
||||
goto return_results;
|
||||
default:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
case LDAP_BUSY:
|
||||
rs->sr_text = "ldap server busy";
|
||||
goto return_results;
|
||||
default:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if( p == NULL) {
|
||||
if ( rs->sr_err == 0 ) {
|
||||
e = ei->bei_e;
|
||||
eip = ei->bei_parent;
|
||||
bdb_cache_find_entry_id( op->o_bd, ltid, eip->bei_id, &eip,
|
||||
0, locker, &plock, op->o_tmpmemctx );
|
||||
}
|
||||
if ( eip ) {
|
||||
p = eip->bei_e;
|
||||
}
|
||||
|
||||
if ( pdn.bv_len != 0 ) {
|
||||
if( p == NULL || !bvmatch( &pdn, &p->e_nname )) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, DETAIL1,
|
||||
"<=- bdb_delete: parent does not exist\n", 0, 0, 0 );
|
||||
|
|
@ -208,25 +221,6 @@ retry: /* transaction retry */
|
|||
}
|
||||
}
|
||||
|
||||
/* get entry for read/modify/write */
|
||||
rs->sr_err = bdb_dn2entry_w( op->o_bd, ltid, &op->o_req_ndn, &e, &matched, DB_RMW, locker, &lock );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto retry;
|
||||
case LDAP_BUSY:
|
||||
rs->sr_text = "ldap server busy";
|
||||
goto return_results;
|
||||
default:
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ARGS,
|
||||
|
|
@ -310,7 +304,27 @@ retry: /* transaction retry */
|
|||
goto done;
|
||||
}
|
||||
|
||||
rs->sr_err = bdb_dn2id_children( op->o_bd, ltid, &e->e_nname, 0 );
|
||||
/* nested transaction */
|
||||
rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
|
||||
bdb->bi_db_opflags );
|
||||
rs->sr_text = NULL;
|
||||
if( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
"bdb_delete: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_delete: txn_begin(2) failed: %s (%d)\n",
|
||||
db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#endif
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
/* Can't do it if we have kids */
|
||||
rs->sr_err = ei->bei_kids ? 0 : bdb_dn2id_children( op->o_bd, lt2,
|
||||
&e->e_nname, 0 );
|
||||
if( rs->sr_err != DB_NOTFOUND ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -345,7 +359,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* delete from dn2id */
|
||||
rs->sr_err = bdb_dn2id_delete( op->o_bd, ltid, pdn.bv_val, e );
|
||||
rs->sr_err = bdb_dn2id_delete( op->o_bd, lt2, pdn.bv_val, e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -366,7 +380,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* delete from id2entry */
|
||||
rs->sr_err = bdb_id2entry_delete( op->o_bd, ltid, e );
|
||||
rs->sr_err = bdb_id2entry_delete( op->o_bd, lt2, e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -388,7 +402,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* delete indices for old attributes */
|
||||
rs->sr_err = bdb_index_entry_del( op, ltid, e );
|
||||
rs->sr_err = bdb_index_entry_del( op, lt2, e );
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -406,6 +420,11 @@ retry: /* transaction retry */
|
|||
rs->sr_err = LDAP_OTHER;
|
||||
goto return_results;
|
||||
}
|
||||
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "txn_commit(2) failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
#if 0 /* Do we want to reclaim deleted IDs? */
|
||||
ldap_pvt_thread_mutex_lock( &bdb->bi_lastid_mutex );
|
||||
|
|
@ -423,6 +442,8 @@ retry: /* transaction retry */
|
|||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
bdb_cache_delete_entry( &bdb->bi_cache, e, bdb->bi_dbenv,
|
||||
locker, &lock );
|
||||
rs->sr_err = TXN_COMMIT( ltid, 0 );
|
||||
}
|
||||
ltid = NULL;
|
||||
|
|
@ -477,7 +498,11 @@ return_results:
|
|||
done:
|
||||
/* free entry */
|
||||
if( e != NULL ) {
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
if ( rs->sr_err == LDAP_SUCCESS ) {
|
||||
bdb_entry_return( e );
|
||||
} else {
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
}
|
||||
}
|
||||
|
||||
if( ltid != NULL ) {
|
||||
|
|
|
|||
|
|
@ -15,48 +15,60 @@
|
|||
|
||||
/*
|
||||
* dn2entry - look up dn in the cache/indexes and return the corresponding
|
||||
* entry.
|
||||
* entry. If the requested DN is not found and matched is TRUE, return info
|
||||
* for the closest ancestor of the DN. Otherwise e is NULL.
|
||||
*/
|
||||
|
||||
int
|
||||
bdb_dn2entry_rw(
|
||||
bdb_dn2entry(
|
||||
BackendDB *be,
|
||||
DB_TXN *tid,
|
||||
struct berval *dn,
|
||||
Entry **e,
|
||||
Entry **matched,
|
||||
int flags,
|
||||
int rw,
|
||||
EntryInfo **e,
|
||||
int matched,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock )
|
||||
DB_LOCK *lock,
|
||||
void *ctx )
|
||||
{
|
||||
EntryInfo *ei = NULL;
|
||||
int rc;
|
||||
ID id, id2 = 0;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( CACHE, ARGS, "bdb_dn2entry_rw(\"%s\")\n", dn->bv_val, 0, 0 );
|
||||
LDAP_LOG ( CACHE, ARGS, "bdb_dn2entry(\"%s\")\n", dn->bv_val, 0, 0 );
|
||||
#else
|
||||
Debug(LDAP_DEBUG_TRACE, "bdb_dn2entry_rw(\"%s\")\n",
|
||||
Debug(LDAP_DEBUG_TRACE, "bdb_dn2entry(\"%s\")\n",
|
||||
dn->bv_val, 0, 0 );
|
||||
#endif
|
||||
|
||||
*e = NULL;
|
||||
|
||||
if( matched != NULL ) {
|
||||
*matched = NULL;
|
||||
rc = bdb_dn2id_matched( be, tid, dn, &id, &id2, flags );
|
||||
rc = bdb_cache_find_entry_ndn2id( be, tid, dn, &ei, locker, ctx );
|
||||
if ( rc ) {
|
||||
if ( matched && rc == DB_NOTFOUND ) {
|
||||
/* Set the return value, whether we have its entry
|
||||
* or not.
|
||||
*/
|
||||
*e = ei;
|
||||
if ( ei && ei->bei_id )
|
||||
bdb_cache_find_entry_id( be, tid, ei->bei_id,
|
||||
&ei, 1, locker, lock, ctx );
|
||||
else if ( ei )
|
||||
bdb_cache_entryinfo_unlock( ei );
|
||||
} else if ( ei ) {
|
||||
bdb_cache_entryinfo_unlock( ei );
|
||||
}
|
||||
} else {
|
||||
rc = bdb_dn2id( be, tid, dn, &id, flags );
|
||||
}
|
||||
|
||||
if( rc != 0 ) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if( id2 == 0 ) {
|
||||
rc = bdb_id2entry_rw( be, tid, id, e, rw, locker, lock );
|
||||
} else {
|
||||
rc = bdb_id2entry_r( be, tid, id2, matched, locker, lock );
|
||||
rc = bdb_cache_find_entry_id( be, tid, ei->bei_id, &ei, 1,
|
||||
locker, lock, ctx );
|
||||
if ( rc == 0 ) {
|
||||
*e = ei;
|
||||
} else if ( matched && rc == DB_NOTFOUND ) {
|
||||
/* always return EntryInfo */
|
||||
ei = ei->bei_parent;
|
||||
bdb_cache_find_entry_id( be, tid, ei->bei_id, &ei, 1,
|
||||
locker, lock, ctx );
|
||||
*e = ei;
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
|
|||
|
|
@ -299,7 +299,7 @@ bdb_dn2id(
|
|||
DB_TXN *txn,
|
||||
struct berval *dn,
|
||||
ID *id,
|
||||
int flags )
|
||||
void *ctx )
|
||||
{
|
||||
int rc;
|
||||
DBT key, data;
|
||||
|
|
@ -314,14 +314,9 @@ bdb_dn2id(
|
|||
|
||||
assert (id);
|
||||
|
||||
*id = bdb_cache_find_entry_ndn2id(be, &bdb->bi_cache, dn);
|
||||
if (*id != NOID) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
DBTzero( &key );
|
||||
key.size = dn->bv_len + 2;
|
||||
key.data = ch_malloc( key.size );
|
||||
key.data = sl_malloc( key.size, ctx );
|
||||
((char *)key.data)[0] = DN_BASE_PREFIX;
|
||||
AC_MEMCPY( &((char *)key.data)[1], dn->bv_val, key.size - 1 );
|
||||
|
||||
|
|
@ -332,7 +327,7 @@ bdb_dn2id(
|
|||
data.flags = DB_DBT_USERMEM;
|
||||
|
||||
/* fetch it */
|
||||
rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags | flags);
|
||||
rc = db->get( db, txn, &key, &data, bdb->bi_db_opflags );
|
||||
|
||||
if( rc != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -352,134 +347,7 @@ bdb_dn2id(
|
|||
#endif
|
||||
}
|
||||
|
||||
ch_free( key.data );
|
||||
return rc;
|
||||
}
|
||||
|
||||
int
|
||||
bdb_dn2id_matched(
|
||||
BackendDB *be,
|
||||
DB_TXN *txn,
|
||||
struct berval *in,
|
||||
ID *id,
|
||||
ID *id2,
|
||||
int flags )
|
||||
{
|
||||
int rc;
|
||||
DBT key, data;
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
DB *db = bdb->bi_dn2id->bdi_db;
|
||||
char *buf;
|
||||
struct berval dn;
|
||||
ID cached_id;
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, ARGS,
|
||||
"=> bdb_dn2id_matched( \"%s\" )\n", in->bv_val, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "=> bdb_dn2id_matched( \"%s\" )\n", in->bv_val, 0, 0 );
|
||||
#endif
|
||||
|
||||
DBTzero( &key );
|
||||
key.size = in->bv_len + 2;
|
||||
buf = ch_malloc( key.size );
|
||||
key.data = buf;
|
||||
dn.bv_val = buf+1;
|
||||
dn.bv_len = key.size - 2;
|
||||
AC_MEMCPY( dn.bv_val, in->bv_val, key.size - 1 );
|
||||
|
||||
/* store the ID */
|
||||
DBTzero( &data );
|
||||
data.data = id;
|
||||
data.ulen = sizeof(ID);
|
||||
data.flags = DB_DBT_USERMEM;
|
||||
|
||||
while(1) {
|
||||
dn.bv_val[-1] = DN_BASE_PREFIX;
|
||||
|
||||
*id = NOID;
|
||||
|
||||
/* lookup cache */
|
||||
cached_id = bdb_cache_find_entry_ndn2id(be, &bdb->bi_cache, &dn);
|
||||
|
||||
if (cached_id != NOID) {
|
||||
rc = 0;
|
||||
*id = cached_id;
|
||||
if ( dn.bv_val != buf+1 ) {
|
||||
*id2 = *id;
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
/* fetch it */
|
||||
rc = db->get(db, txn, &key, &data, bdb->bi_db_opflags | flags );
|
||||
}
|
||||
|
||||
if( rc == DB_NOTFOUND ) {
|
||||
struct berval pdn;
|
||||
|
||||
if ( ! be_issuffix( be, &dn ) ) {
|
||||
dnParent( &dn, &pdn );
|
||||
} else {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, DETAIL1,
|
||||
"<= bdb_dn2id_matched: no match\n", 0, 0, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= bdb_dn2id_matched: no match\n",
|
||||
0, 0, 0 );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
key.size = pdn.bv_len + 2;
|
||||
dn = pdn;
|
||||
key.data = pdn.bv_val - 1;
|
||||
|
||||
} else if ( rc == 0 ) {
|
||||
if( data.size != sizeof( ID ) ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, DETAIL1,
|
||||
"<= bdb_dn2id_matched: get size mismatch:"
|
||||
"expected %ld, got %ld\n",
|
||||
(long) sizeof(ID), (long) data.size, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= bdb_dn2id_matched: get size mismatch: "
|
||||
"expected %ld, got %ld\n",
|
||||
(long) sizeof(ID), (long) data.size, 0 );
|
||||
#endif
|
||||
}
|
||||
|
||||
if( dn.bv_val != buf+1 ) {
|
||||
*id2 = *id;
|
||||
}
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, DETAIL1,
|
||||
"<= bdb_dn2id_matched: id=0x%08lx: %s %s\n",
|
||||
(long) *id, *id2 == 0 ? "entry" : "matched", dn.bv_val );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"<= bdb_dn2id_matched: id=0x%08lx: %s %s\n",
|
||||
(long) *id, *id2 == 0 ? "entry" : "matched", dn.bv_val );
|
||||
#endif
|
||||
break;
|
||||
|
||||
} else {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, ERR,
|
||||
"<= bdb_dn2id_matched: get failed: %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"<= bdb_dn2id_matched: get failed: %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ch_free( buf );
|
||||
sl_free( key.data, ctx );
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -523,11 +391,11 @@ bdb_dn2id_children(
|
|||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( INDEX, DETAIL1,
|
||||
"<= bdb_dn2id_children( %s ): %schildren (%d)\n",
|
||||
"<= bdb_dn2id_children( %s ): %s (%d)\n",
|
||||
dn->bv_val, rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
|
||||
db_strerror(rc)), rc );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %schildren (%d)\n",
|
||||
Debug( LDAP_DEBUG_TRACE, "<= bdb_dn2id_children( %s ): %s (%d)\n",
|
||||
dn->bv_val,
|
||||
rc == 0 ? "" : ( rc == DB_NOTFOUND ? "no " :
|
||||
db_strerror(rc) ), rc );
|
||||
|
|
|
|||
|
|
@ -76,14 +76,11 @@ int bdb_id2entry_update(
|
|||
return bdb_id2entry_put(be, tid, e, 0);
|
||||
}
|
||||
|
||||
int bdb_id2entry_rw(
|
||||
int bdb_id2entry(
|
||||
BackendDB *be,
|
||||
DB_TXN *tid,
|
||||
ID id,
|
||||
Entry **e,
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock )
|
||||
Entry **e )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
DB *db = bdb->bi_id2entry->bdi_db;
|
||||
|
|
@ -100,12 +97,8 @@ int bdb_id2entry_rw(
|
|||
DBTzero( &data );
|
||||
data.flags = DB_DBT_MALLOC;
|
||||
|
||||
if ((*e = bdb_cache_find_entry_id(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock)) != NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* fetch it */
|
||||
rc = db->get( db, tid, &key, &data, bdb->bi_db_opflags | ( rw ? DB_RMW : 0 ));
|
||||
rc = db->get( db, tid, &key, &data, bdb->bi_db_opflags );
|
||||
|
||||
if( rc != 0 ) {
|
||||
return rc;
|
||||
|
|
@ -128,38 +121,6 @@ int bdb_id2entry_rw(
|
|||
#ifdef BDB_HIER
|
||||
bdb_fix_dn(be, id, *e);
|
||||
#endif
|
||||
ret = bdb_cache_add_entry_rw( bdb->bi_dbenv,
|
||||
&bdb->bi_cache, *e, rw, locker, lock);
|
||||
while ( ret == 1 || ret == -1 ) {
|
||||
Entry *ee;
|
||||
int add_loop_cnt = 0;
|
||||
if ( (*e)->e_private != NULL ) {
|
||||
free ((*e)->e_private);
|
||||
}
|
||||
(*e)->e_private = NULL;
|
||||
if ( (ee = bdb_cache_find_entry_id
|
||||
(bdb->bi_dbenv, &bdb->bi_cache, id, rw, locker, lock) ) != NULL) {
|
||||
bdb_entry_return ( *e );
|
||||
*e = ee;
|
||||
return 0;
|
||||
}
|
||||
if ( ++add_loop_cnt == BDB_MAX_ADD_LOOP ) {
|
||||
bdb_entry_return ( *e );
|
||||
*e = NULL;
|
||||
return LDAP_BUSY;
|
||||
}
|
||||
}
|
||||
if ( ret != 0 ) {
|
||||
if ( (*e)->e_private != NULL )
|
||||
free ( (*e)->e_private );
|
||||
bdb_entry_return( *e );
|
||||
*e = NULL;
|
||||
}
|
||||
rc = ret;
|
||||
}
|
||||
|
||||
if (rc == 0) {
|
||||
bdb_cache_entry_commit(*e);
|
||||
}
|
||||
|
||||
return rc;
|
||||
|
|
@ -175,8 +136,6 @@ int bdb_id2entry_delete(
|
|||
DBT key;
|
||||
int rc;
|
||||
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
|
||||
DBTzero( &key );
|
||||
key.data = (char *) &e->e_id;
|
||||
key.size = sizeof(ID);
|
||||
|
|
@ -252,7 +211,7 @@ int bdb_entry_release(
|
|||
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 );
|
||||
ch_free( boi );
|
||||
sl_free( boi, o->o_tmpmemctx );
|
||||
o->o_private = NULL;
|
||||
}
|
||||
} else {
|
||||
|
|
@ -279,6 +238,7 @@ int bdb_entry_get(
|
|||
struct bdb_op_info *boi = NULL;
|
||||
DB_TXN *txn = NULL;
|
||||
Entry *e;
|
||||
EntryInfo *ei;
|
||||
int rc;
|
||||
const char *at_name = at->ad_cname.bv_val;
|
||||
|
||||
|
|
@ -321,7 +281,7 @@ int bdb_entry_get(
|
|||
|
||||
dn2entry_retry:
|
||||
/* can we find entry */
|
||||
rc = bdb_dn2entry_rw( op->o_bd, txn, ndn, &e, NULL, 0, rw, locker, &lock );
|
||||
rc = bdb_dn2entry( op->o_bd, txn, ndn, &ei, 0, locker, &lock, op->o_tmpmemctx );
|
||||
switch( rc ) {
|
||||
case DB_NOTFOUND:
|
||||
case 0:
|
||||
|
|
@ -342,6 +302,7 @@ dn2entry_retry:
|
|||
}
|
||||
return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
|
||||
}
|
||||
if (ei) e = ei->bei_e;
|
||||
if (e == NULL) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG( BACK_BDB, INFO,
|
||||
|
|
@ -417,7 +378,7 @@ return_results:
|
|||
* release it later??
|
||||
*/
|
||||
if ( op && !boi ) {
|
||||
boi = ch_calloc(1,sizeof(struct bdb_op_info));
|
||||
boi = sl_calloc(1,sizeof(struct bdb_op_info),op->o_tmpmemctx);
|
||||
boi->boi_lock = lock;
|
||||
op->o_private = boi;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -502,8 +502,6 @@ bdb_db_destroy( BackendDB *be )
|
|||
#endif
|
||||
}
|
||||
|
||||
bdb_cache_release_all (&bdb->bi_cache);
|
||||
|
||||
rc = bdb->bi_dbenv->close( bdb->bi_dbenv, 0 );
|
||||
bdb->bi_dbenv = NULL;
|
||||
if( rc != 0 ) {
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ int bdb_modify_internal(
|
|||
return LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
||||
/* save_attrs will be disposed of by bdb_cache_modify */
|
||||
save_attrs = e->e_attrs;
|
||||
e->e_attrs = attrs_dup( e->e_attrs );
|
||||
|
||||
|
|
@ -255,13 +256,6 @@ int bdb_modify_internal(
|
|||
}
|
||||
}
|
||||
|
||||
/* If we've done repeated mods on a cached entry, then e_attrs
|
||||
* is no longer contiguous with the entry.
|
||||
*/
|
||||
if( (void *) save_attrs != (void *) (e+1)) {
|
||||
attrs_free( save_attrs );
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
|
@ -270,13 +264,14 @@ int
|
|||
bdb_modify( Operation *op, SlapReply *rs )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
Entry *matched = NULL;
|
||||
Entry *e = NULL;
|
||||
EntryInfo *ei = NULL;
|
||||
int manageDSAit = get_manageDSAit( op );
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
DB_TXN *ltid = NULL;
|
||||
DB_TXN *ltid = NULL, *lt2;
|
||||
struct bdb_op_info opinfo;
|
||||
Entry dummy;
|
||||
|
||||
u_int32_t locker = 0;
|
||||
DB_LOCK lock;
|
||||
|
|
@ -297,8 +292,8 @@ bdb_modify( Operation *op, SlapReply *rs )
|
|||
if( 0 ) {
|
||||
retry: /* transaction retry */
|
||||
if( e != NULL ) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
e = NULL;
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, DETAIL1, "bdb_modify: retrying...\n", 0, 0, 0 );
|
||||
|
|
@ -356,8 +351,9 @@ retry: /* transaction retry */
|
|||
opinfo.boi_acl_cache = op->o_do_not_cache;
|
||||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rs->sr_err = bdb_dn2entry_w( op->o_bd, ltid, &op->o_req_ndn, &e, &matched, 0, locker, &lock );
|
||||
/* get entry or ancestor */
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, ltid, &op->o_req_ndn, &ei, 1,
|
||||
locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
if ( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -384,15 +380,16 @@ retry: /* transaction retry */
|
|||
}
|
||||
}
|
||||
|
||||
e = ei->bei_e;
|
||||
/* acquire and lock entry */
|
||||
if ( e == NULL ) {
|
||||
if ( matched != NULL ) {
|
||||
rs->sr_matched = ch_strdup( matched->e_dn );
|
||||
rs->sr_ref = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
if ( rs->sr_err == DB_NOTFOUND ) {
|
||||
if ( e != NULL ) {
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
rs->sr_ref = is_entry_referral( e )
|
||||
? get_entry_referrals( op, e )
|
||||
: NULL;
|
||||
bdb_unlocked_cache_return_entry_r (&bdb->bi_cache, matched);
|
||||
matched = NULL;
|
||||
bdb_unlocked_cache_return_entry_r (&bdb->bi_cache, e);
|
||||
e = NULL;
|
||||
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
|
|
@ -440,9 +437,27 @@ retry: /* transaction retry */
|
|||
}
|
||||
#endif
|
||||
|
||||
/* nested transaction */
|
||||
rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
|
||||
bdb->bi_db_opflags );
|
||||
rs->sr_text = NULL;
|
||||
if( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
"bdb_modify: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_modify: txn_begin(2) failed: %s (%d)\n",
|
||||
db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#endif
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
/* Modify the entry */
|
||||
rs->sr_err = bdb_modify_internal( op, ltid, op->oq_modify.rs_modlist, e,
|
||||
&rs->sr_text, textbuf, textlen );
|
||||
dummy = *e;
|
||||
rs->sr_err = bdb_modify_internal( op, lt2, op->oq_modify.rs_modlist,
|
||||
&dummy, &rs->sr_text, textbuf, textlen );
|
||||
|
||||
if( rs->sr_err != LDAP_SUCCESS ) {
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -465,7 +480,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* change the entry itself */
|
||||
rs->sr_err = bdb_id2entry_update( op->o_bd, ltid, e );
|
||||
rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, &dummy );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
|
|
@ -483,6 +498,11 @@ retry: /* transaction retry */
|
|||
rs->sr_text = "entry update failed";
|
||||
goto return_results;
|
||||
}
|
||||
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "txn_commit(2) failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if( op->o_noop ) {
|
||||
if ( ( rs->sr_err = TXN_ABORT( ltid ) ) != 0 ) {
|
||||
|
|
@ -492,6 +512,7 @@ retry: /* transaction retry */
|
|||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
bdb_cache_modify( e, dummy.e_attrs, bdb->bi_dbenv, locker, &lock );
|
||||
rs->sr_err = TXN_COMMIT( ltid, 0 );
|
||||
}
|
||||
ltid = NULL;
|
||||
|
|
|
|||
|
|
@ -24,14 +24,15 @@ bdb_modrdn( Operation *op, SlapReply *rs )
|
|||
int isroot = -1;
|
||||
Entry *e = NULL;
|
||||
Entry *p = NULL;
|
||||
Entry *matched;
|
||||
EntryInfo *ei = NULL, *eip = NULL, *nei = NULL, *neip = NULL;
|
||||
/* LDAP v2 supporting correct attribute handling. */
|
||||
LDAPRDN new_rdn = NULL;
|
||||
LDAPRDN old_rdn = NULL;
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
DB_TXN * ltid = NULL;
|
||||
DB_TXN *ltid = NULL, *lt2;
|
||||
struct bdb_op_info opinfo;
|
||||
Entry dummy, *save;
|
||||
|
||||
ID id;
|
||||
|
||||
|
|
@ -46,7 +47,7 @@ bdb_modrdn( Operation *op, SlapReply *rs )
|
|||
int manageDSAit = get_manageDSAit( op );
|
||||
|
||||
u_int32_t locker = 0;
|
||||
DB_LOCK lock;
|
||||
DB_LOCK lock, plock, nplock;
|
||||
|
||||
int noop = 0;
|
||||
|
||||
|
|
@ -68,7 +69,6 @@ bdb_modrdn( Operation *op, SlapReply *rs )
|
|||
if( 0 ) {
|
||||
retry: /* transaction retry */
|
||||
if (e != NULL) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
e = NULL;
|
||||
}
|
||||
|
|
@ -137,7 +137,8 @@ retry: /* transaction retry */
|
|||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rs->sr_err = bdb_dn2entry_w( op->o_bd, ltid, &op->o_req_ndn, &e, &matched, DB_RMW, locker, &lock );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, ltid, &op->o_req_ndn, &ei, 1,
|
||||
locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
|
|
@ -155,14 +156,15 @@ retry: /* transaction retry */
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if( matched != NULL ) {
|
||||
rs->sr_matched = ch_strdup( matched->e_dn );
|
||||
rs->sr_ref = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
e = ei->bei_e;
|
||||
if ( rs->sr_err == DB_NOTFOUND ) {
|
||||
if( e != NULL ) {
|
||||
rs->sr_matched = ch_strdup( e->e_dn );
|
||||
rs->sr_ref = is_entry_referral( e )
|
||||
? get_entry_referrals( op, e )
|
||||
: NULL;
|
||||
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, matched);
|
||||
matched = NULL;
|
||||
bdb_unlocked_cache_return_entry_r( &bdb->bi_cache, e);
|
||||
e = NULL;
|
||||
|
||||
} else {
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
|
|
@ -203,7 +205,8 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
#ifndef BDB_HIER
|
||||
rs->sr_err = bdb_dn2id_children( op->o_bd, ltid, &e->e_nname, 0 );
|
||||
rs->sr_err = ei->bei_kids ? 0 : bdb_dn2id_children( op->o_bd, ltid,
|
||||
&e->e_nname, 0 );
|
||||
if ( rs->sr_err != DB_NOTFOUND ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -269,7 +272,9 @@ retry: /* transaction retry */
|
|||
/* Make sure parent entry exist and we can write its
|
||||
* children.
|
||||
*/
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, ltid, &p_ndn, &p, NULL, 0, locker, &lock );
|
||||
eip = ei->bei_parent;
|
||||
rs->sr_err = bdb_cache_find_entry_id( op->o_bd, ltid,
|
||||
eip->bei_id, &eip, 0, locker, &plock, op->o_tmpmemctx );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
|
|
@ -287,6 +292,7 @@ retry: /* transaction retry */
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
p = eip->bei_e;
|
||||
if( p == NULL) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
|
|
@ -459,11 +465,11 @@ retry: /* transaction retry */
|
|||
/* newSuperior == entry being moved?, if so ==> ERROR */
|
||||
/* Get Entry with dn=newSuperior. Does newSuperior exist? */
|
||||
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd,
|
||||
ltid, np_ndn, &np, NULL, 0, locker, &lock );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, ltid, np_ndn,
|
||||
&neip, 0, locker, &nplock, op->o_tmpmemctx );
|
||||
|
||||
switch( rs->sr_err ) {
|
||||
case 0:
|
||||
case 0: np = neip->bei_e;
|
||||
case DB_NOTFOUND:
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -661,7 +667,11 @@ retry: /* transaction retry */
|
|||
new_ndn.bv_val, 0, 0 );
|
||||
#endif
|
||||
|
||||
rs->sr_err = bdb_dn2id ( op->o_bd, ltid, &new_ndn, &id, 0 );
|
||||
/* Shortcut the search */
|
||||
nei = neip ? neip : eip;
|
||||
rs->sr_err = bdb_cache_find_entry_ndn2id ( op->o_bd, ltid, &new_ndn,
|
||||
&nei, locker, op->o_tmpmemctx );
|
||||
if ( nei ) bdb_cache_entryinfo_unlock( nei );
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
|
|
@ -741,9 +751,31 @@ retry: /* transaction retry */
|
|||
goto return_results;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* nested transaction */
|
||||
rs->sr_err = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
|
||||
bdb->bi_db_opflags );
|
||||
rs->sr_text = NULL;
|
||||
if( rs->sr_err != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
"bdb_modrdn: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_modrdn: txn_begin(2) failed: %s (%d)\n",
|
||||
db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#endif
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
dummy = *e;
|
||||
save = e;
|
||||
e = &dummy;
|
||||
|
||||
/* delete old one */
|
||||
rs->sr_err = bdb_dn2id_delete( op->o_bd, ltid, p_ndn.bv_val, e );
|
||||
rs->sr_err = bdb_dn2id_delete( op->o_bd, lt2, p_ndn.bv_val, e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -755,14 +787,12 @@ retry: /* transaction retry */
|
|||
goto return_results;
|
||||
}
|
||||
|
||||
(void) bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
|
||||
/* Binary format uses a single contiguous block, cannot
|
||||
* free individual fields. But if a previous modrdn has
|
||||
* already happened, must free the names.
|
||||
* already happened, must free the names. The frees are
|
||||
* done in bdb_cache_modrdn().
|
||||
*/
|
||||
#ifdef BDB_HIER
|
||||
ch_free(e->e_name.bv_val);
|
||||
e->e_name.bv_val = ch_malloc(new_dn.bv_len + new_ndn.bv_len + 2);
|
||||
e->e_name.bv_len = new_dn.bv_len;
|
||||
e->e_nname.bv_val = e->e_name.bv_val + new_dn.bv_len + 1;
|
||||
|
|
@ -772,8 +802,6 @@ retry: /* transaction retry */
|
|||
#else
|
||||
if( e->e_nname.bv_val < e->e_bv.bv_val || e->e_nname.bv_val >
|
||||
e->e_bv.bv_val + e->e_bv.bv_len ) {
|
||||
ch_free(e->e_name.bv_val);
|
||||
ch_free(e->e_nname.bv_val);
|
||||
e->e_name.bv_val = NULL;
|
||||
e->e_nname.bv_val = NULL;
|
||||
}
|
||||
|
|
@ -783,7 +811,7 @@ retry: /* transaction retry */
|
|||
new_ndn.bv_val = NULL;
|
||||
#endif
|
||||
/* add new one */
|
||||
rs->sr_err = bdb_dn2id_add( op->o_bd, ltid, np_ndn, e );
|
||||
rs->sr_err = bdb_dn2id_add( op->o_bd, lt2, np_ndn, e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -804,7 +832,7 @@ retry: /* transaction retry */
|
|||
#endif
|
||||
|
||||
/* modify entry */
|
||||
rs->sr_err = bdb_modify_internal( op, ltid, &mod[0], e,
|
||||
rs->sr_err = bdb_modify_internal( op, lt2, &mod[0], e,
|
||||
&rs->sr_text, textbuf, textlen );
|
||||
|
||||
if( rs->sr_err != LDAP_SUCCESS ) {
|
||||
|
|
@ -820,7 +848,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* id2entry index */
|
||||
rs->sr_err = bdb_id2entry_update( op->o_bd, ltid, e );
|
||||
rs->sr_err = bdb_id2entry_update( op->o_bd, lt2, e );
|
||||
if ( rs->sr_err != 0 ) {
|
||||
switch( rs->sr_err ) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -831,6 +859,11 @@ retry: /* transaction retry */
|
|||
rs->sr_text = "entry update failed";
|
||||
goto return_results;
|
||||
}
|
||||
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "txn_commit(2) failed";
|
||||
goto return_results;
|
||||
}
|
||||
|
||||
if( op->o_noop ) {
|
||||
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
|
||||
|
|
@ -849,21 +882,12 @@ retry: /* transaction retry */
|
|||
if(( rs->sr_err=TXN_PREPARE( ltid, gid )) != 0 ) {
|
||||
rs->sr_text = "txn_prepare failed";
|
||||
} else {
|
||||
if( bdb_cache_update_entry(&bdb->bi_cache, e) == -1 ) {
|
||||
if(( rs->sr_err=TXN_ABORT( ltid )) != 0 ) {
|
||||
rs->sr_text ="cache update & txn_abort failed";
|
||||
} else {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
rs->sr_text = "cache update failed";
|
||||
}
|
||||
|
||||
bdb_cache_modrdn( save, &op->orr_newrdn, e, neip,
|
||||
bdb->bi_dbenv, locker, &lock );
|
||||
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
|
||||
rs->sr_text = "txn_commit failed";
|
||||
} else {
|
||||
bdb_cache_entry_commit( e );
|
||||
if(( rs->sr_err=TXN_COMMIT( ltid, 0 )) != 0 ) {
|
||||
rs->sr_text = "txn_commit failed";
|
||||
} else {
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -20,8 +20,9 @@ bdb_exop_passwd( Operation *op, SlapReply *rs )
|
|||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
int rc;
|
||||
Entry *e = NULL;
|
||||
EntryInfo *ei;
|
||||
struct berval hash = { 0, NULL };
|
||||
DB_TXN *ltid = NULL;
|
||||
DB_TXN *ltid = NULL, *lt2;
|
||||
struct bdb_op_info opinfo;
|
||||
char textbuf[SLAP_TEXT_BUFLEN];
|
||||
size_t textlen = sizeof textbuf;
|
||||
|
|
@ -101,7 +102,6 @@ bdb_exop_passwd( Operation *op, SlapReply *rs )
|
|||
if( 0 ) {
|
||||
retry: /* transaction retry */
|
||||
if ( e != NULL ) {
|
||||
bdb_cache_delete_entry(&bdb->bi_cache, e);
|
||||
bdb_unlocked_cache_return_entry_w(&bdb->bi_cache, e);
|
||||
}
|
||||
#ifdef NEW_LOGGING
|
||||
|
|
@ -150,7 +150,7 @@ retry: /* transaction retry */
|
|||
op->o_private = &opinfo;
|
||||
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_w( op->o_bd, ltid, &ndn, &e, NULL, 0 , locker, &lock);
|
||||
rc = bdb_dn2entry( op->o_bd, ltid, &ndn, &ei, 0 , locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
switch(rc) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -168,6 +168,8 @@ retry: /* transaction retry */
|
|||
goto done;
|
||||
}
|
||||
|
||||
if ( ei ) e = ei->bei_e;
|
||||
|
||||
if( e == NULL ) {
|
||||
rs->sr_text = "could not locate authorization entry";
|
||||
rc = LDAP_NO_SUCH_OBJECT;
|
||||
|
|
@ -198,9 +200,31 @@ retry: /* transaction retry */
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* nested transaction */
|
||||
rc = TXN_BEGIN( bdb->bi_dbenv, ltid, <2,
|
||||
bdb->bi_db_opflags );
|
||||
rs->sr_text = NULL;
|
||||
if( rc != 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, ERR,
|
||||
"bdb_exop_passwd: txn_begin(2) failed: %s (%d)\n", db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#else
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"bdb_exop_passwd: txn_begin(2) failed: %s (%d)\n",
|
||||
db_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
#endif
|
||||
rc = LDAP_OTHER;
|
||||
rs->sr_text = "internal error";
|
||||
goto done;
|
||||
}
|
||||
{
|
||||
Modifications ml;
|
||||
struct berval vals[2];
|
||||
Entry dummy, *save;
|
||||
|
||||
save = e;
|
||||
dummy = *e;
|
||||
e = &dummy;
|
||||
|
||||
vals[0] = hash;
|
||||
vals[1].bv_val = NULL;
|
||||
|
|
@ -211,7 +235,7 @@ retry: /* transaction retry */
|
|||
ml.sml_op = LDAP_MOD_REPLACE;
|
||||
ml.sml_next = NULL;
|
||||
|
||||
rc = bdb_modify_internal( op, ltid,
|
||||
rc = bdb_modify_internal( op, lt2,
|
||||
&ml, e, &rs->sr_text, textbuf, textlen );
|
||||
|
||||
if ( (rc == LDAP_INSUFFICIENT_ACCESS) && opinfo.boi_err ) {
|
||||
|
|
@ -232,7 +256,7 @@ retry: /* transaction retry */
|
|||
}
|
||||
|
||||
/* change the entry itself */
|
||||
rc = bdb_id2entry_update( op->o_bd, ltid, e );
|
||||
rc = bdb_id2entry_update( op->o_bd, lt2, e );
|
||||
if( rc != 0 ) {
|
||||
switch(rc) {
|
||||
case DB_LOCK_DEADLOCK:
|
||||
|
|
@ -242,11 +266,17 @@ retry: /* transaction retry */
|
|||
rs->sr_text = "entry update failed";
|
||||
rc = LDAP_OTHER;
|
||||
}
|
||||
if ( TXN_COMMIT( lt2, 0 ) != 0 ) {
|
||||
rc = LDAP_OTHER;
|
||||
rs->sr_text = "txn_commit(2) failed";
|
||||
}
|
||||
|
||||
if( rc == 0 ) {
|
||||
if( op->o_noop ) {
|
||||
rc = TXN_ABORT( ltid );
|
||||
} else {
|
||||
bdb_cache_modify( save, e->e_attrs,
|
||||
bdb->bi_dbenv, locker, &lock );
|
||||
rc = TXN_COMMIT( ltid, 0 );
|
||||
}
|
||||
ltid = NULL;
|
||||
|
|
|
|||
|
|
@ -52,13 +52,9 @@ bdb_db_cache(
|
|||
/*
|
||||
* dn2entry.c
|
||||
*/
|
||||
int bdb_dn2entry_rw LDAP_P(( BackendDB *be, DB_TXN *tid,
|
||||
struct berval *dn, Entry **e, Entry **matched, int flags, int rw,
|
||||
u_int32_t locker, DB_LOCK *lock));
|
||||
#define bdb_dn2entry_r(be, tid, dn, e, m, f, locker, lock) \
|
||||
bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 0, locker, lock)
|
||||
#define bdb_dn2entry_w(be, tid, dn, e, m, f, locker, lock) \
|
||||
bdb_dn2entry_rw((be), (tid), (dn), (e), (m), (f), 1, locker, lock)
|
||||
int bdb_dn2entry LDAP_P(( BackendDB *be, DB_TXN *tid,
|
||||
struct berval *dn, EntryInfo **e, int matched,
|
||||
u_int32_t locker, DB_LOCK *lock, void *ctx));
|
||||
|
||||
/*
|
||||
* dn2id.c
|
||||
|
|
@ -68,15 +64,7 @@ int bdb_dn2id(
|
|||
DB_TXN *tid,
|
||||
struct berval *dn,
|
||||
ID *id,
|
||||
int flags );
|
||||
|
||||
int bdb_dn2id_matched(
|
||||
BackendDB *be,
|
||||
DB_TXN *tid,
|
||||
struct berval *dn,
|
||||
ID *id,
|
||||
ID *id2,
|
||||
int flags );
|
||||
void *ctx );
|
||||
|
||||
int bdb_dn2id_add(
|
||||
BackendDB *be,
|
||||
|
|
@ -143,18 +131,11 @@ int bdb_id2entry_delete(
|
|||
DB_TXN *tid,
|
||||
Entry *e);
|
||||
|
||||
int bdb_id2entry_rw(
|
||||
int bdb_id2entry(
|
||||
BackendDB *be,
|
||||
DB_TXN *tid,
|
||||
ID id,
|
||||
Entry **e,
|
||||
int rw,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock );
|
||||
#define bdb_id2entry_r(be, tid, id, e, locker, lock) \
|
||||
bdb_id2entry_rw((be), (tid), (id), (e), 0, locker, lock)
|
||||
#define bdb_id2entry_w(be, tid, id, e, locker, lock) \
|
||||
bdb_id2entry_rw((be), (tid), (id), (e), 1, locker, lock)
|
||||
Entry **e);
|
||||
|
||||
void bdb_entry_free ( Entry *e );
|
||||
|
||||
|
|
@ -303,46 +284,84 @@ BI_op_extended bdb_exop_passwd;
|
|||
* cache.c
|
||||
*/
|
||||
|
||||
void bdb_cache_entry_commit( Entry *e );
|
||||
#define bdb_cache_entryinfo_lock(e) \
|
||||
ldap_pvt_thread_mutex_lock( &(e)->bei_kids_mutex )
|
||||
#define bdb_cache_entryinfo_unlock(e) \
|
||||
ldap_pvt_thread_mutex_unlock( &(e)->bei_kids_mutex )
|
||||
|
||||
#if 0
|
||||
void bdb_cache_return_entry_rw( DB_ENV *env, Cache *cache, Entry *e,
|
||||
int rw, DB_LOCK *lock );
|
||||
#else
|
||||
#define bdb_cache_return_entry_rw( env, cache, e, rw, lock ) \
|
||||
bdb_cache_entry_db_unlock( env, lock )
|
||||
#define bdb_cache_return_entry( env, lock ) \
|
||||
bdb_cache_entry_db_unlock( env, lock )
|
||||
#endif
|
||||
#define bdb_cache_return_entry_r(env, c, e, l) \
|
||||
bdb_cache_return_entry_rw((env), (c), (e), 0, (l))
|
||||
#define bdb_cache_return_entry_w(env, c, e, l) \
|
||||
bdb_cache_return_entry_rw((env), (c), (e), 1, (l))
|
||||
#if 0
|
||||
void bdb_unlocked_cache_return_entry_rw( Cache *cache, Entry *e, int rw );
|
||||
#else
|
||||
#define bdb_unlocked_cache_return_entry_rw( a, b, c )
|
||||
#endif
|
||||
#define bdb_unlocked_cache_return_entry_r( c, e ) \
|
||||
bdb_unlocked_cache_return_entry_rw((c), (e), 0)
|
||||
#define bdb_unlocked_cache_return_entry_w( c, e ) \
|
||||
bdb_unlocked_cache_return_entry_rw((c), (e), 1)
|
||||
int bdb_cache_add_entry_rw(
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
int bdb_cache_add(
|
||||
struct bdb_info *bdb,
|
||||
EntryInfo *pei,
|
||||
Entry *e,
|
||||
int rw,
|
||||
struct berval *nrdn,
|
||||
u_int32_t locker
|
||||
);
|
||||
int bdb_cache_modrdn(
|
||||
Entry *e,
|
||||
struct berval *nrdn,
|
||||
Entry *new,
|
||||
EntryInfo *ein,
|
||||
DB_ENV *env,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
DB_LOCK *lock
|
||||
);
|
||||
int bdb_cache_modify(
|
||||
Entry *e,
|
||||
Attribute *newAttrs,
|
||||
DB_ENV *env,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
);
|
||||
int bdb_cache_update_entry(
|
||||
Cache *cache,
|
||||
Entry *e
|
||||
);
|
||||
ID bdb_cache_find_entry_ndn2id(
|
||||
Backend *be,
|
||||
Cache *cache,
|
||||
struct berval *ndn
|
||||
);
|
||||
Entry* bdb_cache_find_entry_id(
|
||||
DB_ENV *env,
|
||||
Cache *cache,
|
||||
ID id,
|
||||
int rw,
|
||||
int bdb_cache_find_entry_ndn2id(
|
||||
Backend *be,
|
||||
DB_TXN *txn,
|
||||
struct berval *ndn,
|
||||
EntryInfo **res,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
void *ctx
|
||||
);
|
||||
int bdb_cache_find_entry_id(
|
||||
Backend *be,
|
||||
DB_TXN *tid,
|
||||
ID id,
|
||||
EntryInfo **eip,
|
||||
int islocked,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock,
|
||||
void *ctx
|
||||
);
|
||||
int bdb_cache_delete_entry(
|
||||
Cache *cache,
|
||||
Entry *e
|
||||
Cache *cache,
|
||||
Entry *e,
|
||||
DB_ENV *env,
|
||||
u_int32_t locker,
|
||||
DB_LOCK *lock
|
||||
);
|
||||
void bdb_cache_release_all( Cache *cache );
|
||||
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ bdb_referrals( Operation *op, SlapReply *rs )
|
|||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
Entry *e = NULL;
|
||||
Entry *matched = NULL;
|
||||
EntryInfo *ei;
|
||||
int rc = LDAP_SUCCESS;
|
||||
|
||||
u_int32_t locker;
|
||||
|
|
@ -43,20 +43,15 @@ bdb_referrals( Operation *op, SlapReply *rs )
|
|||
|
||||
dn2entry_retry:
|
||||
/* get entry */
|
||||
rc = bdb_dn2entry_r( op->o_bd, NULL, &op->o_req_ndn, &e, &matched, 0, locker, &lock );
|
||||
rc = bdb_dn2entry( op->o_bd, NULL, &op->o_req_ndn, &ei, 1, locker,
|
||||
&lock, op->o_tmpmemctx );
|
||||
|
||||
e = ei->bei_e;
|
||||
switch(rc) {
|
||||
case DB_NOTFOUND:
|
||||
rc = 0;
|
||||
case 0:
|
||||
break;
|
||||
case LDAP_BUSY:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
return LDAP_BUSY;
|
||||
|
|
@ -73,20 +68,15 @@ dn2entry_retry:
|
|||
"bdb_referrals: dn2entry failed: %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
#endif
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
}
|
||||
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
|
||||
LOCK_ID_FREE ( bdb->bi_dbenv, locker );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if ( matched != NULL ) {
|
||||
rs->sr_matched = ch_strdup( matched->e_name.bv_val );
|
||||
if ( rc == DB_NOTFOUND ) {
|
||||
rc = 0;
|
||||
if ( e != NULL ) {
|
||||
rs->sr_matched = ch_strdup( e->e_name.bv_val );
|
||||
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, DETAIL1,
|
||||
|
|
@ -98,13 +88,13 @@ dn2entry_retry:
|
|||
(long) op->o_tag, op->o_req_dn.bv_val, rs->sr_matched );
|
||||
#endif
|
||||
|
||||
if( is_entry_referral( matched ) ) {
|
||||
if( is_entry_referral( e ) ) {
|
||||
rc = LDAP_OTHER;
|
||||
rs->sr_ref = get_entry_referrals( op, matched );
|
||||
rs->sr_ref = get_entry_referrals( op, e );
|
||||
}
|
||||
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, matched, &lock);
|
||||
matched = NULL;
|
||||
bdb_cache_return_entry_r (bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
e = NULL;
|
||||
} else if ( default_referral != NULL ) {
|
||||
rc = LDAP_OTHER;
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ static void send_pagerequest_response(
|
|||
* dereferenced entry on success, NULL on any failure.
|
||||
*/
|
||||
static Entry * deref_base (
|
||||
BackendDB *be,
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
Entry *e,
|
||||
Entry **matched,
|
||||
|
|
@ -44,14 +44,15 @@ static Entry * deref_base (
|
|||
ID *tmp,
|
||||
ID *visited )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
|
||||
struct berval ndn;
|
||||
EntryInfo *ei;
|
||||
DB_LOCK lockr;
|
||||
|
||||
rs->sr_err = LDAP_ALIAS_DEREF_PROBLEM;
|
||||
rs->sr_text = "maximum deref depth exceeded";
|
||||
|
||||
while (BDB_IDL_N(tmp) < be->be_max_deref_depth) {
|
||||
while (BDB_IDL_N(tmp) < op->o_bd->be_max_deref_depth) {
|
||||
|
||||
/* Remember the last entry we looked at, so we can
|
||||
* report broken links
|
||||
|
|
@ -84,8 +85,9 @@ static Entry * deref_base (
|
|||
break;
|
||||
}
|
||||
|
||||
rs->sr_err = bdb_dn2entry_r( be, NULL, &ndn, &e,
|
||||
NULL, 0, locker, &lockr );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, NULL, &ndn, &ei,
|
||||
0, locker, &lockr, op->o_tmpmemctx );
|
||||
if ( ei ) e = ei->bei_e;
|
||||
if (!e) {
|
||||
rs->sr_err = LDAP_ALIAS_PROBLEM;
|
||||
rs->sr_text = "aliasedObject not found";
|
||||
|
|
@ -129,6 +131,7 @@ static int search_aliases(
|
|||
ID *aliases, *curscop, *subscop, *visited, *newsubs, *oldsubs, *tmp;
|
||||
ID cursora, ida, cursoro, ido, *subscop2;
|
||||
Entry *matched, *a;
|
||||
EntryInfo *ei;
|
||||
struct berval bv_alias = { sizeof("alias")-1, "alias" };
|
||||
AttributeAssertion aa_alias;
|
||||
Filter af;
|
||||
|
|
@ -194,11 +197,13 @@ static int search_aliases(
|
|||
for (ida = bdb_idl_first(curscop, &cursora); ida != NOID;
|
||||
ida = bdb_idl_next(curscop, &cursora))
|
||||
{
|
||||
rs->sr_err = bdb_id2entry_r(op->o_bd, NULL, ida, &a,
|
||||
locker, &lockr);
|
||||
ei = NULL;
|
||||
rs->sr_err = bdb_cache_find_entry_id(op->o_bd, NULL,
|
||||
ida, &ei, 0, locker, &lockr, op->o_tmpmemctx );
|
||||
if (rs->sr_err != LDAP_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
a = ei->bei_e;
|
||||
|
||||
/* This should only happen if the curscop IDL has maxed out and
|
||||
* turned into a range that spans IDs indiscriminately
|
||||
|
|
@ -211,7 +216,7 @@ static int search_aliases(
|
|||
|
||||
/* Actually dereference the alias */
|
||||
BDB_IDL_ZERO(tmp);
|
||||
a = deref_base( op->o_bd, rs, a, &matched, locker, &lockr,
|
||||
a = deref_base( op, rs, a, &matched, locker, &lockr,
|
||||
tmp, visited );
|
||||
if (a) {
|
||||
/* If the target was not already in our current candidates,
|
||||
|
|
@ -257,8 +262,11 @@ nextido:
|
|||
* we should never see the ID of an entry that doesn't exist.
|
||||
* Set the name so that the scope's IDL can be retrieved.
|
||||
*/
|
||||
rs->sr_err = bdb_id2entry_r(op->o_bd, NULL, ido, &e, locker, &locka);
|
||||
ei = NULL;
|
||||
rs->sr_err = bdb_cache_find_entry_id(op->o_bd, NULL, ido, &ei,
|
||||
0, locker, &locka, op->o_tmpmemctx );
|
||||
if (rs->sr_err != LDAP_SUCCESS) goto nextido;
|
||||
e = ei->bei_e;
|
||||
sf->f_dn = &e->e_nname;
|
||||
}
|
||||
return rs->sr_err;
|
||||
|
|
@ -338,8 +346,9 @@ int bdb_search( Operation *op, SlapReply *rs )
|
|||
time_t stoptime;
|
||||
ID id, cursor;
|
||||
ID candidates[BDB_IDL_UM_SIZE];
|
||||
Entry *e = NULL;
|
||||
Entry *e = NULL, dummy;
|
||||
Entry *matched = NULL;
|
||||
EntryInfo *ei;
|
||||
struct berval realbase = { 0, NULL };
|
||||
int manageDSAit;
|
||||
int tentries = 0;
|
||||
|
|
@ -451,22 +460,16 @@ int bdb_search( Operation *op, SlapReply *rs )
|
|||
} else {
|
||||
dn2entry_retry:
|
||||
/* get entry with reader lock */
|
||||
rs->sr_err = bdb_dn2entry_r( op->o_bd, NULL, &sop->o_req_ndn, &e,
|
||||
&matched, 0, locker, &lock );
|
||||
rs->sr_err = bdb_dn2entry( op->o_bd, NULL, &sop->o_req_ndn, &ei,
|
||||
1, locker, &lock, op->o_tmpmemctx );
|
||||
}
|
||||
|
||||
switch(rs->sr_err) {
|
||||
case DB_NOTFOUND:
|
||||
matched = ei->bei_e; break;
|
||||
case 0:
|
||||
break;
|
||||
e = ei->bei_e; break;
|
||||
case LDAP_BUSY:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
|
||||
matched, &lock);
|
||||
}
|
||||
send_ldap_error( sop, rs, LDAP_BUSY, "ldap server busy" );
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
return LDAP_BUSY;
|
||||
|
|
@ -474,13 +477,6 @@ dn2entry_retry:
|
|||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
if (e != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
if (matched != NULL) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache,
|
||||
matched, &lock);
|
||||
}
|
||||
send_ldap_error( sop, rs, LDAP_OTHER, "internal error" );
|
||||
LOCK_ID_FREE (bdb->bi_dbenv, locker );
|
||||
return rs->sr_err;
|
||||
|
|
@ -488,7 +484,7 @@ dn2entry_retry:
|
|||
|
||||
if ( e && (op->ors_deref & LDAP_DEREF_FINDING) && is_entry_alias(e) ) {
|
||||
BDB_IDL_ZERO(candidates);
|
||||
e = deref_base( op->o_bd, rs, e, &matched, locker, &lock,
|
||||
e = deref_base( op, rs, e, &matched, locker, &lock,
|
||||
candidates, NULL );
|
||||
}
|
||||
|
||||
|
|
@ -648,13 +644,24 @@ dn2entry_retry:
|
|||
/* compute it anyway; root does not use it */
|
||||
stoptime = op->o_time + sop->oq_search.rs_tlimit;
|
||||
|
||||
/* need normalized dn below */
|
||||
ber_dupbv( &realbase, &e->e_nname );
|
||||
|
||||
dummy.e_nname = realbase;
|
||||
dummy.e_id = e->e_id;
|
||||
|
||||
if ( e != &slap_entry_root ) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
e = NULL;
|
||||
|
||||
/* select candidates */
|
||||
if ( sop->oq_search.rs_scope == LDAP_SCOPE_BASE ) {
|
||||
rs->sr_err = base_candidate( op->o_bd, e, candidates );
|
||||
rs->sr_err = base_candidate( op->o_bd, &dummy, candidates );
|
||||
|
||||
} else {
|
||||
BDB_IDL_ALL( bdb, candidates );
|
||||
rs->sr_err = search_candidates( op, sop, rs, e, locker, candidates );
|
||||
rs->sr_err = search_candidates( op, sop, rs, &dummy, locker, candidates );
|
||||
}
|
||||
|
||||
/* start cursor at beginning of candidates.
|
||||
|
|
@ -680,14 +687,6 @@ dn2entry_retry:
|
|||
}
|
||||
#endif
|
||||
|
||||
/* need normalized dn below */
|
||||
ber_dupbv( &realbase, &e->e_nname );
|
||||
|
||||
if ( e != &slap_entry_root ) {
|
||||
bdb_cache_return_entry_r(bdb->bi_dbenv, &bdb->bi_cache, e, &lock);
|
||||
}
|
||||
e = NULL;
|
||||
|
||||
if ( candidates[0] == 0 ) {
|
||||
#ifdef NEW_LOGGING
|
||||
LDAP_LOG ( OPERATION, RESULTS,
|
||||
|
|
@ -849,8 +848,9 @@ loop_begin:
|
|||
#endif
|
||||
id2entry_retry:
|
||||
/* get the entry with reader lock */
|
||||
rs->sr_err = bdb_id2entry_r( op->o_bd, NULL, id,
|
||||
&e, locker, &lock );
|
||||
ei = NULL;
|
||||
rs->sr_err = bdb_cache_find_entry_id( op->o_bd, NULL,
|
||||
id, &ei, 0, locker, &lock, op->o_tmpmemctx );
|
||||
|
||||
if (rs->sr_err == LDAP_BUSY) {
|
||||
rs->sr_text = "ldap server busy";
|
||||
|
|
@ -863,6 +863,12 @@ id2entry_retry:
|
|||
goto id2entry_retry;
|
||||
}
|
||||
|
||||
if ( ei && rs->sr_err == 0 ) {
|
||||
e = ei->bei_e;
|
||||
} else {
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if( !BDB_IDL_IS_RANGE(candidates) ) {
|
||||
/* only complain for non-range IDLs */
|
||||
|
|
|
|||
|
|
@ -133,21 +133,24 @@ int bdb_tool_next_id(
|
|||
DB_TXN *tid,
|
||||
Entry *e,
|
||||
struct berval *text,
|
||||
int hole )
|
||||
int hole,
|
||||
u_int32_t locker )
|
||||
{
|
||||
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
|
||||
struct berval dn = e->e_nname;
|
||||
struct berval pdn;
|
||||
EntryInfo *ei = NULL;
|
||||
int rc;
|
||||
|
||||
rc = bdb_dn2id( be, tid, &dn, &e->e_id, 0 );
|
||||
rc = bdb_cache_find_entry_ndn2id( be, tid, &dn, &ei, locker, NULL );
|
||||
if ( ei ) bdb_cache_entryinfo_unlock( ei );
|
||||
if ( rc == DB_NOTFOUND ) {
|
||||
if ( be_issuffix( be, &dn ) ) {
|
||||
pdn = slap_empty_bv;
|
||||
} else {
|
||||
dnParent( &dn, &pdn );
|
||||
e->e_nname = pdn;
|
||||
rc = bdb_tool_next_id( be, tid, e, text, 1 );
|
||||
rc = bdb_tool_next_id( be, tid, e, text, 1, locker );
|
||||
if ( rc ) {
|
||||
return rc;
|
||||
}
|
||||
|
|
@ -221,6 +224,7 @@ ID bdb_tool_entry_put(
|
|||
DB_TXN *tid = NULL;
|
||||
struct berval pdn;
|
||||
Operation op = {0};
|
||||
u_int32_t locker;
|
||||
|
||||
assert( be != NULL );
|
||||
assert( slapMode & SLAP_TOOL_MODE );
|
||||
|
|
@ -253,8 +257,9 @@ ID bdb_tool_entry_put(
|
|||
return NOID;
|
||||
}
|
||||
|
||||
locker = TXN_ID( tid );
|
||||
/* add dn2id indices */
|
||||
rc = bdb_tool_next_id( be, tid, e, text, 0 );
|
||||
rc = bdb_tool_next_id( be, tid, e, text, 0, locker );
|
||||
if( rc != 0 ) {
|
||||
goto done;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue