summaryrefslogtreecommitdiff
path: root/source3/smbd/trans2.c
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/smbd/trans2.c
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/smbd/trans2.c')
-rw-r--r--source3/smbd/trans2.c32
1 files changed, 18 insertions, 14 deletions
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 199204684f..5acce13e52 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4503,7 +4503,7 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
SMB_BIG_UINT count;
SMB_BIG_UINT offset;
uint32 lock_pid;
- BOOL lock_blocking = False;
+ BOOL blocking_lock = False;
enum brl_type lock_type;
if (fsp == NULL || fsp->fh->fd == -1) {
@@ -4533,15 +4533,15 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
}
if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_NOWAIT) {
- lock_blocking = False;
+ blocking_lock = False;
} else if (SVAL(pdata,POSIX_LOCK_FLAGS_OFFSET) == POSIX_LOCK_FLAG_WAIT) {
- lock_blocking = True;
+ blocking_lock = True;
} else {
return ERROR_NT(NT_STATUS_INVALID_PARAMETER);
}
if (!lp_blocking_locks(SNUM(conn))) {
- lock_blocking = False;
+ blocking_lock = False;
}
lock_pid = IVAL(pdata, POSIX_LOCK_PID_OFFSET);
@@ -4562,21 +4562,23 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
offset,
POSIX_LOCK);
} else {
- status = do_lock(fsp,
- lock_pid,
- count,
- offset,
- lock_type,
- lock_blocking ? -1 : 0,
- POSIX_LOCK);
-
- if (lock_blocking && ERROR_WAS_LOCK_DENIED(status)) {
+ struct byte_range_lock *br_lck = do_lock(fsp,
+ lock_pid,
+ count,
+ offset,
+ lock_type,
+ blocking_lock,
+ POSIX_LOCK,
+ &status);
+
+ if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/*
* A blocking lock was requested. Package up
* this smb into a queued request and push it
* onto the blocking lock queue.
*/
- if(push_blocking_lock_request(inbuf, length,
+ if(push_blocking_lock_request(br_lck,
+ inbuf, length,
fsp,
-1, /* infinite timeout. */
0,
@@ -4585,9 +4587,11 @@ size = %.0f, uid = %u, gid = %u, raw perms = 0%o\n",
POSIX_LOCK,
offset,
count)) {
+ TALLOC_FREE(br_lck);
return -1;
}
}
+ TALLOC_FREE(br_lck);
}
if (!NT_STATUS_IS_OK(status)) {