mirror of
https://git.openldap.org/openldap/openldap.git
synced 2026-06-09 08:42:22 -04:00
More porting
This commit is contained in:
parent
c8e723e831
commit
e7768b12ab
12 changed files with 299 additions and 491 deletions
|
|
@ -132,8 +132,6 @@ txnReturn:
|
|||
|
||||
opinfo.moi_oe.oe_key = mdb;
|
||||
opinfo.moi_txn = txn;
|
||||
opinfo.moi_err = 0;
|
||||
opinfo.moi_acl_cache = op->o_do_not_cache;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -101,8 +101,6 @@ struct mdb_info {
|
|||
struct mdb_op_info {
|
||||
OpExtra moi_oe;
|
||||
MDB_txn* moi_txn;
|
||||
u_int32_t moi_err;
|
||||
char moi_acl_cache;
|
||||
char moi_flag;
|
||||
};
|
||||
#define MOI_DONTFREE 1
|
||||
|
|
|
|||
|
|
@ -113,8 +113,6 @@ txnReturn:
|
|||
|
||||
opinfo.moi_oe.oe_key = mdb;
|
||||
opinfo.moi_txn = txn;
|
||||
opinfo.moi_err = 0;
|
||||
opinfo.moi_acl_cache = op->o_do_not_cache;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
|
||||
|
||||
if ( !be_issuffix( op->o_bd, &op->o_req_ndn ) ) {
|
||||
|
|
|
|||
|
|
@ -538,6 +538,7 @@ int
|
|||
mdb_id2name(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
MDB_cursor **cursp,
|
||||
ID id,
|
||||
struct berval *name,
|
||||
struct berval *nname )
|
||||
|
|
@ -553,8 +554,11 @@ mdb_id2name(
|
|||
|
||||
key.mv_size = sizeof(ID);
|
||||
|
||||
rc = mdb_cursor_open( txn, dbi, &cursor );
|
||||
if ( rc ) return rc;
|
||||
if ( !*cursp ) {
|
||||
rc = mdb_cursor_open( txn, dbi, cursp );
|
||||
if ( rc ) return rc;
|
||||
}
|
||||
cursor = *cursp;
|
||||
|
||||
len = 0;
|
||||
nlen = 0;
|
||||
|
|
@ -597,6 +601,126 @@ mdb_id2name(
|
|||
return rc;
|
||||
}
|
||||
|
||||
/* Find each id in ids that is a child of base and move it to res.
|
||||
*/
|
||||
int
|
||||
mdb_idscope(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
ID base,
|
||||
ID *ids,
|
||||
ID *res )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
MDB_dbi dbi = mdb->mi_dn2id;
|
||||
MDB_val key, data;
|
||||
MDB_cursor *cursor;
|
||||
ID ida, id, cid, ci0, idc = 0;
|
||||
char *ptr;
|
||||
int rc;
|
||||
|
||||
key.mv_size = sizeof(ID);
|
||||
|
||||
MDB_IDL_ZERO( res );
|
||||
|
||||
rc = mdb_cursor_open( txn, dbi, &cursor );
|
||||
if ( rc ) return rc;
|
||||
|
||||
ida = mdb_idl_first( ids, &cid );
|
||||
|
||||
/* Don't bother moving out of ids if it's a range */
|
||||
if (!MDB_IDL_IS_RANGE(ids)) {
|
||||
idc = ids[0];
|
||||
ci0 = cid;
|
||||
}
|
||||
|
||||
while (ida != NOID) {
|
||||
id = ida;
|
||||
while (id) {
|
||||
key.mv_data = &id;
|
||||
rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
|
||||
if ( rc ) {
|
||||
/* not found, move on to next */
|
||||
if (idc) {
|
||||
if (ci0 != cid)
|
||||
ids[ci0] = ids[cid];
|
||||
ci0++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
ptr = data.mv_data;
|
||||
ptr += data.mv_size - sizeof(ID);
|
||||
memcpy( &id, ptr, sizeof(ID) );
|
||||
if ( id == base ) {
|
||||
res[0]++;
|
||||
res[res[0]] = ida;
|
||||
if (idc)
|
||||
idc--;
|
||||
break;
|
||||
} else {
|
||||
if (idc) {
|
||||
if (ci0 != cid)
|
||||
ids[ci0] = ids[cid];
|
||||
ci0++;
|
||||
}
|
||||
}
|
||||
if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
|
||||
break;
|
||||
}
|
||||
ida = mdb_idl_next( ids, &cid );
|
||||
}
|
||||
if (!MDB_IDL_IS_RANGE( ids ))
|
||||
ids[0] = idc;
|
||||
|
||||
mdb_cursor_close( cursor );
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* See if base is a child of any of the scopes
|
||||
*/
|
||||
int
|
||||
mdb_idscopes(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
MDB_cursor **cursp,
|
||||
ID base,
|
||||
ID *scopes )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
MDB_dbi dbi = mdb->mi_dn2id;
|
||||
MDB_val key, data;
|
||||
MDB_cursor *cursor;
|
||||
ID id;
|
||||
char *ptr;
|
||||
int rc;
|
||||
unsigned int x;
|
||||
|
||||
key.mv_size = sizeof(ID);
|
||||
|
||||
if ( !*cursp ) {
|
||||
rc = mdb_cursor_open( txn, dbi, cursp );
|
||||
if ( rc ) return rc;
|
||||
}
|
||||
cursor = *cursp;
|
||||
|
||||
id = base;
|
||||
while (id) {
|
||||
key.mv_data = &id;
|
||||
rc = mdb_cursor_get( cursor, &key, &data, MDB_SET );
|
||||
if ( rc )
|
||||
break;
|
||||
ptr = data.mv_data;
|
||||
ptr += data.mv_size - sizeof(ID);
|
||||
memcpy( &id, ptr, sizeof(ID) );
|
||||
x = mdb_idl_search( scopes, id );
|
||||
if ( scopes[x] == id )
|
||||
return MDB_SUCCESS;
|
||||
if ( op->ors_scope == LDAP_SCOPE_ONELEVEL )
|
||||
break;
|
||||
}
|
||||
return MDB_NOTFOUND;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* mdb_dn2idl:
|
||||
* We can't just use mdb_idl_fetch_key because
|
||||
|
|
|
|||
|
|
@ -220,12 +220,10 @@ int mdb_entry_get(
|
|||
int rw,
|
||||
Entry **ent )
|
||||
{
|
||||
#if 0
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
struct mdb_op_info *boi = NULL;
|
||||
struct mdb_op_info *moi = NULL;
|
||||
MDB_txn *txn = NULL;
|
||||
Entry *e = NULL;
|
||||
EntryInfo *ei;
|
||||
int rc;
|
||||
const char *at_name = at ? at->ad_cname.bv_val : "(null)";
|
||||
|
||||
|
|
@ -240,13 +238,13 @@ int mdb_entry_get(
|
|||
LDAP_SLIST_FOREACH( oex, &op->o_extra, oe_next ) {
|
||||
if ( oex->oe_key == mdb ) break;
|
||||
}
|
||||
boi = (struct mdb_op_info *)oex;
|
||||
if ( boi )
|
||||
txn = boi->boi_txn;
|
||||
moi = (struct mdb_op_info *)oex;
|
||||
if ( moi )
|
||||
txn = moi->moi_txn;
|
||||
}
|
||||
|
||||
if ( !txn ) {
|
||||
rc = mdb_reader_get( op, mdb->bi_dbenv, &txn );
|
||||
rc = mdb_reader_get( op, mdb->mi_dbenv, &txn );
|
||||
switch(rc) {
|
||||
case 0:
|
||||
break;
|
||||
|
|
@ -255,18 +253,15 @@ int mdb_entry_get(
|
|||
}
|
||||
}
|
||||
|
||||
dn2entry_retry:
|
||||
/* can we find entry */
|
||||
rc = mdb_dn2entry( op, txn, ndn, &ei, 0, &lock );
|
||||
rc = mdb_dn2entry( op, txn, ndn, &e, 0 );
|
||||
switch( rc ) {
|
||||
case MDB_NOTFOUND:
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
if ( boi ) boi->boi_err = rc;
|
||||
return (rc != LDAP_BUSY) ? LDAP_OTHER : LDAP_BUSY;
|
||||
}
|
||||
if (ei) e = ei->bei_e;
|
||||
if (e == NULL) {
|
||||
Debug( LDAP_DEBUG_ACL,
|
||||
"=> mdb_entry_get: cannot find entry: \"%s\"\n",
|
||||
|
|
@ -298,41 +293,14 @@ dn2entry_retry:
|
|||
return_results:
|
||||
if( rc != LDAP_SUCCESS ) {
|
||||
/* free entry */
|
||||
mdb_cache_return_entry_rw(mdb, e, rw, &lock);
|
||||
mdb_entry_return( e );
|
||||
|
||||
} else {
|
||||
if ( slapMode == SLAP_SERVER_MODE ) {
|
||||
*ent = e;
|
||||
/* big drag. we need a place to store a read lock so we can
|
||||
* release it later?? If we're in a txn, nothing is needed
|
||||
* here because the locks will go away with the txn.
|
||||
*/
|
||||
if ( op ) {
|
||||
if ( !boi ) {
|
||||
boi = op->o_tmpcalloc(1,sizeof(struct mdb_op_info),op->o_tmpmemctx);
|
||||
boi->boi_oe.oe_key = mdb;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &boi->boi_oe, oe_next );
|
||||
}
|
||||
if ( !boi->boi_txn ) {
|
||||
struct mdb_lock_info *bli;
|
||||
bli = op->o_tmpalloc( sizeof(struct mdb_lock_info),
|
||||
op->o_tmpmemctx );
|
||||
bli->bli_next = boi->boi_locks;
|
||||
bli->bli_id = e->e_id;
|
||||
bli->bli_flag = 0;
|
||||
bli->bli_lock = lock;
|
||||
boi->boi_locks = bli;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
*ent = entry_dup( e );
|
||||
mdb_cache_return_entry_rw(mdb, e, rw, &lock);
|
||||
}
|
||||
*ent = entry_dup( e );
|
||||
}
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE,
|
||||
"mdb_entry_get: rc=%d\n",
|
||||
rc, 0, 0 );
|
||||
return(rc);
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -896,8 +896,6 @@ ID mdb_idl_next( ID *ids, ID *cursor )
|
|||
return NOID;
|
||||
}
|
||||
|
||||
#ifdef MDB_HIER
|
||||
|
||||
/* Add one ID to an unsorted list. We ensure that the first element is the
|
||||
* minimum and the last element is the maximum, for fast range compaction.
|
||||
* this means IDLs up to length 3 are always sorted...
|
||||
|
|
@ -1166,5 +1164,3 @@ mdb_idl_sort( ID *ids, ID *tmp )
|
|||
}
|
||||
}
|
||||
#endif /* Quick vs Radix */
|
||||
|
||||
#endif /* MDB_HIER */
|
||||
|
|
|
|||
|
|
@ -384,7 +384,6 @@ mdb_back_initialize(
|
|||
bi->bi_db_close = mdb_db_close;
|
||||
bi->bi_db_destroy = mdb_db_destroy;
|
||||
|
||||
#if 0
|
||||
bi->bi_op_add = mdb_add;
|
||||
bi->bi_op_bind = mdb_bind;
|
||||
bi->bi_op_compare = mdb_compare;
|
||||
|
|
@ -401,7 +400,6 @@ mdb_back_initialize(
|
|||
bi->bi_operational = mdb_operational;
|
||||
|
||||
bi->bi_has_subordinates = mdb_hasSubordinates;
|
||||
#endif
|
||||
bi->bi_entry_release_rw = mdb_entry_release;
|
||||
bi->bi_entry_get_rw = mdb_entry_get;
|
||||
|
||||
|
|
@ -415,11 +413,9 @@ mdb_back_initialize(
|
|||
bi->bi_tool_entry_next = mdb_tool_entry_next;
|
||||
bi->bi_tool_entry_get = mdb_tool_entry_get;
|
||||
bi->bi_tool_entry_put = mdb_tool_entry_put;
|
||||
#if 0
|
||||
bi->bi_tool_entry_reindex = mdb_tool_entry_reindex;
|
||||
bi->bi_tool_sync = 0;
|
||||
bi->bi_tool_dn2id_get = mdb_tool_dn2id_get;
|
||||
#endif
|
||||
bi->bi_tool_entry_modify = mdb_tool_entry_modify;
|
||||
|
||||
bi->bi_connection_init = 0;
|
||||
|
|
|
|||
|
|
@ -479,8 +479,6 @@ txnReturn:
|
|||
|
||||
opinfo.moi_oe.oe_key = mdb;
|
||||
opinfo.moi_txn = txn;
|
||||
opinfo.moi_err = 0;
|
||||
opinfo.moi_acl_cache = op->o_do_not_cache;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
|
||||
|
||||
/* get entry or ancestor */
|
||||
|
|
@ -578,9 +576,6 @@ txnReturn:
|
|||
Debug( LDAP_DEBUG_TRACE,
|
||||
LDAP_XSTRING(mdb_modify) ": modify failed (%d)\n",
|
||||
rs->sr_err, 0, 0 );
|
||||
if ( (rs->sr_err == LDAP_INSUFFICIENT_ACCESS) && opinfo.moi_err ) {
|
||||
rs->sr_err = opinfo.moi_err;
|
||||
}
|
||||
/* Only free attrs if they were dup'd. */
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
goto return_results;
|
||||
|
|
|
|||
|
|
@ -118,8 +118,6 @@ txnReturn:
|
|||
|
||||
opinfo.moi_oe.oe_key = mdb;
|
||||
opinfo.moi_txn = txn;
|
||||
opinfo.moi_err = 0;
|
||||
opinfo.moi_acl_cache = op->o_do_not_cache;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &opinfo.moi_oe, oe_next );
|
||||
|
||||
if ( be_issuffix( op->o_bd, &e->e_nname ) ) {
|
||||
|
|
@ -496,9 +494,6 @@ txnReturn:
|
|||
"<=- " LDAP_XSTRING(mdb_modrdn)
|
||||
": modify failed: %s (%d)\n",
|
||||
mdb_strerror(rs->sr_err), rs->sr_err, 0 );
|
||||
if ( ( rs->sr_err == LDAP_INSUFFICIENT_ACCESS ) && opinfo.moi_err ) {
|
||||
rs->sr_err = opinfo.moi_err;
|
||||
}
|
||||
if ( dummy.e_attrs == e->e_attrs ) dummy.e_attrs = NULL;
|
||||
goto return_results;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -111,10 +111,25 @@ int mdb_dn2id_parent(
|
|||
int mdb_id2name(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
MDB_cursor **cursp,
|
||||
ID eid,
|
||||
struct berval *name,
|
||||
struct berval *nname);
|
||||
|
||||
int mdb_idscope(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
ID base,
|
||||
ID *ids,
|
||||
ID *res );
|
||||
|
||||
int mdb_idscopes(
|
||||
Operation *op,
|
||||
MDB_txn *txn,
|
||||
MDB_cursor **cursp,
|
||||
ID base,
|
||||
ID *scopes );
|
||||
|
||||
MDB_cmp_func mdb_dup_compare;
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ static int search_candidates(
|
|||
Operation *op,
|
||||
SlapReply *rs,
|
||||
Entry *e,
|
||||
DB_TXN *txn,
|
||||
MDB_txn *txn,
|
||||
ID *ids,
|
||||
ID *scopes );
|
||||
|
||||
|
|
@ -51,15 +51,11 @@ static Entry * deref_base (
|
|||
SlapReply *rs,
|
||||
Entry *e,
|
||||
Entry **matched,
|
||||
DB_TXN *txn,
|
||||
DB_LOCK *lock,
|
||||
MDB_txn *txn,
|
||||
ID *tmp,
|
||||
ID *visited )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_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";
|
||||
|
|
@ -101,18 +97,8 @@ static Entry * deref_base (
|
|||
break;
|
||||
}
|
||||
|
||||
rs->sr_err = mdb_dn2entry( op, txn, &ndn, &ei,
|
||||
0, &lockr );
|
||||
if ( rs->sr_err == DB_LOCK_DEADLOCK )
|
||||
return NULL;
|
||||
|
||||
if ( ei ) {
|
||||
e = ei->bei_e;
|
||||
} else {
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
if (!e) {
|
||||
rs->sr_err = mdb_dn2entry( op, txn, &ndn, &e, 0 );
|
||||
if (rs->sr_err) {
|
||||
rs->sr_err = LDAP_ALIAS_PROBLEM;
|
||||
rs->sr_text = "aliasedObject not found";
|
||||
break;
|
||||
|
|
@ -121,11 +107,9 @@ static Entry * deref_base (
|
|||
/* Free the previous entry, continue to work with the
|
||||
* one we just retrieved.
|
||||
*/
|
||||
mdb_cache_return_entry_r( mdb, *matched, lock);
|
||||
*lock = lockr;
|
||||
mdb_entry_return( *matched );
|
||||
|
||||
/* We found a regular entry. Return this to the caller. The
|
||||
* entry is still locked for Read.
|
||||
/* We found a regular entry. Return this to the caller.
|
||||
*/
|
||||
if (!is_entry_alias(e)) {
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
|
|
@ -136,44 +120,34 @@ static Entry * deref_base (
|
|||
return e;
|
||||
}
|
||||
|
||||
/* Look for and dereference all aliases within the search scope. Adds
|
||||
* the dereferenced entries to the "ids" list. Requires "stack" to be
|
||||
* able to hold 8 levels of DB_SIZE IDLs. Of course we're hardcoded to
|
||||
* require a minimum of 8 UM_SIZE IDLs so this is never a problem.
|
||||
/* Look for and dereference all aliases within the search scope.
|
||||
* Requires "stack" to be able to hold 6 levels of DB_SIZE IDLs.
|
||||
* Of course we're hardcoded to require a minimum of 8 UM_SIZE
|
||||
* IDLs so this is never a problem.
|
||||
*/
|
||||
static int search_aliases(
|
||||
Operation *op,
|
||||
SlapReply *rs,
|
||||
Entry *e,
|
||||
DB_TXN *txn,
|
||||
ID *ids,
|
||||
MDB_txn *txn,
|
||||
ID *scopes,
|
||||
ID *stack )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
ID *aliases, *curscop, *subscop, *visited, *newsubs, *oldsubs, *tmp;
|
||||
ID cursora, ida, cursoro, ido, *subscop2;
|
||||
ID *aliases, *curscop, *visited, *newsubs, *oldsubs, *tmp;
|
||||
ID cursora, ida, cursoro, ido;
|
||||
Entry *matched, *a;
|
||||
EntryInfo *ei;
|
||||
struct berval bv_alias = BER_BVC( "alias" );
|
||||
AttributeAssertion aa_alias = ATTRIBUTEASSERTION_INIT;
|
||||
Filter af;
|
||||
DB_LOCK locka, lockr;
|
||||
int first = 1;
|
||||
|
||||
aliases = stack; /* IDL of all aliases in the database */
|
||||
curscop = aliases + MDB_IDL_DB_SIZE; /* Aliases in the current scope */
|
||||
subscop = curscop + MDB_IDL_DB_SIZE; /* The current scope */
|
||||
visited = subscop + MDB_IDL_DB_SIZE; /* IDs we've seen in this search */
|
||||
visited = curscop + MDB_IDL_DB_SIZE; /* IDs we've seen in this search */
|
||||
newsubs = visited + MDB_IDL_DB_SIZE; /* New subtrees we've added */
|
||||
oldsubs = newsubs + MDB_IDL_DB_SIZE; /* Subtrees added previously */
|
||||
tmp = oldsubs + MDB_IDL_DB_SIZE; /* Scratch space for deref_base() */
|
||||
|
||||
/* A copy of subscop, because subscop gets clobbered by
|
||||
* the mdb_idl_union/intersection routines
|
||||
*/
|
||||
subscop2 = tmp + MDB_IDL_DB_SIZE;
|
||||
|
||||
af.f_choice = LDAP_FILTER_EQUALITY;
|
||||
af.f_ava = &aa_alias;
|
||||
af.f_av_desc = slap_schema.si_ad_objectClass;
|
||||
|
|
@ -190,7 +164,6 @@ static int search_aliases(
|
|||
oldsubs[0] = 1;
|
||||
oldsubs[1] = e->e_id;
|
||||
|
||||
MDB_IDL_ZERO( ids );
|
||||
MDB_IDL_ZERO( visited );
|
||||
MDB_IDL_ZERO( newsubs );
|
||||
|
||||
|
|
@ -199,75 +172,52 @@ static int search_aliases(
|
|||
|
||||
for (;;) {
|
||||
/* Set curscop to only the aliases in the current scope. Start with
|
||||
* all the aliases, obtain the IDL for the current scope, and then
|
||||
* get the intersection of these two IDLs. Add the current scope
|
||||
* to the cumulative list of candidates.
|
||||
* all the aliases, then get the intersection with the scope.
|
||||
*/
|
||||
MDB_IDL_CPY( curscop, aliases );
|
||||
rs->sr_err = mdb_dn2idl( op, txn, &e->e_nname, BEI(e), subscop,
|
||||
subscop2+MDB_IDL_DB_SIZE );
|
||||
rs->sr_err = mdb_idscope( op, txn, e->e_id, aliases, curscop );
|
||||
|
||||
if (first) {
|
||||
first = 0;
|
||||
} else {
|
||||
mdb_cache_return_entry_r (mdb, e, &locka);
|
||||
mdb_entry_return( e );
|
||||
}
|
||||
if ( rs->sr_err == DB_LOCK_DEADLOCK )
|
||||
return rs->sr_err;
|
||||
|
||||
MDB_IDL_CPY(subscop2, subscop);
|
||||
rs->sr_err = mdb_idl_intersection(curscop, subscop);
|
||||
mdb_idl_union( ids, subscop2 );
|
||||
|
||||
/* Dereference all of the aliases in the current scope. */
|
||||
cursora = 0;
|
||||
for (ida = mdb_idl_first(curscop, &cursora); ida != NOID;
|
||||
ida = mdb_idl_next(curscop, &cursora))
|
||||
{
|
||||
ei = NULL;
|
||||
retry1:
|
||||
rs->sr_err = mdb_cache_find_id(op, txn,
|
||||
ida, &ei, 0, &lockr );
|
||||
rs->sr_err = mdb_id2entry(op, txn, ida, &a);
|
||||
if (rs->sr_err != LDAP_SUCCESS) {
|
||||
if ( rs->sr_err == DB_LOCK_DEADLOCK )
|
||||
return rs->sr_err;
|
||||
if ( rs->sr_err == DB_LOCK_NOTGRANTED )
|
||||
goto retry1;
|
||||
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
|
||||
*/
|
||||
if (!is_entry_alias(a)) {
|
||||
mdb_cache_return_entry_r (mdb, a, &lockr);
|
||||
mdb_entry_return (a);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Actually dereference the alias */
|
||||
MDB_IDL_ZERO(tmp);
|
||||
a = deref_base( op, rs, a, &matched, txn, &lockr,
|
||||
a = deref_base( op, rs, a, &matched, txn,
|
||||
tmp, visited );
|
||||
if (a) {
|
||||
/* If the target was not already in our current candidates,
|
||||
* make note of it in the newsubs list. Also
|
||||
* set it in the scopes list so that mdb_search
|
||||
* can check it.
|
||||
/* If the target was not already in our current scopes,
|
||||
* make note of it in the newsubs list.
|
||||
*/
|
||||
if (mdb_idl_insert(ids, a->e_id) == 0) {
|
||||
if (mdb_idl_insert(scopes, a->e_id) == 0) {
|
||||
mdb_idl_insert(newsubs, a->e_id);
|
||||
mdb_idl_insert(scopes, a->e_id);
|
||||
}
|
||||
mdb_cache_return_entry_r( mdb, a, &lockr);
|
||||
mdb_entry_return( a );
|
||||
|
||||
} else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
|
||||
return rs->sr_err;
|
||||
} else if (matched) {
|
||||
/* Alias could not be dereferenced, or it deref'd to
|
||||
* an ID we've already seen. Ignore it.
|
||||
*/
|
||||
mdb_cache_return_entry_r( mdb, matched, &lockr );
|
||||
mdb_entry_return( matched );
|
||||
rs->sr_text = NULL;
|
||||
}
|
||||
}
|
||||
|
|
@ -292,20 +242,11 @@ nextido:
|
|||
/* Find the entry corresponding to the next scope. If it can't
|
||||
* be found, ignore it and move on. This should never happen;
|
||||
* 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.
|
||||
*/
|
||||
ei = NULL;
|
||||
sameido:
|
||||
rs->sr_err = mdb_cache_find_id(op, txn, ido, &ei,
|
||||
0, &locka );
|
||||
rs->sr_err = mdb_id2entry(op, txn, ido, &e);
|
||||
if ( rs->sr_err != LDAP_SUCCESS ) {
|
||||
if ( rs->sr_err == DB_LOCK_DEADLOCK )
|
||||
return rs->sr_err;
|
||||
if ( rs->sr_err == DB_LOCK_NOTGRANTED )
|
||||
goto sameido;
|
||||
goto nextido;
|
||||
}
|
||||
e = ei->bei_e;
|
||||
}
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
|
@ -314,29 +255,24 @@ sameido:
|
|||
* a range and simple iteration hits missing entryIDs
|
||||
*/
|
||||
static int
|
||||
mdb_get_nextid(struct mdb_info *mdb, DB_TXN *ltid, ID *cursor)
|
||||
mdb_get_nextid(struct mdb_info *mdb, MDB_txn *txn, ID *cursor)
|
||||
{
|
||||
DBC *curs;
|
||||
DBT key, data;
|
||||
ID id, nid;
|
||||
MDB_cursor *curs;
|
||||
MDB_val key;
|
||||
ID id;
|
||||
int rc;
|
||||
|
||||
id = *cursor + 1;
|
||||
MDB_ID2DISK( id, &nid );
|
||||
rc = mdb->bi_id2entry->bdi_db->cursor(
|
||||
mdb->bi_id2entry->bdi_db, ltid, &curs, mdb->bi_db_opflags );
|
||||
rc = mdb_cursor_open( txn, mdb->mi_id2entry, &curs );
|
||||
if ( rc )
|
||||
return rc;
|
||||
key.data = &nid;
|
||||
key.size = key.ulen = sizeof(ID);
|
||||
key.flags = DB_DBT_USERMEM;
|
||||
data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
|
||||
data.dlen = data.ulen = 0;
|
||||
rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
|
||||
curs->c_close( curs );
|
||||
key.mv_data = &id;
|
||||
key.mv_size = sizeof(ID);
|
||||
rc = mdb_cursor_get( curs, &key, NULL, MDB_SET_RANGE );
|
||||
mdb_cursor_close( curs );
|
||||
if ( rc )
|
||||
return rc;
|
||||
MDB_DISK2ID( &nid, cursor );
|
||||
memcpy( cursor, key.mv_data, sizeof(ID));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -348,21 +284,18 @@ mdb_search( Operation *op, SlapReply *rs )
|
|||
ID lastid = NOID;
|
||||
ID candidates[MDB_IDL_UM_SIZE];
|
||||
ID scopes[MDB_IDL_DB_SIZE];
|
||||
Entry *e = NULL, base, *e_root;
|
||||
Entry *e = NULL, base;
|
||||
Entry *matched = NULL;
|
||||
EntryInfo *ei;
|
||||
AttributeName *attrs;
|
||||
struct berval realbase = BER_BVNULL;
|
||||
slap_mask_t mask;
|
||||
time_t stoptime;
|
||||
int manageDSAit;
|
||||
int tentries = 0;
|
||||
unsigned nentries = 0;
|
||||
int idflag = 0;
|
||||
|
||||
DB_LOCK lock;
|
||||
struct mdb_op_info *opinfo = NULL;
|
||||
DB_TXN *ltid = NULL;
|
||||
MDB_txn *ltid = NULL;
|
||||
MDB_cursor *idcursor = NULL;
|
||||
OpExtra *oex;
|
||||
|
||||
Debug( LDAP_DEBUG_TRACE, "=> " LDAP_XSTRING(mdb_search) "\n", 0, 0, 0);
|
||||
|
|
@ -376,10 +309,10 @@ mdb_search( Operation *op, SlapReply *rs )
|
|||
|
||||
manageDSAit = get_manageDSAit( op );
|
||||
|
||||
if ( opinfo && opinfo->boi_txn ) {
|
||||
ltid = opinfo->boi_txn;
|
||||
if ( opinfo && opinfo->moi_txn ) {
|
||||
ltid = opinfo->moi_txn;
|
||||
} else {
|
||||
rs->sr_err = mdb_reader_get( op, mdb->bi_dbenv, <id );
|
||||
rs->sr_err = mdb_reader_get( op, mdb->mi_dbenv, <id );
|
||||
|
||||
switch(rs->sr_err) {
|
||||
case 0:
|
||||
|
|
@ -390,40 +323,22 @@ mdb_search( Operation *op, SlapReply *rs )
|
|||
}
|
||||
}
|
||||
|
||||
e_root = mdb->bi_cache.c_dntree.bei_e;
|
||||
if ( op->o_req_ndn.bv_len == 0 ) {
|
||||
/* DIT root special case */
|
||||
ei = e_root->e_private;
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
} else {
|
||||
if ( op->ors_deref & LDAP_DEREF_FINDING ) {
|
||||
MDB_IDL_ZERO(candidates);
|
||||
}
|
||||
dn2entry_retry:
|
||||
/* get entry with reader lock */
|
||||
rs->sr_err = mdb_dn2entry( op, ltid, &op->o_req_ndn, &ei,
|
||||
1, &lock );
|
||||
if ( op->ors_deref & LDAP_DEREF_FINDING ) {
|
||||
MDB_IDL_ZERO(candidates);
|
||||
}
|
||||
dn2entry_retry:
|
||||
/* get entry with reader lock */
|
||||
rs->sr_err = mdb_dn2entry( op, ltid, &op->o_req_ndn, &e, 1 );
|
||||
|
||||
switch(rs->sr_err) {
|
||||
case DB_NOTFOUND:
|
||||
matched = ei->bei_e;
|
||||
case MDB_NOTFOUND:
|
||||
matched = e;
|
||||
break;
|
||||
case 0:
|
||||
e = ei->bei_e;
|
||||
break;
|
||||
case DB_LOCK_DEADLOCK:
|
||||
if ( !opinfo ) {
|
||||
ltid->flags &= ~TXN_DEADLOCK;
|
||||
goto dn2entry_retry;
|
||||
}
|
||||
opinfo->boi_err = rs->sr_err;
|
||||
/* FALLTHRU */
|
||||
case LDAP_BUSY:
|
||||
send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
|
||||
return LDAP_BUSY;
|
||||
case DB_LOCK_NOTGRANTED:
|
||||
goto dn2entry_retry;
|
||||
default:
|
||||
send_ldap_error( op, rs, LDAP_OTHER, "internal error" );
|
||||
return rs->sr_err;
|
||||
|
|
@ -435,17 +350,17 @@ dn2entry_retry:
|
|||
|
||||
stub.bv_val = op->o_req_ndn.bv_val;
|
||||
stub.bv_len = op->o_req_ndn.bv_len - matched->e_nname.bv_len - 1;
|
||||
e = deref_base( op, rs, matched, &matched, ltid, &lock,
|
||||
e = deref_base( op, rs, matched, &matched, ltid,
|
||||
candidates, NULL );
|
||||
if ( e ) {
|
||||
build_new_dn( &op->o_req_ndn, &e->e_nname, &stub,
|
||||
op->o_tmpmemctx );
|
||||
mdb_cache_return_entry_r (mdb, e, &lock);
|
||||
mdb_entry_return (e);
|
||||
matched = NULL;
|
||||
goto dn2entry_retry;
|
||||
}
|
||||
} else if ( e && is_entry_alias( e )) {
|
||||
e = deref_base( op, rs, e, &matched, ltid, &lock,
|
||||
e = deref_base( op, rs, e, &matched, ltid,
|
||||
candidates, NULL );
|
||||
}
|
||||
}
|
||||
|
|
@ -470,15 +385,12 @@ dn2entry_retry:
|
|||
erefs = is_entry_referral( matched )
|
||||
? get_entry_referrals( op, matched )
|
||||
: NULL;
|
||||
if ( rs->sr_err == DB_NOTFOUND )
|
||||
if ( rs->sr_err == MDB_NOTFOUND )
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
rs->sr_matched = matched_dn.bv_val;
|
||||
}
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, matched);
|
||||
#endif
|
||||
mdb_cache_return_entry_r (mdb, matched, &lock);
|
||||
mdb_entry_return (matched);
|
||||
matched = NULL;
|
||||
|
||||
if ( erefs ) {
|
||||
|
|
@ -488,9 +400,6 @@ dn2entry_retry:
|
|||
}
|
||||
|
||||
} else {
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, matched);
|
||||
#endif
|
||||
rs->sr_ref = referral_rewrite( default_referral,
|
||||
NULL, &op->o_req_dn, op->oq_search.rs_scope );
|
||||
rs->sr_err = rs->sr_ref != NULL ? LDAP_REFERRAL : LDAP_NO_SUCH_OBJECT;
|
||||
|
|
@ -520,18 +429,13 @@ dn2entry_retry:
|
|||
rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
|
||||
}
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
if ( e != e_root ) {
|
||||
mdb_cache_return_entry_r(mdb, e, &lock);
|
||||
}
|
||||
mdb_entry_return(e);
|
||||
send_ldap_result( op, rs );
|
||||
return rs->sr_err;
|
||||
}
|
||||
|
||||
if ( !manageDSAit && e != e_root && is_entry_referral( e ) ) {
|
||||
/* entry is a referral, don't allow add */
|
||||
if ( !manageDSAit && is_entry_referral( e ) ) {
|
||||
/* entry is a referral */
|
||||
struct berval matched_dn = BER_BVNULL;
|
||||
BerVarray erefs = NULL;
|
||||
|
||||
|
|
@ -540,10 +444,7 @@ dn2entry_retry:
|
|||
|
||||
rs->sr_err = LDAP_REFERRAL;
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
mdb_cache_return_entry_r( mdb, e, &lock );
|
||||
mdb_entry_return( e );
|
||||
e = NULL;
|
||||
|
||||
if ( erefs ) {
|
||||
|
|
@ -574,12 +475,7 @@ dn2entry_retry:
|
|||
( test_filter( op, e, get_assertion( op )) != LDAP_COMPARE_TRUE ))
|
||||
{
|
||||
rs->sr_err = LDAP_ASSERTION_FAILED;
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
if ( e != e_root ) {
|
||||
mdb_cache_return_entry_r(mdb, e, &lock);
|
||||
}
|
||||
mdb_entry_return(e);
|
||||
send_ldap_result( op, rs );
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -597,12 +493,7 @@ dn2entry_retry:
|
|||
base.e_nname = realbase;
|
||||
base.e_id = e->e_id;
|
||||
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
if ( e != e_root ) {
|
||||
mdb_cache_return_entry_r(mdb, e, &lock);
|
||||
}
|
||||
mdb_entry_return(e);
|
||||
e = NULL;
|
||||
|
||||
/* select candidates */
|
||||
|
|
@ -610,20 +501,11 @@ dn2entry_retry:
|
|||
rs->sr_err = base_candidate( op->o_bd, &base, candidates );
|
||||
|
||||
} else {
|
||||
cand_retry:
|
||||
MDB_IDL_ZERO( candidates );
|
||||
MDB_IDL_ZERO( scopes );
|
||||
mdb_idl_insert( scopes, base.e_id );
|
||||
rs->sr_err = search_candidates( op, rs, &base,
|
||||
ltid, candidates, scopes );
|
||||
if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
|
||||
if ( !opinfo ) {
|
||||
ltid->flags &= ~TXN_DEADLOCK;
|
||||
goto cand_retry;
|
||||
}
|
||||
opinfo->boi_err = rs->sr_err;
|
||||
send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
|
||||
return LDAP_BUSY;
|
||||
}
|
||||
}
|
||||
|
||||
/* start cursor at beginning of candidates.
|
||||
|
|
@ -682,7 +564,6 @@ cand_retry:
|
|||
rs->sr_err = LDAP_OTHER;
|
||||
goto done;
|
||||
}
|
||||
nentries = ps->ps_count;
|
||||
if ( id == (ID)ps->ps_cookie )
|
||||
id = mdb_idl_next( candidates, &cursor );
|
||||
goto loop_begin;
|
||||
|
|
@ -722,51 +603,20 @@ loop_begin:
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* If we inspect more entries than will
|
||||
* fit into the entry cache, stop caching
|
||||
* any subsequent entries
|
||||
*/
|
||||
nentries++;
|
||||
if ( nentries > mdb->bi_cache.c_maxsize && !idflag ) {
|
||||
idflag = ID_NOCACHE;
|
||||
}
|
||||
|
||||
fetch_entry_retry:
|
||||
/* get the entry with reader lock */
|
||||
ei = NULL;
|
||||
rs->sr_err = mdb_cache_find_id( op, ltid,
|
||||
id, &ei, idflag, &lock );
|
||||
/* get the entry */
|
||||
rs->sr_err = mdb_id2entry( op, ltid, id, &e );
|
||||
|
||||
if (rs->sr_err == LDAP_BUSY) {
|
||||
rs->sr_text = "ldap server busy";
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
|
||||
} else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
|
||||
if ( !opinfo ) {
|
||||
ltid->flags &= ~TXN_DEADLOCK;
|
||||
goto fetch_entry_retry;
|
||||
}
|
||||
txnfail:
|
||||
opinfo->boi_err = rs->sr_err;
|
||||
send_ldap_error( op, rs, LDAP_BUSY, "ldap server busy" );
|
||||
goto done;
|
||||
|
||||
} else if ( rs->sr_err == DB_LOCK_NOTGRANTED )
|
||||
{
|
||||
goto fetch_entry_retry;
|
||||
} else if ( rs->sr_err == LDAP_OTHER ) {
|
||||
rs->sr_text = "internal error";
|
||||
send_ldap_result( op, rs );
|
||||
goto done;
|
||||
}
|
||||
|
||||
if ( ei && rs->sr_err == LDAP_SUCCESS ) {
|
||||
e = ei->bei_e;
|
||||
} else {
|
||||
e = NULL;
|
||||
}
|
||||
|
||||
if ( e == NULL ) {
|
||||
if( !MDB_IDL_IS_RANGE(candidates) ) {
|
||||
/* only complain for non-range IDLs */
|
||||
|
|
@ -776,17 +626,9 @@ txnfail:
|
|||
(long) id, 0, 0 );
|
||||
} else {
|
||||
/* get the next ID from the DB */
|
||||
id_retry:
|
||||
rs->sr_err = mdb_get_nextid( mdb, ltid, &cursor );
|
||||
if ( rs->sr_err == DB_NOTFOUND ) {
|
||||
if ( rs->sr_err == MDB_NOTFOUND ) {
|
||||
break;
|
||||
} else if ( rs->sr_err == DB_LOCK_DEADLOCK ) {
|
||||
if ( opinfo )
|
||||
goto txnfail;
|
||||
ltid->flags &= ~TXN_DEADLOCK;
|
||||
goto id_retry;
|
||||
} else if ( rs->sr_err == DB_LOCK_NOTGRANTED ) {
|
||||
goto id_retry;
|
||||
}
|
||||
if ( rs->sr_err ) {
|
||||
rs->sr_err = LDAP_OTHER;
|
||||
|
|
@ -820,13 +662,6 @@ id_retry:
|
|||
}
|
||||
|
||||
/* Does this candidate actually satisfy the search scope?
|
||||
*
|
||||
* Note that we don't lock access to the bei_parent pointer.
|
||||
* Since only leaf nodes can be deleted, the parent of any
|
||||
* node will always be a valid node. Also since we have
|
||||
* a Read lock on the data, it cannot be renamed out of the
|
||||
* scope while we are looking at it, and unless we're using
|
||||
* MDB_HIER, its parents cannot be moved either.
|
||||
*/
|
||||
scopeok = 0;
|
||||
switch( op->ors_scope ) {
|
||||
|
|
@ -835,24 +670,15 @@ id_retry:
|
|||
if ( id == base.e_id ) scopeok = 1;
|
||||
break;
|
||||
|
||||
case LDAP_SCOPE_ONELEVEL:
|
||||
if ( ei->bei_parent->bei_id == base.e_id ) scopeok = 1;
|
||||
break;
|
||||
|
||||
#ifdef LDAP_SCOPE_CHILDREN
|
||||
case LDAP_SCOPE_CHILDREN:
|
||||
if ( id == base.e_id ) break;
|
||||
/* Fall-thru */
|
||||
#endif
|
||||
case LDAP_SCOPE_SUBTREE: {
|
||||
EntryInfo *tmp;
|
||||
for ( tmp = BEI(e); tmp; tmp = tmp->bei_parent ) {
|
||||
if ( tmp->bei_id == base.e_id ) {
|
||||
scopeok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} break;
|
||||
case LDAP_SCOPE_ONELEVEL:
|
||||
case LDAP_SCOPE_SUBTREE:
|
||||
if ( mdb_idscopes( op, ltid, &idcursor, id, scopes ) == MDB_SUCCESS ) scopeok = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
/* aliases were already dereferenced in candidate list */
|
||||
|
|
@ -866,25 +692,6 @@ id_retry:
|
|||
{
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
/* scopes is only non-empty for onelevel or subtree */
|
||||
if ( !scopeok && MDB_IDL_N(scopes) ) {
|
||||
unsigned x;
|
||||
if ( op->ors_scope == LDAP_SCOPE_ONELEVEL ) {
|
||||
x = mdb_idl_search( scopes, e->e_id );
|
||||
if ( scopes[x] == e->e_id ) scopeok = 1;
|
||||
} else {
|
||||
/* subtree, walk up the tree */
|
||||
EntryInfo *tmp = BEI(e);
|
||||
for (;tmp->bei_parent; tmp=tmp->bei_parent) {
|
||||
x = mdb_idl_search( scopes, tmp->bei_id );
|
||||
if ( scopes[x] == tmp->bei_id ) {
|
||||
scopeok = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Not in scope, ignore it */
|
||||
|
|
@ -897,6 +704,13 @@ id_retry:
|
|||
goto loop_continue;
|
||||
}
|
||||
|
||||
if ( !manageDSAit && is_entry_glue( e )) {
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
mdb_id2name( op, ltid, &idcursor, e->e_id,
|
||||
&e->e_name, &e->e_nname );
|
||||
|
||||
/*
|
||||
* if it's a referral, add it to the list of referrals. only do
|
||||
* this for non-base searches, and don't check the filter
|
||||
|
|
@ -905,49 +719,17 @@ id_retry:
|
|||
if ( !manageDSAit && op->oq_search.rs_scope != LDAP_SCOPE_BASE
|
||||
&& is_entry_referral( e ) )
|
||||
{
|
||||
struct mdb_op_info bois;
|
||||
struct mdb_lock_info blis;
|
||||
BerVarray erefs = get_entry_referrals( op, e );
|
||||
rs->sr_ref = referral_rewrite( erefs, &e->e_name, NULL,
|
||||
op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL
|
||||
? LDAP_SCOPE_BASE : LDAP_SCOPE_SUBTREE );
|
||||
|
||||
/* Must set lockinfo so that entry_release will work */
|
||||
if (!opinfo) {
|
||||
bois.boi_oe.oe_key = mdb;
|
||||
bois.boi_txn = NULL;
|
||||
bois.boi_err = 0;
|
||||
bois.boi_acl_cache = op->o_do_not_cache;
|
||||
bois.boi_flag = BOI_DONTFREE;
|
||||
bois.boi_locks = &blis;
|
||||
blis.bli_next = NULL;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe,
|
||||
oe_next );
|
||||
} else {
|
||||
blis.bli_next = opinfo->boi_locks;
|
||||
opinfo->boi_locks = &blis;
|
||||
}
|
||||
blis.bli_id = e->e_id;
|
||||
blis.bli_lock = lock;
|
||||
blis.bli_flag = BLI_DONTFREE;
|
||||
|
||||
rs->sr_entry = e;
|
||||
rs->sr_flags = REP_ENTRY_MUSTRELEASE;
|
||||
rs->sr_flags = 0;
|
||||
|
||||
send_search_reference( op, rs );
|
||||
|
||||
if ( blis.bli_flag ) {
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
mdb_cache_return_entry_r(mdb, e, &lock);
|
||||
if ( opinfo ) {
|
||||
opinfo->boi_locks = blis.bli_next;
|
||||
} else {
|
||||
LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe,
|
||||
OpExtra, oe_next );
|
||||
}
|
||||
}
|
||||
mdb_entry_return( e );
|
||||
rs->sr_entry = NULL;
|
||||
e = NULL;
|
||||
|
||||
|
|
@ -958,10 +740,6 @@ id_retry:
|
|||
goto loop_continue;
|
||||
}
|
||||
|
||||
if ( !manageDSAit && is_entry_glue( e )) {
|
||||
goto loop_continue;
|
||||
}
|
||||
|
||||
/* if it matches the filter and scope, send it */
|
||||
rs->sr_err = test_filter( op, e, op->oq_search.rs_filter );
|
||||
|
||||
|
|
@ -969,10 +747,7 @@ id_retry:
|
|||
/* check size limit */
|
||||
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
|
||||
if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
mdb_cache_return_entry_r( mdb, e, &lock );
|
||||
mdb_entry_return( e );
|
||||
e = NULL;
|
||||
send_paged_response( op, rs, &lastid, tentries );
|
||||
goto done;
|
||||
|
|
@ -981,56 +756,18 @@ id_retry:
|
|||
}
|
||||
|
||||
if (e) {
|
||||
struct mdb_op_info bois;
|
||||
struct mdb_lock_info blis;
|
||||
|
||||
/* Must set lockinfo so that entry_release will work */
|
||||
if (!opinfo) {
|
||||
bois.boi_oe.oe_key = mdb;
|
||||
bois.boi_txn = NULL;
|
||||
bois.boi_err = 0;
|
||||
bois.boi_acl_cache = op->o_do_not_cache;
|
||||
bois.boi_flag = BOI_DONTFREE;
|
||||
bois.boi_locks = &blis;
|
||||
blis.bli_next = NULL;
|
||||
LDAP_SLIST_INSERT_HEAD( &op->o_extra, &bois.boi_oe,
|
||||
oe_next );
|
||||
} else {
|
||||
blis.bli_next = opinfo->boi_locks;
|
||||
opinfo->boi_locks = &blis;
|
||||
}
|
||||
blis.bli_id = e->e_id;
|
||||
blis.bli_lock = lock;
|
||||
blis.bli_flag = BLI_DONTFREE;
|
||||
|
||||
/* safe default */
|
||||
rs->sr_attrs = op->oq_search.rs_attrs;
|
||||
rs->sr_operational_attrs = NULL;
|
||||
rs->sr_ctrls = NULL;
|
||||
rs->sr_entry = e;
|
||||
RS_ASSERT( e->e_private != NULL );
|
||||
rs->sr_flags = REP_ENTRY_MUSTRELEASE;
|
||||
rs->sr_flags = 0;
|
||||
rs->sr_err = LDAP_SUCCESS;
|
||||
rs->sr_err = send_search_entry( op, rs );
|
||||
rs->sr_attrs = NULL;
|
||||
rs->sr_entry = NULL;
|
||||
|
||||
/* send_search_entry will usually free it.
|
||||
* an overlay might leave its own copy here;
|
||||
* bli_flag will be 0 if lock was already released.
|
||||
*/
|
||||
if ( blis.bli_flag ) {
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
mdb_cache_return_entry_r(mdb, e, &lock);
|
||||
if ( opinfo ) {
|
||||
opinfo->boi_locks = blis.bli_next;
|
||||
} else {
|
||||
LDAP_SLIST_REMOVE( &op->o_extra, &bois.boi_oe,
|
||||
OpExtra, oe_next );
|
||||
}
|
||||
}
|
||||
mdb_entry_return( e );
|
||||
e = NULL;
|
||||
|
||||
switch ( rs->sr_err ) {
|
||||
|
|
@ -1062,10 +799,7 @@ id_retry:
|
|||
loop_continue:
|
||||
if( e != NULL ) {
|
||||
/* free reader lock */
|
||||
#ifdef SLAP_ZONE_ALLOC
|
||||
slap_zn_runlock(mdb->bi_cache.c_zctx, e);
|
||||
#endif
|
||||
mdb_cache_return_entry_r( mdb, e , &lock );
|
||||
mdb_entry_return( e );
|
||||
RS_ASSERT( rs->sr_entry == NULL );
|
||||
e = NULL;
|
||||
rs->sr_entry = NULL;
|
||||
|
|
@ -1086,6 +820,8 @@ nochange:
|
|||
rs->sr_err = LDAP_SUCCESS;
|
||||
|
||||
done:
|
||||
if( idcursor )
|
||||
mdb_cursor_close( idcursor );
|
||||
if( rs->sr_v2ref ) {
|
||||
ber_bvarray_free( rs->sr_v2ref );
|
||||
rs->sr_v2ref = NULL;
|
||||
|
|
@ -1158,17 +894,17 @@ static void *search_stack( Operation *op )
|
|||
ldap_pvt_thread_pool_getkey( op->o_threadctx, (void *)search_stack,
|
||||
&ret, NULL );
|
||||
} else {
|
||||
ret = mdb->bi_search_stack;
|
||||
ret = mdb->mi_search_stack;
|
||||
}
|
||||
|
||||
if ( !ret ) {
|
||||
ret = ch_malloc( mdb->bi_search_stack_depth * MDB_IDL_UM_SIZE
|
||||
ret = ch_malloc( mdb->mi_search_stack_depth * MDB_IDL_UM_SIZE
|
||||
* sizeof( ID ) );
|
||||
if ( op->o_threadctx ) {
|
||||
ldap_pvt_thread_pool_setkey( op->o_threadctx, (void *)search_stack,
|
||||
ret, search_stack_free, NULL, NULL );
|
||||
} else {
|
||||
mdb->bi_search_stack = ret;
|
||||
mdb->mi_search_stack = ret;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
|
@ -1178,32 +914,29 @@ static int search_candidates(
|
|||
Operation *op,
|
||||
SlapReply *rs,
|
||||
Entry *e,
|
||||
DB_TXN *txn,
|
||||
MDB_txn *txn,
|
||||
ID *ids,
|
||||
ID *scopes )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
int rc, depth = 1;
|
||||
Filter f, rf, xf, nf;
|
||||
Filter *f, rf, xf, nf, sf;
|
||||
ID *stack;
|
||||
AttributeAssertion aa_ref = ATTRIBUTEASSERTION_INIT;
|
||||
Filter sf;
|
||||
AttributeAssertion aa_subentry = ATTRIBUTEASSERTION_INIT;
|
||||
|
||||
/*
|
||||
* This routine takes as input a filter (user-filter)
|
||||
* and rewrites it as follows:
|
||||
* (&(scope=DN)[(objectClass=subentry)]
|
||||
* (|[(objectClass=referral)(objectClass=alias)](user-filter))
|
||||
* (|[(objectClass=referral)](user-filter))
|
||||
*/
|
||||
|
||||
Debug(LDAP_DEBUG_TRACE,
|
||||
"search_candidates: base=\"%s\" (0x%08lx) scope=%d\n",
|
||||
e->e_nname.bv_val, (long) e->e_id, op->oq_search.rs_scope );
|
||||
|
||||
xf.f_or = op->oq_search.rs_filter;
|
||||
xf.f_choice = LDAP_FILTER_OR;
|
||||
xf.f_next = NULL;
|
||||
f = op->oq_search.rs_filter;
|
||||
|
||||
/* If the user's filter uses objectClass=*,
|
||||
* these clauses are redundant.
|
||||
|
|
@ -1217,52 +950,48 @@ static int search_candidates(
|
|||
rf.f_ava = &aa_ref;
|
||||
rf.f_av_desc = slap_schema.si_ad_objectClass;
|
||||
rf.f_av_value = bv_ref;
|
||||
rf.f_next = xf.f_or;
|
||||
rf.f_next = f;
|
||||
xf.f_or = &rf;
|
||||
xf.f_choice = LDAP_FILTER_OR;
|
||||
xf.f_next = NULL;
|
||||
f = &xf;
|
||||
depth++;
|
||||
}
|
||||
}
|
||||
|
||||
f.f_next = NULL;
|
||||
f.f_choice = LDAP_FILTER_AND;
|
||||
f.f_and = &nf;
|
||||
/* Dummy; we compute scope separately now */
|
||||
nf.f_choice = SLAPD_FILTER_COMPUTED;
|
||||
nf.f_result = LDAP_SUCCESS;
|
||||
nf.f_next = ( xf.f_or == op->oq_search.rs_filter )
|
||||
? op->oq_search.rs_filter : &xf ;
|
||||
/* Filter depth increased again, adding dummy clause */
|
||||
depth++;
|
||||
|
||||
if( get_subentries_visibility( op ) ) {
|
||||
struct berval bv_subentry = BER_BVC( "subentry" );
|
||||
sf.f_choice = LDAP_FILTER_EQUALITY;
|
||||
sf.f_ava = &aa_subentry;
|
||||
sf.f_av_desc = slap_schema.si_ad_objectClass;
|
||||
sf.f_av_value = bv_subentry;
|
||||
sf.f_next = nf.f_next;
|
||||
nf.f_next = &sf;
|
||||
sf.f_next = f;
|
||||
nf.f_choice = LDAP_FILTER_AND;
|
||||
nf.f_and = &sf;
|
||||
nf.f_next = NULL;
|
||||
f = &nf;
|
||||
depth++;
|
||||
}
|
||||
|
||||
/* Allocate IDL stack, plus 1 more for former tmp */
|
||||
if ( depth+1 > mdb->bi_search_stack_depth ) {
|
||||
if ( depth+1 > mdb->mi_search_stack_depth ) {
|
||||
stack = ch_malloc( (depth + 1) * MDB_IDL_UM_SIZE * sizeof( ID ) );
|
||||
} else {
|
||||
stack = search_stack( op );
|
||||
}
|
||||
|
||||
if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
|
||||
rc = search_aliases( op, rs, e, txn, ids, scopes, stack );
|
||||
rc = search_aliases( op, rs, e, txn, scopes, stack );
|
||||
} else {
|
||||
rc = mdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack );
|
||||
rc = LDAP_SUCCESS;
|
||||
}
|
||||
|
||||
if ( rc == LDAP_SUCCESS ) {
|
||||
rc = mdb_filter_candidates( op, txn, &f, ids,
|
||||
rc = mdb_filter_candidates( op, txn, f, ids,
|
||||
stack, stack+MDB_IDL_UM_SIZE );
|
||||
}
|
||||
|
||||
if ( depth+1 > mdb->bi_search_stack_depth ) {
|
||||
if ( depth+1 > mdb->mi_search_stack_depth ) {
|
||||
ch_free( stack );
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
#include "idl.h"
|
||||
|
||||
static MDB_txn *txn = NULL;
|
||||
static MDB_cursor *cursor = NULL;
|
||||
static MDB_cursor *cursor = NULL, *idcursor = NULL;
|
||||
static MDB_val key, data;
|
||||
static EntryHeader eh;
|
||||
static ID previd = NOID;
|
||||
|
|
@ -131,6 +131,10 @@ int mdb_tool_entry_close(
|
|||
}
|
||||
#endif
|
||||
|
||||
if( idcursor ) {
|
||||
mdb_cursor_close( idcursor );
|
||||
idcursor = NULL;
|
||||
}
|
||||
if( cursor ) {
|
||||
mdb_cursor_close( cursor );
|
||||
cursor = NULL;
|
||||
|
|
@ -293,7 +297,7 @@ mdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep )
|
|||
op.o_tmpmemctx = NULL;
|
||||
op.o_tmpmfuncs = &ch_mfuncs;
|
||||
|
||||
rc = mdb_id2name( &op, txn, id, &dn, &ndn );
|
||||
rc = mdb_id2name( &op, txn, &idcursor, id, &dn, &ndn );
|
||||
if ( rc ) {
|
||||
rc = LDAP_OTHER;
|
||||
mdb_entry_return( e );
|
||||
|
|
@ -437,18 +441,18 @@ static int mdb_tool_next_id(
|
|||
return rc;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int
|
||||
mdb_tool_index_add(
|
||||
Operation *op,
|
||||
DB_TXN *txn,
|
||||
MDB_txn *txn,
|
||||
Entry *e )
|
||||
{
|
||||
struct mdb_info *mdb = (struct mdb_info *) op->o_bd->be_private;
|
||||
|
||||
if ( !mdb->bi_nattrs )
|
||||
if ( !mdb->mi_nattrs )
|
||||
return 0;
|
||||
|
||||
#if 0
|
||||
if ( slapMode & SLAP_TOOL_QUICK ) {
|
||||
IndexRec *ir;
|
||||
int i, rc;
|
||||
|
|
@ -494,11 +498,12 @@ mdb_tool_index_add(
|
|||
}
|
||||
ldap_pvt_thread_mutex_unlock( &mdb_tool_index_mutex );
|
||||
return rc;
|
||||
} else {
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
return mdb_index_entry_add( op, txn, e );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ID mdb_tool_entry_put(
|
||||
BackendDB *be,
|
||||
|
|
@ -608,16 +613,15 @@ done:
|
|||
return e->e_id;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int mdb_tool_entry_reindex(
|
||||
BackendDB *be,
|
||||
ID id,
|
||||
AttributeDescription **adv )
|
||||
{
|
||||
struct mdb_info *bi = (struct mdb_info *) be->be_private;
|
||||
struct mdb_info *mi = (struct mdb_info *) be->be_private;
|
||||
int rc;
|
||||
Entry *e;
|
||||
DB_TXN *tid = NULL;
|
||||
MDB_txn *tid = NULL;
|
||||
Operation op = {0};
|
||||
Opheader ohdr = {0};
|
||||
|
||||
|
|
@ -630,7 +634,7 @@ int mdb_tool_entry_reindex(
|
|||
/* No indexes configured, nothing to do. Could return an
|
||||
* error here to shortcut things.
|
||||
*/
|
||||
if (!bi->bi_attrs) {
|
||||
if (!mi->mi_attrs) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -638,7 +642,7 @@ int mdb_tool_entry_reindex(
|
|||
if ( adv ) {
|
||||
int i, j, n;
|
||||
|
||||
if ( bi->bi_attrs[0]->ai_desc != adv[0] ) {
|
||||
if ( mi->mi_attrs[0]->ai_desc != adv[0] ) {
|
||||
/* count */
|
||||
for ( n = 0; adv[n]; n++ ) ;
|
||||
|
||||
|
|
@ -654,16 +658,16 @@ int mdb_tool_entry_reindex(
|
|||
}
|
||||
|
||||
for ( i = 0; adv[i]; i++ ) {
|
||||
if ( bi->bi_attrs[i]->ai_desc != adv[i] ) {
|
||||
for ( j = i+1; j < bi->bi_nattrs; j++ ) {
|
||||
if ( bi->bi_attrs[j]->ai_desc == adv[i] ) {
|
||||
AttrInfo *ai = bi->bi_attrs[i];
|
||||
bi->bi_attrs[i] = bi->bi_attrs[j];
|
||||
bi->bi_attrs[j] = ai;
|
||||
if ( mi->mi_attrs[i]->ai_desc != adv[i] ) {
|
||||
for ( j = i+1; j < mi->mi_nattrs; j++ ) {
|
||||
if ( mi->mi_attrs[j]->ai_desc == adv[i] ) {
|
||||
AttrInfo *ai = mi->mi_attrs[i];
|
||||
mi->mi_attrs[i] = mi->mi_attrs[j];
|
||||
mi->mi_attrs[j] = ai;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( j == bi->bi_nattrs ) {
|
||||
if ( j == mi->mi_nattrs ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
LDAP_XSTRING(mdb_tool_entry_reindex)
|
||||
": no index configured for %s\n",
|
||||
|
|
@ -672,13 +676,7 @@ int mdb_tool_entry_reindex(
|
|||
}
|
||||
}
|
||||
}
|
||||
bi->bi_nattrs = i;
|
||||
}
|
||||
|
||||
/* Get the first attribute to index */
|
||||
if (bi->bi_linear_index && !index_nattrs) {
|
||||
index_nattrs = bi->bi_nattrs - 1;
|
||||
bi->bi_nattrs = 1;
|
||||
mi->mi_nattrs = i;
|
||||
}
|
||||
|
||||
e = mdb_tool_entry_get( be, id );
|
||||
|
|
@ -691,15 +689,15 @@ int mdb_tool_entry_reindex(
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (! (slapMode & SLAP_TOOL_QUICK)) {
|
||||
rc = TXN_BEGIN( bi->bi_dbenv, NULL, &tid, bi->bi_db_opflags );
|
||||
if( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(mdb_tool_entry_reindex) ": "
|
||||
"txn_begin failed: %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
goto done;
|
||||
}
|
||||
if ( !txn ) {
|
||||
rc = mdb_txn_begin( mi->mi_dbenv, 0, &tid );
|
||||
if( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(mdb_tool_entry_reindex) ": "
|
||||
"txn_begin failed: %s (%d)\n",
|
||||
mdb_strerror(rc), rc, 0 );
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -722,32 +720,30 @@ int mdb_tool_entry_reindex(
|
|||
|
||||
done:
|
||||
if( rc == 0 ) {
|
||||
if (! (slapMode & SLAP_TOOL_QUICK)) {
|
||||
rc = TXN_COMMIT( tid, 0 );
|
||||
if( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(mdb_tool_entry_reindex)
|
||||
": txn_commit failed: %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
mdb_writes++;
|
||||
if ( mdb_writes >= mdb_writes_per_commit ) {
|
||||
rc = mdb_txn_commit( tid );
|
||||
if( rc != 0 ) {
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(mdb_tool_entry_reindex)
|
||||
": txn_commit failed: %s (%d)\n",
|
||||
mdb_strerror(rc), rc, 0 );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
if (! (slapMode & SLAP_TOOL_QUICK)) {
|
||||
TXN_ABORT( tid );
|
||||
mdb_txn_abort( tid );
|
||||
Debug( LDAP_DEBUG_ANY,
|
||||
"=> " LDAP_XSTRING(mdb_tool_entry_reindex)
|
||||
": txn_aborted! %s (%d)\n",
|
||||
db_strerror(rc), rc, 0 );
|
||||
}
|
||||
mdb_strerror(rc), rc, 0 );
|
||||
e->e_id = NOID;
|
||||
}
|
||||
mdb_entry_release( &op, e, 0 );
|
||||
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
|
||||
ID mdb_tool_entry_modify(
|
||||
BackendDB *be,
|
||||
|
|
|
|||
Loading…
Reference in a new issue