Fix bug #7928 - Samba problems with kernel oplocks option set to "no"
authorPavel Shilovsky <piastry@etersoft.ru>
Mon, 31 Jan 2011 20:00:15 +0000 (12:00 -0800)
committerJeremy Allison <jra@samba.org>
Mon, 31 Jan 2011 20:00:15 +0000 (12:00 -0800)
We should not grant levelII oplocks on a file with existing
byte range locks.

source3/smbd/open.c
source3/smbd/oplock.c

index 0de70451daa7a66d6ad6e695a6642ca13b60bfbc..5a725c66341aafaf4f119597a70307e133ce97da 100644 (file)
@@ -2182,7 +2182,10 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
         */
 
        if (!set_file_oplock(fsp, fsp->oplock_type)) {
-               /* Could not get the kernel oplock */
+               /*
+                * Could not get the kernel oplock or there are byte-range
+                * locks on the file.
+                */
                fsp->oplock_type = NO_OPLOCK;
        }
 
index e92fbd43af1ad5c66a6cbb9bc9fc48598a56d283..31cedc415e3800a6efabf398e215ab4491656925 100644 (file)
@@ -52,19 +52,40 @@ void break_kernel_oplock(struct messaging_context *msg_ctx, files_struct *fsp)
                           msg, MSG_SMB_KERNEL_BREAK_SIZE);
 }
 
+static bool file_has_brlocks(files_struct *fsp)
+{
+       struct byte_range_lock *br_lck;
+
+       br_lck = brl_get_locks_readonly(fsp);
+       if (!br_lck)
+               return false;
+
+       return br_lck->num_locks > 0 ? true : false;
+}
+
 /****************************************************************************
- Attempt to set an oplock on a file. Always succeeds if kernel oplocks are
- disabled (just sets flags). Returns True if oplock set.
+ Attempt to set an oplock on a file. Succeeds if kernel oplocks are
+ disabled (just sets flags) and no byte-range locks in the file. Returns True
+ if oplock set.
 ****************************************************************************/
 
 bool set_file_oplock(files_struct *fsp, int oplock_type)
 {
-       if ((fsp->oplock_type == LEVEL_II_OPLOCK)
-           && koplocks && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
-               DEBUG(10, ("Refusing level2 oplock, kernel oplocks don't "
-                          "support them\n"));
-               return false;
+       if (fsp->oplock_type == LEVEL_II_OPLOCK) {
+               if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
+                       DEBUG(10, ("Refusing level2 oplock because of "
+                                  "byte-range locks on the file\n"));
+                       return false;
+               }
+
+               if (koplocks &&
+                   !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) {
+                       DEBUG(10, ("Refusing level2 oplock, kernel oplocks "
+                                  "don't support them\n"));
+                       return false;
+               }
        }
+
        if ((fsp->oplock_type != NO_OPLOCK) &&
            (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK) &&
            koplocks &&