Ok - this is more subtle than it looks :-).
authorJeremy Allison <jra@samba.org>
Thu, 27 Apr 2000 23:28:56 +0000 (23:28 +0000)
committerJeremy Allison <jra@samba.org>
Thu, 27 Apr 2000 23:28:56 +0000 (23:28 +0000)
When a file is being closed, once it passes the fnum and tid tests then
the locking context should be ignored when removing all locks. This is
what is done in the brl close case, but when you have outstanding
POSIX locks, then you cannot remove all the brl locks in one go, you
have to get the lock list and call do_unlock individually. As this
uses global_smbpid as the locking context, you need to make sure
that this is set correctly for the specific lock being removed. I
now do this by storing the smbpid in each entry in the unlock list returned from
the query call. I removed the smbpid from fsp (not needed) and
things seem ok (even with the stupid smbpid tricks that smbtorture plays :-).

Jeremy.
(This used to be commit 6baa96bb466915cc17e8cbad50254d6bd47b967b)

source3/include/smb.h
source3/locking/brlock.c
source3/locking/locking.c
source3/smbd/open.c
source3/smbd/process.c

index e4415e7d220c8998dbe51fae5eec8500fde33563..78d17aaa3d4bf91ef622339c249de559e99a87ec 100644 (file)
@@ -482,7 +482,6 @@ typedef struct files_struct
        SMB_OFF_T size;
        mode_t mode;
        uint16 vuid;
-       int smbpid;
        write_bmpx_struct *wbmpx_ptr;
        write_cache *wcp;
        struct timeval open_time;
@@ -527,6 +526,7 @@ struct unlock_list {
        struct unlock_list *prev;
        SMB_BIG_UINT start;
        SMB_BIG_UINT size;
+       uint16 smbpid;
 };
 
 typedef struct
index ed1f73df5ed202625b5cac81e28084a13226e3e1..410fb3fc0bdea667a02e7eb25bed82a7aa437e74 100644 (file)
@@ -367,6 +367,7 @@ BECOMES.....
                                ZERO_STRUCTP(ul_new);
                                ul_new->start = lock->start + lock->size;
                                ul_new->size = ul_curr->start + ul_curr->size - ul_new->start;
+                               ul_new->smbpid = ul_curr->smbpid;
 
                                /* Add into the dlink list after the ul_curr point - NOT at ulhead. */
                                DLIST_ADD(ul_curr, ul_new);
@@ -638,6 +639,7 @@ struct unlock_list *brl_getlocklist( TALLOC_CTX *ctx, SMB_DEV_T dev, SMB_INO_T i
                                ZERO_STRUCTP(ul_new);
                                ul_new->start = lock->start;
                                ul_new->size = lock->size;
+                               ul_new->smbpid = lock->context.smbpid;
 
                                DLIST_ADD(ulist, ul_new);
                }
index b6b34138e369e22059d17cbfd9fdc22e9b75f34a..088693b6d422637b148423de9a46e112f8963b00 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "includes.h"
 extern int DEBUGLEVEL;
+int global_smbpid;
 
 /* the locking database handle */
 static TDB_CONTEXT *tdb;
@@ -567,7 +568,7 @@ BOOL is_locked(files_struct *fsp,connection_struct *conn,
                return(False);
 
        ret = !brl_locktest(fsp->dev, fsp->inode, 
-                            fsp->smbpid, getpid(), conn->cnum, 
+                            global_smbpid, getpid(), conn->cnum, 
                             offset, count, lock_type);
 
        /*
@@ -605,7 +606,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
 
        if (OPEN_FSP(fsp) && fsp->can_lock && (fsp->conn == conn)) {
                ok = brl_lock(fsp->dev, fsp->inode, fsp->fnum,
-                             fsp->smbpid, getpid(), conn->cnum, 
+                             global_smbpid, getpid(), conn->cnum, 
                              offset, count, 
                              lock_type);
 
@@ -625,7 +626,7 @@ BOOL do_lock(files_struct *fsp,connection_struct *conn,
                                 * lock entry.
                                 */
                                (void)brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
-                                                               fsp->smbpid, getpid(), conn->cnum, 
+                                                               global_smbpid, getpid(), conn->cnum, 
                                                                offset, count);
                        }
                }
@@ -674,7 +675,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
        pid = getpid();
 
        ok = brl_unlock(fsp->dev, fsp->inode, fsp->fnum,
-                       fsp->smbpid, pid, conn->cnum, offset, count);
+                       global_smbpid, pid, conn->cnum, offset, count);
    
        if (!ok) {
                DEBUG(10,("do_unlock: returning ERRlock.\n" ));
@@ -705,6 +706,7 @@ BOOL do_unlock(files_struct *fsp,connection_struct *conn,
        ZERO_STRUCTP(ul);
        ul->start = offset;
        ul->size = count;
+       ul->smbpid = global_smbpid;
 
        DLIST_ADD(ulist, ul);
 
@@ -770,12 +772,16 @@ void locking_close_file(files_struct *fsp)
 
                /*
                 * Now unlock all of them. This will remove the brl entry also
-                * for each lock.
+                * for each lock. Note we need to make sure the global_smbpid matches
+                * the one associated with each lock in case the client plays games
+                * with smbpids (like smbtorture does :-).
                 */
 
-               for(; ul; ul = ul->next)
+               for(; ul; ul = ul->next) {
+                       global_smbpid = ul->smbpid;
                        do_unlock(fsp,fsp->conn,ul->size,ul->start,&eclass,&ecode);
-               
+               }
+       
                talloc_destroy(ul_ctx);
 
        } else {
index 92bba76619af28e48a555043995109ec1da1f3ff..737b9b5ef3684f62d259db377ab59abe4915888b 100644 (file)
@@ -26,7 +26,6 @@ extern int DEBUGLEVEL;
 extern pstring sesssetup_user;
 extern uint16 global_oplock_port;
 extern BOOL global_client_failed_oplock_break;
-extern int global_smbpid;
 
 /****************************************************************************
  fd support routines - attempt to do a dos_open.
@@ -165,7 +164,6 @@ static BOOL open_file(files_struct *fsp,connection_struct *conn,
        fsp->dev = sbuf.st_dev;
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
-       fsp->smbpid = global_smbpid;
        fsp->size = 0;
        fsp->pos = -1;
        fsp->can_lock = True;
@@ -799,7 +797,6 @@ files_struct *open_file_stat(connection_struct *conn,
        fsp->mode = 0;
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
-       fsp->smbpid = global_smbpid;
        fsp->size = 0;
        fsp->pos = -1;
        fsp->can_lock = False;
@@ -923,7 +920,6 @@ files_struct *open_directory(connection_struct *conn,
        fsp->mode = 0;
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
-       fsp->smbpid = global_smbpid;
        fsp->size = 0;
        fsp->pos = -1;
        fsp->can_lock = True;
index 77e6fc2aa794413c99cab2090531ee89d150696c..f37855028295f4f836720333914f0ad8477c1529 100644 (file)
@@ -28,7 +28,6 @@ struct timeval smb_last_time;
 static char *InBuffer = NULL;
 char *OutBuffer = NULL;
 char *last_inbuf = NULL;
-int global_smbpid;
 
 /* 
  * Size of data we can send to client. Set
@@ -419,6 +418,7 @@ static int switch_message(int type,char *inbuf,char *outbuf,int size,int bufsize
   static int num_smb_messages = 
     sizeof(smb_messages) / sizeof(struct smb_message_struct);
   int match;
+  extern int global_smbpid;
 
   if (pid == (pid_t)-1)
     pid = getpid();