]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-bdb/search.c
TS#7303 tweak
[openldap] / servers / slapd / back-bdb / search.c
index b152c2b2966d41121c39a937443b8b41dd9a04df..d30d7b9f2e7b5ba1095bb67ddf756fb838ae8788 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 2000-2011 The OpenLDAP Foundation.
+ * Copyright 2000-2012 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -184,7 +184,7 @@ static int search_aliases(
        BDB_IDL_ZERO( aliases );
        rs->sr_err = bdb_filter_candidates( op, txn, &af, aliases,
                curscop, visited );
-       if (rs->sr_err != LDAP_SUCCESS) {
+       if (rs->sr_err != LDAP_SUCCESS || BDB_IDL_IS_ZERO( aliases )) {
                return rs->sr_err;
        }
        oldsubs[0] = 1;
@@ -313,7 +313,7 @@ sameido:
 /* Get the next ID from the DB. Used if the candidate list is
  * a range and simple iteration hits missing entryIDs
  */
-static ID
+static int
 bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
 {
        DBC *curs;
@@ -326,7 +326,7 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
        rc = bdb->bi_id2entry->bdi_db->cursor(
                bdb->bi_id2entry->bdi_db, ltid, &curs, bdb->bi_db_opflags );
        if ( rc )
-               return NOID;
+               return rc;
        key.data = &nid;
        key.size = key.ulen = sizeof(ID);
        key.flags = DB_DBT_USERMEM;
@@ -335,9 +335,9 @@ bdb_get_nextid(struct bdb_info *bdb, DB_TXN *ltid, ID *cursor)
        rc = curs->c_get( curs, &key, &data, DB_SET_RANGE );
        curs->c_close( curs );
        if ( rc )
-               return NOID;
+               return rc;
        BDB_DISK2ID( &nid, cursor );
-       return *cursor;
+       return 0;
 }
 
 int
@@ -747,6 +747,7 @@ fetch_entry_retry:
                                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;
@@ -775,8 +776,25 @@ fetch_entry_retry:
                                        (long) id, 0, 0 );
                        } else {
                                /* get the next ID from the DB */
-                               id = bdb_get_nextid( bdb, ltid, &cursor );
-                               cursor = id - 1;
+id_retry:
+                               rs->sr_err = bdb_get_nextid( bdb, ltid, &cursor );
+                               if ( rs->sr_err == DB_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;
+                                       rs->sr_text = "internal error in get_nextid";
+                                       send_ldap_result( op, rs );
+                                       goto done;
+                               }
+                               cursor--;
                        }
 
                        goto loop_continue;
@@ -1235,6 +1253,8 @@ static int search_candidates(
 
        if( op->ors_deref & LDAP_DEREF_SEARCHING ) {
                rc = search_aliases( op, rs, e, txn, ids, scopes, stack );
+               if ( BDB_IDL_IS_ZERO( ids ) && rc == LDAP_SUCCESS )
+                       rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack );
        } else {
                rc = bdb_dn2idl( op, txn, &e->e_nname, BEI(e), ids, stack );
        }