summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-05-19 20:57:12 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:22:15 -0500
commit01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b (patch)
tree461916086f30ca61c6bed9c439a8d96808bd3d8b
parentfa4df182e5777f534edd327446f5b1d1e79c6133 (diff)
downloadsamba-01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b.tar.gz
samba-01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b.tar.bz2
samba-01a7017d7b0e0cbc3b0923c43b7fe3f0b01aac0b.zip
r23014: For all branches, ensure that if we're blocked on a POSIX
lock we know nothing about that we retry the lock every 10 seconds instead of waiting for the standard select timeout. This is how we used to (and are supposed to) work. Jeremy. (This used to be commit fa18fc25a50cf13c687ae88e7e5e2dda1120e017)
-rw-r--r--source3/locking/brlock.c25
-rw-r--r--source3/locking/locking.c6
-rw-r--r--source3/smbd/blocking.c25
-rw-r--r--source3/smbd/reply.c13
-rw-r--r--source3/smbd/trans2.c8
5 files changed, 62 insertions, 15 deletions
diff --git a/source3/locking/brlock.c b/source3/locking/brlock.c
index d48c746161..f3e4042d8a 100644
--- a/source3/locking/brlock.c
+++ b/source3/locking/brlock.c
@@ -313,7 +313,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, BOOL blocking_lock)
+ struct lock_struct *plock, BOOL blocking_lock)
{
unsigned int i;
files_struct *fsp = br_lck->fsp;
@@ -322,6 +322,8 @@ 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)) {
+ /* Remember who blocked us. */
+ plock->context.smbpid = locks[i].context.smbpid;
return brl_lock_failed(fsp,plock,blocking_lock);
}
#if ZERO_ZERO
@@ -346,6 +348,10 @@ static NTSTATUS brl_lock_windows(struct byte_range_lock *br_lck,
locks,
br_lck->num_locks,
&errno_ret)) {
+
+ /* We don't know who blocked us. */
+ plock->context.smbpid = 0xFFFFFFFF;
+
if (errno_ret == EACCES || errno_ret == EAGAIN) {
return NT_STATUS_FILE_LOCK_CONFLICT;
} else {
@@ -586,7 +592,7 @@ OR
static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
struct byte_range_lock *br_lck,
- const struct lock_struct *plock)
+ struct lock_struct *plock)
{
unsigned int i, count;
struct lock_struct *locks = br_lck->lock_data;
@@ -630,6 +636,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
if (brl_conflict(curr_lock, plock)) {
/* No games with error messages. */
SAFE_FREE(tp);
+ /* Remember who blocked us. */
+ plock->context.smbpid = curr_lock->context.smbpid;
return NT_STATUS_FILE_LOCK_CONFLICT;
}
/* Just copy the Windows lock into the new array. */
@@ -641,6 +649,8 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
/* Can't block ourselves with POSIX locks. */
/* No games with error messages. */
SAFE_FREE(tp);
+ /* Remember who blocked us. */
+ plock->context.smbpid = curr_lock->context.smbpid;
return NT_STATUS_FILE_LOCK_CONFLICT;
}
@@ -670,6 +680,10 @@ static NTSTATUS brl_lock_posix(struct messaging_context *msg_ctx,
plock->size,
plock->lock_type,
&errno_ret)) {
+
+ /* We don't know who blocked us. */
+ plock->context.smbpid = 0xFFFFFFFF;
+
if (errno_ret == EACCES || errno_ret == EAGAIN) {
SAFE_FREE(tp);
return NT_STATUS_FILE_LOCK_CONFLICT;
@@ -730,7 +744,8 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx,
br_off size,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- BOOL blocking_lock)
+ BOOL blocking_lock,
+ uint32 *psmbpid)
{
NTSTATUS ret;
struct lock_struct lock;
@@ -761,6 +776,10 @@ NTSTATUS brl_lock(struct messaging_context *msg_ctx,
qsort(br_lck->lock_data, (size_t)br_lck->num_locks, sizeof(lock), lock_compare);
#endif
+ /* If we're returning an error, return who blocked us. */
+ if (!NT_STATUS_IS_OK(ret) && psmbpid) {
+ *psmbpid = lock.context.smbpid;
+ }
return ret;
}
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 28a7fab97d..56ff3b9790 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -188,7 +188,8 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
enum brl_type lock_type,
enum brl_flavour lock_flav,
BOOL blocking_lock,
- NTSTATUS *perr)
+ NTSTATUS *perr,
+ uint32 *plock_pid)
{
struct byte_range_lock *br_lck = NULL;
@@ -222,7 +223,8 @@ struct byte_range_lock *do_lock(struct messaging_context *msg_ctx,
count,
lock_type,
lock_flav,
- blocking_lock);
+ blocking_lock,
+ plock_pid);
/* blocking ie. pending, locks also count here,
* as this is an efficiency counter to avoid checking
diff --git a/source3/smbd/blocking.c b/source3/smbd/blocking.c
index ae7b861f2b..43b2633b9a 100644
--- a/source3/smbd/blocking.c
+++ b/source3/smbd/blocking.c
@@ -39,6 +39,7 @@ typedef struct _blocking_lock_record {
SMB_BIG_UINT offset;
SMB_BIG_UINT count;
uint32 lock_pid;
+ uint32 blocking_pid; /* PID that blocks us. */
enum brl_flavour lock_flav;
enum brl_type lock_type;
char *inbuf;
@@ -108,6 +109,16 @@ static BOOL recalc_brl_timeout(void)
for (brl = blocking_lock_queue; brl; brl = brl->next) {
if (timeval_is_zero(&brl->expire_time)) {
+ /*
+ * If we're blocked on pid 0xFFFFFFFF this is
+ * a POSIX lock, so calculate a timeout of
+ * 10 seconds into the future.
+ */
+ if (brl->blocking_pid == 0xFFFFFFFF) {
+ struct timeval psx_to = timeval_current_ofs(10, 0);
+ next_timeout = timeval_min(&next_timeout, &psx_to);
+ }
+
continue;
}
@@ -146,7 +157,9 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
uint32 lock_pid,
enum brl_type lock_type,
enum brl_flavour lock_flav,
- SMB_BIG_UINT offset, SMB_BIG_UINT count)
+ SMB_BIG_UINT offset,
+ SMB_BIG_UINT count,
+ uint32 blocking_pid)
{
static BOOL set_lock_msg;
blocking_lock_record *blr;
@@ -187,6 +200,7 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
}
blr->lock_num = lock_num;
blr->lock_pid = lock_pid;
+ blr->blocking_pid = blocking_pid;
blr->lock_flav = lock_flav;
blr->lock_type = lock_type;
blr->offset = offset;
@@ -202,7 +216,8 @@ BOOL push_blocking_lock_request( struct byte_range_lock *br_lck,
count,
lock_type == READ_LOCK ? PENDING_READ_LOCK : PENDING_WRITE_LOCK,
blr->lock_flav,
- lock_timeout ? True : False); /* blocking_lock. */
+ lock_timeout ? True : False, /* blocking_lock. */
+ NULL);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("push_blocking_lock_request: failed to add PENDING_LOCK record.\n"));
@@ -445,7 +460,8 @@ static BOOL process_lockingX(blocking_lock_record *blr)
READ_LOCK : WRITE_LOCK),
WINDOWS_LOCK,
True,
- &status);
+ &status,
+ &blr->blocking_pid);
TALLOC_FREE(br_lck);
@@ -506,7 +522,8 @@ static BOOL process_trans2(blocking_lock_record *blr)
blr->lock_type,
blr->lock_flav,
True,
- &status);
+ &status,
+ &blr->blocking_pid);
TALLOC_FREE(br_lck);
if (!NT_STATUS_IS_OK(status)) {
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index c71c7b8bea..ec110e7b21 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -2426,7 +2426,8 @@ int reply_lockread(connection_struct *conn, char *inbuf,char *outbuf, int length
WRITE_LOCK,
WINDOWS_LOCK,
False, /* Non-blocking lock. */
- &status);
+ &status,
+ NULL);
TALLOC_FREE(br_lck);
if (NT_STATUS_V(status)) {
@@ -3474,7 +3475,8 @@ int reply_lock(connection_struct *conn,
WRITE_LOCK,
WINDOWS_LOCK,
False, /* Non-blocking lock. */
- &status);
+ &status,
+ NULL);
TALLOC_FREE(br_lck);
@@ -5575,6 +5577,7 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
BOOL blocking_lock = lock_timeout ? True : False;
BOOL defer_lock = False;
struct byte_range_lock *br_lck;
+ uint32 block_smbpid;
br_lck = do_lock(smbd_messaging_context(),
fsp,
@@ -5584,7 +5587,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
lock_type,
WINDOWS_LOCK,
blocking_lock,
- &status);
+ &status,
+ &block_smbpid);
if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/* Windows internal resolution for blocking locks seems
@@ -5621,7 +5625,8 @@ int reply_lockingX(connection_struct *conn, char *inbuf, char *outbuf,
lock_type,
WINDOWS_LOCK,
offset,
- count)) {
+ count,
+ block_smbpid)) {
TALLOC_FREE(br_lck);
END_PROFILE(SMBlockingX);
return -1;
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index 0730041899..63fd414e16 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -4815,6 +4815,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
offset,
POSIX_LOCK);
} else {
+ uint32 block_smbpid;
+
struct byte_range_lock *br_lck = do_lock(smbd_messaging_context(),
fsp,
lock_pid,
@@ -4823,7 +4825,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
lock_type,
POSIX_LOCK,
blocking_lock,
- &status);
+ &status,
+ &block_smbpid);
if (br_lck && blocking_lock && ERROR_WAS_LOCK_DENIED(status)) {
/*
@@ -4840,7 +4843,8 @@ static NTSTATUS smb_set_posix_lock(connection_struct *conn,
lock_type,
POSIX_LOCK,
offset,
- count)) {
+ count,
+ block_smbpid)) {
TALLOC_FREE(br_lck);
return status;
}