mirror of
https://github.com/samba-team/samba.git
synced 2025-03-08 04:58:40 +03:00
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)
This commit is contained in:
parent
5837031ee2
commit
d96f052603
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user