From: Rusty Russell Date: Tue, 23 Nov 2010 01:37:29 +0000 (+1030) Subject: tdb2: allow nesting of read locks on top of write locks. X-Git-Url: https://git.ozlabs.org/?p=ccan;a=commitdiff_plain;h=49c1b2e371c2fa6c3e74cee8d8222d161454ffe4;hp=dde924399b8e16de3e2426af8a44b4fde95c5f48 tdb2: allow nesting of read locks on top of write locks. If we have a write lock and ask for a read lock, that's OK, but not the other way around. tdb_nest_lock() allowed both, tdb_allrecord_lock() allowed neither. --- diff --git a/ccan/tdb2/lock.c b/ccan/tdb2/lock.c index 5d13a23a..60ed4637 100644 --- a/ccan/tdb2/lock.c +++ b/ccan/tdb2/lock.c @@ -270,10 +270,14 @@ static int tdb_nest_lock(struct tdb_context *tdb, tdb_off_t offset, int ltype, new_lck = find_nestlock(tdb, offset); if (new_lck) { - /* - * Just increment the in-memory struct, posix locks - * don't stack. - */ + if (new_lck->ltype == F_RDLCK && ltype == F_WRLCK) { + tdb->ecode = TDB_ERR_LOCK; + tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv, + "tdb_nest_lock: offset %llu has read lock\n", + (long long)offset); + return -1; + } + /* Just increment the struct, posix locks don't stack. */ new_lck->count++; return 0; } @@ -454,7 +458,8 @@ int tdb_allrecord_lock(struct tdb_context *tdb, int ltype, return -1; } - if (tdb->allrecord_lock.count && tdb->allrecord_lock.ltype == ltype) { + if (tdb->allrecord_lock.count + && (ltype == F_RDLCK || tdb->allrecord_lock.ltype == F_WRLCK)) { tdb->allrecord_lock.count++; return 0; }