X-Git-Url: https://git.ozlabs.org/?p=ccan;a=blobdiff_plain;f=ccan%2Ftdb2%2Flock.c;h=a71c95f6e5cc9479288deae43581361019361c38;hp=bd896a35e0144d5b2db619598cabd0bf4ae62690;hb=fbae37ba91ec230e34be564084099726cc3a9d47;hpb=c8c3b3568677e8b0105f84e4ab068c580faf4591 diff --git a/ccan/tdb2/lock.c b/ccan/tdb2/lock.c index bd896a35..a71c95f6 100644 --- a/ccan/tdb2/lock.c +++ b/ccan/tdb2/lock.c @@ -30,7 +30,7 @@ #include /* If we were threaded, we could wait for unlock, but we're not, so fail. */ -static enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call) +enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call) { return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, "%s: lock owned by another tdb in this process.", @@ -38,8 +38,7 @@ static enum TDB_ERROR owner_conflict(struct tdb_context *tdb, const char *call) } /* If we fork, we no longer really own locks. */ -static bool check_lock_pid(struct tdb_context *tdb, - const char *call, bool log) +bool check_lock_pid(struct tdb_context *tdb, const char *call, bool log) { /* No locks? No problem! */ if (tdb->file->allrecord_lock.count == 0 @@ -416,7 +415,7 @@ enum TDB_ERROR tdb_nest_lock(struct tdb_context *tdb, tdb_brunlock(tdb, ltype, offset, 1); if (berr < 0) - return berr; + return TDB_OFF_TO_ERR(berr); ecode = tdb_lock_and_recover(tdb); if (ecode == TDB_SUCCESS) { ecode = tdb_brlock(tdb, ltype, offset, 1, @@ -534,6 +533,12 @@ enum TDB_ERROR tdb_allrecord_lock(struct tdb_context *tdb, int ltype, enum TDB_ERROR ecode; tdb_bool_err berr; + if (tdb->flags & TDB_VERSION1) { + if (tdb1_allrecord_lock(tdb, ltype, flags, upgradable) == -1) + return tdb->last_error; + return TDB_SUCCESS; + } + if (tdb->flags & TDB_NOLOCK) return TDB_SUCCESS; @@ -608,7 +613,7 @@ again: tdb_allrecord_unlock(tdb, ltype); if (berr < 0) - return berr; + return TDB_OFF_TO_ERR(berr); ecode = tdb_lock_and_recover(tdb); if (ecode != TDB_SUCCESS) { return ecode; @@ -648,6 +653,11 @@ void tdb_unlock_expand(struct tdb_context *tdb, int ltype) /* unlock entire db */ void tdb_allrecord_unlock(struct tdb_context *tdb, int ltype) { + if (tdb->flags & TDB_VERSION1) { + tdb1_allrecord_unlock(tdb, ltype); + return; + } + if (tdb->flags & TDB_NOLOCK) return; @@ -776,6 +786,11 @@ enum TDB_ERROR tdb_unlock_hashes(struct tdb_context *tdb, return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, "tdb_unlock_hashes RO allrecord!"); } + if (tdb->file->allrecord_lock.owner != tdb) { + return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_USE_ERROR, + "tdb_unlock_hashes:" + " not locked by us!"); + } return TDB_SUCCESS; } @@ -806,6 +821,10 @@ enum TDB_ERROR tdb_lock_free_bucket(struct tdb_context *tdb, tdb_off_t b_off, if (!check_lock_pid(tdb, "tdb_lock_free_bucket", true)) return TDB_ERR_LOCK; + if (tdb->file->allrecord_lock.owner != tdb) { + return owner_conflict(tdb, "tdb_lock_free_bucket"); + } + if (tdb->file->allrecord_lock.ltype == F_WRLCK) return 0; return tdb_logerr(tdb, TDB_ERR_LOCK, TDB_LOG_ERROR, @@ -862,12 +881,7 @@ void tdb_lock_cleanup(struct tdb_context *tdb) while (tdb->file->allrecord_lock.count && tdb->file->allrecord_lock.owner == tdb) { - if (tdb->flags & TDB_VERSION1) - tdb1_allrecord_unlock(tdb, - tdb->file->allrecord_lock.ltype); - else - tdb_allrecord_unlock(tdb, - tdb->file->allrecord_lock.ltype); + tdb_allrecord_unlock(tdb, tdb->file->allrecord_lock.ltype); } for (i=0; ifile->num_lockrecs; i++) {