Fixed 2 oplock bugs:
authorAndrew Tridgell <tridge@samba.org>
Mon, 27 Oct 1997 12:02:34 +0000 (12:02 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 27 Oct 1997 12:02:34 +0000 (12:02 +0000)
1) the oplock macros in smb.h used | where they should have used
&. This means that smbd thought that all clients were always
requesting oplocks. This would have _really_ confused smbclient
and smbfs when they started receiving async oplock break requests when
they don't even know what an oplock is!

2) an oplock break request from a client can be embedded in a normal
lockingX request, and will be if the client has batched any lock
requests internally. The smbd code assumed that all oplock break
requests had num_locks==num_ulocks==0 which is not true. The only
thing special about a oplock break request with
num_locks==num_ulocks==0 is that no reply is sent. Otherwise it is
processed as a normal locking request in addition to the oplock break
processing.

These two fixes get the MS mail system in Win98 working on a Samba
1.9.18 network drive.

Andrew

source/include/smb.h
source/smbd/reply.c

index 1869020c0d16befe041326ba0fea7b3429da8f8c..7019d41de0d43e5f56b060c2ecfac0ace1cbba41 100644 (file)
@@ -1804,14 +1804,12 @@ extern int unix_ERR_code;
 /*
  * Core protocol.
  */
-#define CORE_OPLOCK_REQUEST(inbuf) (((CVAL(inbuf,smb_flg)|(1<<5))>>5) | \
-                                    ((CVAL(inbuf,smb_flg)|(1<<6))>>5))
+#define CORE_OPLOCK_REQUEST(inbuf) ((CVAL(inbuf,smb_flg)&((1<<5)|(1<<6)))>>5)
 
 /*
  * Extended protocol.
  */
-#define EXTENDED_OPLOCK_REQUEST(inbuf) (((SVAL(inbuf,smb_vwv2)|(1<<1))>>1) | \
-                                        ((SVAL(inbuf,smb_vwv2)|(1<<2))>>1))
+#define EXTENDED_OPLOCK_REQUEST(inbuf) ((SVAL(inbuf,smb_vwv2)&((1<<1)|(1<<2)))>>1)
 
 /* Lock types. */
 #define LOCKING_ANDX_SHARED_LOCK 0x1
index 22c22ccc5567bb7c1842b7cb9b61fbb8c3b428bf..f437ea564dea83db9d217333f6c7044a6331154a 100644 (file)
@@ -3425,9 +3425,7 @@ int reply_lockingX(char *inbuf,char *outbuf,int length,int bufsize)
   /* Check if this is an oplock break on a file
      we have granted an oplock on.
    */
-  if((locktype == LOCKING_ANDX_OPLOCK_RELEASE) && 
-     (num_ulocks == 0) && (num_locks == 0) &&
-     (CVAL(inbuf,smb_vwv0) == 0xFF))
+  if ((locktype & LOCKING_ANDX_OPLOCK_RELEASE))
   {
     int token;
     files_struct *fsp = &Files[fnum];
@@ -3448,19 +3446,21 @@ no oplock granted on this file.\n", fnum));
 
     /* Remove the oplock flag from the sharemode. */
     lock_share_entry(fsp->cnum, dev, inode, &token);
-    if(remove_share_oplock( fnum, token)==False)
-    {
-      DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
-dev = %x, inode = %x\n", fnum, dev, inode));
-      unlock_share_entry(fsp->cnum, dev, inode, token);
-      return -1;
-    }
-    unlock_share_entry(fsp->cnum, dev, inode, token);
+    if(remove_share_oplock( fnum, token)==False) {
+           DEBUG(0,("reply_lockingX: failed to remove share oplock for fnum %d, \
+dev = %x, inode = %x\n", 
+                    fnum, dev, inode));
+           unlock_share_entry(fsp->cnum, dev, inode, token);
+    } else {
+           unlock_share_entry(fsp->cnum, dev, inode, token);
 
-    /* Clear the granted flag and return. */
+           /* Clear the granted flag and return. */
+           fsp->granted_oplock = False;
+    }
 
-    fsp->granted_oplock = False;
-    return -1;
+    /* if this is a pure oplock break request then don't send a reply */
+    if (num_locks == 0 && num_ulocks == 0)
+           return -1;
   }
 
   /* Data now points at the beginning of the list