summaryrefslogtreecommitdiff
path: root/source3
diff options
context:
space:
mode:
Diffstat (limited to 'source3')
-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;
}