r23014: For all branches, ensure that if we're blocked on a POSIX
authorJeremy Allison <jra@samba.org>
Sat, 19 May 2007 20:57:12 +0000 (20:57 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 17:22:15 +0000 (12:22 -0500)
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.

source/locking/brlock.c
source/locking/locking.c
source/smbd/blocking.c
source/smbd/reply.c
source/smbd/trans2.c

index d48c746161daf181bba70c37da641debeabce626..f3e4042d8a99cc49fb0b1599078733faf4e4a122 100644 (file)
@@ -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;
 }
 
index 28a7fab97d3fd2c0a30fc783adba92df404b77c2..56ff3b979036fe43c7a282fce8619c66b448039b 100644 (file)
@@ -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
index ae7b861f2b00924b464f21dab0af952e7bddf24e..43b2633b9af7cf92891d59c5a3f7d71dabef1096 100644 (file)
@@ -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)) {
index c71c7b8beaedbe26244d6d472b4df32f4fc84b82..ec110e7b213c1ad9b97d961692b0a8bde2da44b9 100644 (file)
@@ -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;
index 0730041899f95013478b2c74fe20dbeb2ae6916e..63fd414e16f5155e2d8dd72fc85280102e1f1b97 100644 (file)
@@ -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;
                        }