summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-10-16 22:10:23 +0000
committerJeremy Allison <jra@samba.org>2001-10-16 22:10:23 +0000
commitd96f052603383d99fecfab41291b3957529f4f6c (patch)
tree4db84104cc834b36be25ca5ff63502f7ae873b4a /source3/tdb
parent5837031ee272f8ef02d3e4c11600c42f5cea9ab7 (diff)
downloadsamba-d96f052603383d99fecfab41291b3957529f4f6c.tar.gz
samba-d96f052603383d99fecfab41291b3957529f4f6c.tar.bz2
samba-d96f052603383d99fecfab41291b3957529f4f6c.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 (This used to be commit 21f776df5932e024a0d1fef9097377d35b5cf511)
Diffstat (limited to 'source3/tdb')
-rw-r--r--source3/tdb/tdb.c20
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;
}