summaryrefslogtreecommitdiff
path: root/source3/locking
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2006-07-18 01:05:51 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:38:12 -0500
commitb737f26764cce935d9482335ece11c71a96720f4 (patch)
treee2d21c8b53815c90092437b2c4dc14bf5b34e560 /source3/locking
parent94ad8543bd27c6cbdcdaf4acf84d91438dbef28b (diff)
downloadsamba-b737f26764cce935d9482335ece11c71a96720f4.tar.gz
samba-b737f26764cce935d9482335ece11c71a96720f4.tar.bz2
samba-b737f26764cce935d9482335ece11c71a96720f4.zip
r17105: Fix the race Volker found - we had a non-locked
region between detecting a pending lock was needed and when we added the blocking lock record. Make sure that we hold the lock over all this period. Removed the old code for doing blocking locks on SMB requests that never block (the old SMBlock and friends). Discovered something interesting about the strange NT_STATUS_FILE_LOCK_CONFLICT return. If we asked for a lock with zero timeout, and we got an error of NT_STATUS_FILE_LOCK_CONFLICT, treat it as though it was a blocking lock with a timeout of 150 - 300ms. This only happens when timeout is sent as zero and can be seen quite clearly in ethereal. This is the real replacement for old do_lock_spin() code. Re-worked the blocking lock select timeout to correctly use milliseconds instead of the old second level resolution (far too coarse for this work). Jeremy. (This used to be commit b81d6d1ae95a3d3e449dde629884b565eac289d9)
Diffstat (limited to 'source3/locking')
-rw-r--r--source3/locking/brlock.c14
-rw-r--r--source3/locking/locking.c22
2 files changed, 19 insertions, 17 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index f251ff57ec..20bb4314b6 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -216,14 +216,14 @@ static BOOL brl_conflict_other(const struct lock_struct *lck1, const struct lock
app depends on this ?
****************************************************************************/
-static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, int32 lock_timeout)
+static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *lock, BOOL blocking_lock)
{
if (lock->start >= 0xEF000000 && (lock->start >> 63) == 0) {
/* amazing the little things you learn with a test
suite. Locks beyond this offset (as a 64 bit
number!) always generate the conflict error code,
unless the top bit is set */
- if (lock_timeout == 0) {
+ if (!blocking_lock) {
fsp->last_lock_failure = *lock;
}
return NT_STATUS_FILE_LOCK_CONFLICT;
@@ -236,7 +236,7 @@ static NTSTATUS brl_lock_failed(files_struct *fsp, const struct lock_struct *loc
return NT_STATUS_FILE_LOCK_CONFLICT;
}
- if (lock_timeout == 0) {
+ if (!blocking_lock) {
fsp->last_lock_failure = *lock;
}
return NT_STATUS_LOCK_NOT_GRANTED;
@@ -297,7 +297,7 @@ static int lock_compare(const struct lock_struct *lck1,
****************************************************************************/
static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
- const struct lock_struct *plock, int32 lock_timeout)
+ const struct lock_struct *plock, BOOL blocking_lock)
{
unsigned int i;
files_struct *fsp = br_lck->fsp;
@@ -306,7 +306,7 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
for (i=0; i < br_lck->num_locks; i++) {
/* Do any Windows or POSIX locks conflict ? */
if (brl_conflict(&locks[i], plock)) {
- return brl_lock_failed(fsp,plock,lock_timeout);
+ return brl_lock_failed(fsp,plock,blocking_lock);
}
#if ZERO_ZERO
if (plock->start == 0 && plock->size == 0 &&
@@ -676,7 +676,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- int32 lock_timeout)
+ BOOL blocking_lock)
{
NTSTATUS ret;
struct lock_struct lock;
@@ -697,7 +697,7 @@ NTSTATUS brl_lock(struct byte_range_lock *br_lck,
lock.lock_flav = lock_flav;
if (lock_flav == WINDOWS_LOCK) {
- ret = brl_lock_windows(br_lck, &lock, lock_timeout);
+ ret = brl_lock_windows(br_lck, &lock, blocking_lock);
} else {
ret = brl_lock_posix(br_lck, &lock);
}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index cd1d9547f3..a7cadd3a40 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -179,23 +179,25 @@ NTSTATUS query_lock(files_struct *fsp,
Utility function called by locking requests.
****************************************************************************/
-NTSTATUS do_lock(files_struct *fsp,
+struct byte_range_lock *do_lock(files_struct *fsp,
uint32 lock_pid,
SMB_BIG_UINT count,
SMB_BIG_UINT offset,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- int32 lock_timeout)
+ BOOL blocking_lock,
+ NTSTATUS *perr)
{
struct byte_range_lock *br_lck = NULL;
- NTSTATUS status = NT_STATUS_LOCK_NOT_GRANTED;
if (!fsp->can_lock) {
- return fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
+ *perr = fsp->is_directory ? NT_STATUS_INVALID_DEVICE_REQUEST : NT_STATUS_INVALID_HANDLE;
+ return NULL;
}
if (!lp_locking(SNUM(fsp->conn))) {
- return NT_STATUS_OK;
+ *perr = NT_STATUS_OK;
+ return NULL;
}
/* NOTE! 0 byte long ranges ARE allowed and should be stored */
@@ -206,20 +208,20 @@ NTSTATUS do_lock(files_struct *fsp,
br_lck = brl_get_locks(NULL, fsp);
if (!br_lck) {
- return NT_STATUS_NO_MEMORY;
+ *perr = NT_STATUS_NO_MEMORY;
+ return NULL;
}
- status = brl_lock(br_lck,
+ *perr = brl_lock(br_lck,
lock_pid,
procid_self(),
offset,
count,
lock_type,
lock_flav,
- lock_timeout);
+ blocking_lock);
- TALLOC_FREE(br_lck);
- return status;
+ return br_lck;
}
/****************************************************************************