diff options
author | Jeremy Allison <jra@samba.org> | 2001-10-16 22:10:23 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2001-10-16 22:10:23 +0000 |
commit | 21f776df5932e024a0d1fef9097377d35b5cf511 (patch) | |
tree | 43117355ee5d305861a4e6f18712cf433029bc7b /source/tdb/tdb.c | |
parent | 810272fe44e71706db4379a03c9f3766cfce3a68 (diff) | |
download | samba-21f776df5932e024a0d1fef9097377d35b5cf511.tar.gz samba-21f776df5932e024a0d1fef9097377d35b5cf511.tar.xz samba-21f776df5932e024a0d1fef9097377d35b5cf511.zip |
Don't core dump when using spinlocks on a read-only tdb. Unfortunately this
means that a read-write opener and a read-only opener are using different
locking mechanisms - this needs to be addressed, but it's hard as the
read-write opener using the spinlocks is usually first, so there's no
way to force them to change down to the fcntl method.
Read only access is less important anyway and can never corrupt the
tdb anyway, so errors in read-only record reads are more tolerable.
Jeremy
Diffstat (limited to 'source/tdb/tdb.c')
-rw-r--r-- | source/tdb/tdb.c | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/source/tdb/tdb.c b/source/tdb/tdb.c index 27671580461..d7cd277283a 100644 --- a/source/tdb/tdb.c +++ b/source/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; } |