Fix attribute/group to allow TXN to abort on lock failure. Save and

restore op->o_do_not_cache on TXN retry, bdb_group will set it if it
fails to get a lock.
This commit is contained in:
Howard Chu 2003-02-26 12:09:10 +00:00
parent 00837465c4
commit 18554e7511
8 changed files with 53 additions and 2 deletions

View File

@ -99,6 +99,7 @@ retry: /* transaction retry */
rc = TXN_ABORT( ltid ); rc = TXN_ABORT( ltid );
ltid = NULL; ltid = NULL;
op->o_private = NULL; op->o_private = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rc != 0 ) { if( rc != 0 ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
text = "internal error"; text = "internal error";
@ -134,6 +135,7 @@ retry: /* transaction retry */
opinfo.boi_txn = ltid; opinfo.boi_txn = ltid;
opinfo.boi_locker = locker; opinfo.boi_locker = locker;
opinfo.boi_err = 0; opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo; op->o_private = &opinfo;
/* /*

View File

@ -104,6 +104,12 @@ dn2entry_retry:
break; break;
case DB_LOCK_DEADLOCK: case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED: case DB_LOCK_NOTGRANTED:
/* the txn must abort and retry */
if ( txn ) {
boi->boi_err = rc;
return LDAP_BUSY;
}
ldap_pvt_thread_yield();
goto dn2entry_retry; goto dn2entry_retry;
default: default:
boi->boi_err = rc; boi->boi_err = rc;

View File

@ -157,6 +157,7 @@ struct bdb_op_info {
DB_TXN* boi_txn; DB_TXN* boi_txn;
u_int32_t boi_err; u_int32_t boi_err;
u_int32_t boi_locker; u_int32_t boi_locker;
int boi_acl_cache;
}; };
#define DB_OPEN(db, file, name, type, flags, mode) \ #define DB_OPEN(db, file, name, type, flags, mode) \

View File

@ -70,6 +70,7 @@ retry: /* transaction retry */
rc = TXN_ABORT( ltid ); rc = TXN_ABORT( ltid );
ltid = NULL; ltid = NULL;
op->o_private = NULL; op->o_private = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rc != 0 ) { if( rc != 0 ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
text = "internal error"; text = "internal error";
@ -106,6 +107,7 @@ retry: /* transaction retry */
opinfo.boi_txn = ltid; opinfo.boi_txn = ltid;
opinfo.boi_locker = locker; opinfo.boi_locker = locker;
opinfo.boi_err = 0; opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo; op->o_private = &opinfo;
if ( !be_issuffix( be, ndn ) ) { if ( !be_issuffix( be, ndn ) ) {

View File

@ -109,9 +109,19 @@ dn2entry_retry:
/* can we find group entry */ /* can we find group entry */
rc = bdb_dn2entry_r( be, txn, gr_ndn, &e, NULL, 0, locker, &lock ); rc = bdb_dn2entry_r( be, txn, gr_ndn, &e, NULL, 0, locker, &lock );
if( rc ) { if( rc ) {
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED )
goto dn2entry_retry;
boi->boi_err = rc; boi->boi_err = rc;
if ( rc == DB_LOCK_DEADLOCK || rc == DB_LOCK_NOTGRANTED ) {
if ( txn ) {
/* must let owning txn abort, but our result
* is still inconclusive, so don't let it
* get cached.
*/
op->o_do_not_cache = 1;
return( 1 );
}
ldap_pvt_thread_yield();
goto dn2entry_retry;
}
if ( free_lock_id ) { if ( free_lock_id ) {
LOCK_ID_FREE ( bdb->bi_dbenv, locker ); LOCK_ID_FREE ( bdb->bi_dbenv, locker );
} }

View File

@ -319,6 +319,7 @@ retry: /* transaction retry */
rc = TXN_ABORT( ltid ); rc = TXN_ABORT( ltid );
ltid = NULL; ltid = NULL;
op->o_private = NULL; op->o_private = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rc != 0 ) { if( rc != 0 ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
text = "internal error"; text = "internal error";
@ -351,6 +352,7 @@ retry: /* transaction retry */
opinfo.boi_txn = ltid; opinfo.boi_txn = ltid;
opinfo.boi_locker = locker; opinfo.boi_locker = locker;
opinfo.boi_err = 0; opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo; op->o_private = &opinfo;
/* get entry */ /* get entry */

View File

@ -108,6 +108,7 @@ retry: /* transaction retry */
rc = TXN_ABORT( ltid ); rc = TXN_ABORT( ltid );
ltid = NULL; ltid = NULL;
op->o_private = NULL; op->o_private = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rc != 0 ) { if( rc != 0 ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
text = "internal error"; text = "internal error";
@ -141,6 +142,7 @@ retry: /* transaction retry */
opinfo.boi_txn = ltid; opinfo.boi_txn = ltid;
opinfo.boi_locker = locker; opinfo.boi_locker = locker;
opinfo.boi_err = 0; opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo; op->o_private = &opinfo;
/* get entry */ /* get entry */
@ -276,6 +278,12 @@ retry: /* transaction retry */
rc = access_allowed( be, conn, op, p, rc = access_allowed( be, conn, op, p,
children, NULL, ACL_WRITE, NULL ); children, NULL, ACL_WRITE, NULL );
switch( opinfo.boi_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
}
if ( ! rc ) { if ( ! rc ) {
rc = LDAP_INSUFFICIENT_ACCESS; rc = LDAP_INSUFFICIENT_ACCESS;
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
@ -326,6 +334,12 @@ retry: /* transaction retry */
rc = access_allowed( be, conn, op, p, rc = access_allowed( be, conn, op, p,
children, NULL, ACL_WRITE, NULL ); children, NULL, ACL_WRITE, NULL );
switch( opinfo.boi_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
}
p = NULL; p = NULL;
if ( ! rc ) { if ( ! rc ) {
@ -467,6 +481,12 @@ retry: /* transaction retry */
rc = access_allowed( be, conn, op, np, children, rc = access_allowed( be, conn, op, np, children,
NULL, ACL_WRITE, NULL ); NULL, ACL_WRITE, NULL );
switch( opinfo.boi_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
}
if( ! rc ) { if( ! rc ) {
#ifdef NEW_LOGGING #ifdef NEW_LOGGING
LDAP_LOG ( OPERATION, DETAIL1, LDAP_LOG ( OPERATION, DETAIL1,
@ -528,6 +548,12 @@ retry: /* transaction retry */
rc = access_allowed( be, conn, op, np, rc = access_allowed( be, conn, op, np,
children, NULL, ACL_WRITE, NULL ); children, NULL, ACL_WRITE, NULL );
switch( opinfo.boi_err ) {
case DB_LOCK_DEADLOCK:
case DB_LOCK_NOTGRANTED:
goto retry;
}
np = NULL; np = NULL;
if ( ! rc ) { if ( ! rc ) {

View File

@ -123,6 +123,7 @@ retry: /* transaction retry */
rc = TXN_ABORT( ltid ); rc = TXN_ABORT( ltid );
ltid = NULL; ltid = NULL;
op->o_private = NULL; op->o_private = NULL;
op->o_do_not_cache = opinfo.boi_acl_cache;
if( rc != 0 ) { if( rc != 0 ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
*text = "internal error"; *text = "internal error";
@ -156,6 +157,7 @@ retry: /* transaction retry */
opinfo.boi_txn = ltid; opinfo.boi_txn = ltid;
opinfo.boi_locker = locker; opinfo.boi_locker = locker;
opinfo.boi_err = 0; opinfo.boi_err = 0;
opinfo.boi_acl_cache = op->o_do_not_cache;
op->o_private = &opinfo; op->o_private = &opinfo;
/* get entry */ /* get entry */