s3/smbd: fix exclusive lease optimisation
authorRalph Boehme <slow@samba.org>
Fri, 26 May 2017 09:57:08 +0000 (11:57 +0200)
committerRalph Boehme <slow@samba.org>
Sun, 28 May 2017 12:50:18 +0000 (14:50 +0200)
We need to expect any amount of "stat" opens on the file without
triggering an assert.

This is the correct fix for bug #11844. I guess we haven't seens this
very often before bug #12766 got fixed, because most clients were using
LEASES instead of OPLOCKS.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=12798

See also:
BUG: https://bugzilla.samba.org/show_bug.cgi?id=11844
BUG: https://bugzilla.samba.org/show_bug.cgi?id=12766

Pair-Programmed-With: Stefan Metzmacher <metze@samba.org>

Signed-off-by: Ralph Boehme <slow@samba.org>
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
source3/smbd/oplock.c

index aa060ad3747c2fc011798e2775966387154bb614..1b2a87b8d8a98ab8e1eafc3189edf9e3f31af94e 100644 (file)
@@ -26,6 +26,7 @@
 #include "smbd/globals.h"
 #include "messages.h"
 #include "../librpc/gen_ndr/open_files.h"
+#include "../librpc/gen_ndr/ndr_open_files.h"
 
 /*
  * helper function used by the kernel oplock backends to post the break message
@@ -167,17 +168,38 @@ bool update_num_read_oplocks(files_struct *fsp, struct share_mode_lock *lck)
        uint32_t i;
 
        if (fsp_lease_type_is_exclusive(fsp)) {
+               const struct share_mode_entry *e = NULL;
+               uint32_t e_lease_type = 0;
+
                /*
                 * If we're fully exclusive, we don't need a brlock entry
                 */
                remove_stale_share_mode_entries(d);
 
-               for (i=0; i<d->num_share_modes; i++) {
-                       struct share_mode_entry *e = &d->share_modes[i];
-                       uint32_t e_lease_type = get_lease_type(d, e);
+               e = find_share_mode_entry(lck, fsp);
+               if (e != NULL) {
+                       e_lease_type = get_lease_type(d, e);
+               }
+
+               if (!lease_type_is_exclusive(e_lease_type)) {
+                       char *timestr = NULL;
 
-                       SMB_ASSERT(lease_type_is_exclusive(e_lease_type));
+                       timestr = timeval_string(talloc_tos(),
+                                                &fsp->open_time,
+                                                true);
+
+                       NDR_PRINT_DEBUG(share_mode_data, d);
+                       DBG_ERR("file [%s] file_id [%s] gen_id [%lu] "
+                               "open_time[%s] lease_type [0x%x] "
+                               "oplock_type [0x%x]\n",
+                               fsp_str_dbg(fsp),
+                               file_id_string_tos(&fsp->file_id),
+                               fsp->fh->gen_id, timestr,
+                               e_lease_type, fsp->oplock_type);
+
+                       smb_panic("Found non-exclusive lease");
                }
+
                return true;
        }