From 58974024c18314e99633516a8cf953980a8862e8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 26 May 2017 11:35:52 +0200 Subject: [PATCH 1/2] s3/locking: make find_share_mode_entry public BUG: https://bugzilla.samba.org/show_bug.cgi?id=12798 Signed-off-by: Ralph Boehme Reviewed-by: Stefan Metzmacher --- source3/locking/locking.c | 2 +- source3/locking/proto.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 51c1640..037a987 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -859,7 +859,7 @@ bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, return true; } -static struct share_mode_entry *find_share_mode_entry( +struct share_mode_entry *find_share_mode_entry( struct share_mode_lock *lck, files_struct *fsp) { struct share_mode_data *d = lck->data; diff --git a/source3/locking/proto.h b/source3/locking/proto.h index 5d2326a..6fb2bf2 100644 --- a/source3/locking/proto.h +++ b/source3/locking/proto.h @@ -176,6 +176,8 @@ bool share_mode_stale_pid(struct share_mode_data *d, uint32_t idx); bool set_share_mode(struct share_mode_lock *lck, struct files_struct *fsp, uid_t uid, uint64_t mid, uint16_t op_type, uint32_t lease_idx); +struct share_mode_entry *find_share_mode_entry(struct share_mode_lock *lck, + files_struct *fsp); void remove_stale_share_mode_entries(struct share_mode_data *d); bool del_share_mode(struct share_mode_lock *lck, files_struct *fsp); bool mark_share_mode_disconnected(struct share_mode_lock *lck, -- 2.9.3 From f87f2ff251878063dbe5ff66bba65e6a09ba6ce8 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Fri, 26 May 2017 11:57:08 +0200 Subject: [PATCH 2/2] s3/smbd: fix exclusive lease optimisation 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 client 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 Signed-off-by: Ralph Boehme Signed-off-by: Stefan Metzmacher --- source3/smbd/oplock.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index aa060ad..1b2a87b 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -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; inum_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; } -- 2.9.3