diff options
author | Andrew Tridgell <tridge@samba.org> | 1997-10-27 12:02:34 +0000 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 1997-10-27 12:02:34 +0000 |
commit | ed71534df56d0296280dbde1859597fb42002088 (patch) | |
tree | 234a4c0bdba17add5e0f4f51693d1bb967e7783d | |
parent | 800a7218bcdf3ce57af0ce0428f96d42edc1d188 (diff) | |
download | samba-ed71534df56d0296280dbde1859597fb42002088.tar.gz |
Fixed 2 oplock bugs:
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
-rw-r--r-- | source/include/smb.h | 6 | ||||
-rw-r--r-- | source/smbd/reply.c | 28 |
2 files changed, 16 insertions, 18 deletions
diff --git a/source/include/smb.h b/source/include/smb.h index 1869020c0d1..7019d41de0d 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -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 diff --git a/source/smbd/reply.c b/source/smbd/reply.c index 22c22ccc556..f437ea564de 100644 --- a/source/smbd/reply.c +++ b/source/smbd/reply.c @@ -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 |