X-Git-Url: http://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Flock.c;h=b1799a7e1b9aa0ca9ec5652f573ba74ac7019761;hp=3e939c4b8ffe3c04e57a2bf67bdfbec51b3ddf90;hb=2b5cb9bd6be4e61870ba7a400d1a9d91c5933371;hpb=850c5cfed46cd4f38df79783791969c7b30ad9da diff --git a/ccan/tdb2/lock.c b/ccan/tdb2/lock.c index 3e939c4b..b1799a7e 100644 --- a/ccan/tdb2/lock.c +++ b/ccan/tdb2/lock.c @@ -120,7 +120,7 @@ static int fcntl_unlock(struct tdb_context *tdb, int rw, off_t off, off_t len) } /* a byte range locking function - return 0 on success - this functions locks/unlocks 1 byte at the specified offset. + this functions locks len bytes at the specified offset. note that a len of zero means lock to end of file */ @@ -264,10 +264,7 @@ enum TDB_ERROR tdb_lock_and_recover(struct tdb_context *tdb) tdb_allrecord_unlock(tdb, F_WRLCK); return ecode; } - if (tdb_transaction_recover(tdb) == -1) { - ecode = tdb->ecode; - } - + ecode = tdb_transaction_recover(tdb); tdb_unlock_open(tdb); tdb_allrecord_unlock(tdb, F_WRLCK); @@ -333,16 +330,21 @@ static enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb, /* First time we grab a lock, perhaps someone died in commit? */ if (!(flags & TDB_LOCK_NOCHECK) - && tdb->num_lockrecs == 0 - && unlikely(tdb_needs_recovery(tdb))) { - tdb_brunlock(tdb, ltype, offset, 1); - - ecode = tdb_lock_and_recover(tdb); - if (ecode == TDB_SUCCESS) { - ecode = tdb_brlock(tdb, ltype, offset, 1, flags); - } - if (ecode != TDB_SUCCESS) { - return ecode; + && tdb->num_lockrecs == 0) { + tdb_bool_err berr = tdb_needs_recovery(tdb); + if (berr != false) { + tdb_brunlock(tdb, ltype, offset, 1); + + if (berr < 0) + return berr; + ecode = tdb_lock_and_recover(tdb); + if (ecode == TDB_SUCCESS) { + ecode = tdb_brlock(tdb, ltype, offset, 1, + flags); + } + if (ecode != TDB_SUCCESS) { + return ecode; + } } } @@ -448,12 +450,7 @@ enum TDB_ERROR tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum tdb_lock_flags flags, bool upgradable) { enum TDB_ERROR ecode; - - /* FIXME: There are no locks on read-only dbs */ - if (tdb->read_only) { - return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, - "tdb_allrecord_lock: read-only"); - } + tdb_bool_err berr; if (tdb->allrecord_lock.count && (ltype == F_RDLCK || tdb->allrecord_lock.ltype == F_WRLCK)) { @@ -517,16 +514,21 @@ again: tdb->allrecord_lock.off = upgradable; /* Now check for needing recovery. */ - if (!(flags & TDB_LOCK_NOCHECK) && unlikely(tdb_needs_recovery(tdb))) { - tdb_allrecord_unlock(tdb, ltype); - ecode = tdb_lock_and_recover(tdb); - if (ecode != TDB_SUCCESS) { - return ecode; - } - goto again; - } + if (flags & TDB_LOCK_NOCHECK) + return TDB_SUCCESS; - return TDB_SUCCESS; + berr = tdb_needs_recovery(tdb); + if (likely(berr == false)) + return TDB_SUCCESS; + + tdb_allrecord_unlock(tdb, ltype); + if (berr < 0) + return berr; + ecode = tdb_lock_and_recover(tdb); + if (ecode != TDB_SUCCESS) { + return ecode; + } + goto again; } enum TDB_ERROR tdb_lock_open(struct tdb_context *tdb, enum tdb_lock_flags flags)