From 49c1b2e371c2fa6c3e74cee8d8222d161454ffe4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 23 Nov 2010 12:07:29 +1030 Subject: [PATCH] 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. --- ccan/tdb2/lock.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) 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; } -- 2.39.2