diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/tdb/tdb.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index 2767158046..d7cd277283 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -190,7 +190,7 @@ static int tdb_lock(TDB_CONTEXT *tdb, int list, int ltype) /* Since fcntl locks don't nest, we do a lock for the first one, and simply bump the count for future ones */ if (tdb->locked[list+1].count == 0) { - if (tdb->header.rwlocks) { + if (!tdb->read_only && tdb->header.rwlocks) { if (tdb_spinlock(tdb, list, ltype)) { TDB_LOG((tdb, 0, "tdb_lock spinlock on list ltype=%d\n", list, ltype)); @@ -221,7 +221,7 @@ static void tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) if (tdb->locked[list+1].count == 1) { /* Down to last nested lock: unlock underneath */ - if (tdb->header.rwlocks) + if (!tdb->read_only && tdb->header.rwlocks) tdb_spinunlock(tdb, list, ltype); else tdb_brlock(tdb, FREELIST_TOP+4*list, F_UNLCK, F_SETLKW, 0); @@ -1014,7 +1014,12 @@ static int lock_record(TDB_CONTEXT *tdb, tdb_off off) { return off ? tdb_brlock(tdb, off, F_RDLCK, F_SETLKW, 0) : 0; } -/* write locks override our own fcntl readlocks, so check it here */ +/* + Write locks override our own fcntl readlocks, so check it here. + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) { struct tdb_traverse_lock *i; @@ -1023,6 +1028,12 @@ static int write_lock_record(TDB_CONTEXT *tdb, tdb_off off) return -1; return tdb_brlock(tdb, off, F_WRLCK, F_SETLK, 1); } + +/* + Note this is meant to be F_SETLK, *not* F_SETLKW, as it's not + an error to fail to get the lock here. +*/ + static int write_unlock_record(TDB_CONTEXT *tdb, tdb_off off) { return tdb_brlock(tdb, off, F_UNLCK, F_SETLK, 0); @@ -1449,7 +1460,8 @@ TDB_CONTEXT *tdb_open(char *name, int hash_size, int tdb_flags, goto fail; tdb_mmap(&tdb); if (locked) { - tdb_clear_spinlocks(&tdb); + if (!tdb.read_only) + tdb_clear_spinlocks(&tdb); if (tdb_brlock(&tdb, ACTIVE_LOCK, F_UNLCK, F_SETLK, 0) == -1) goto fail; } |