From 96e2a82760ea06a89b7387b5cd3e864732afded3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Mon, 15 Aug 2022 22:45:17 +0200 Subject: [PATCH] s3:smbd: only clear LEASE_READ if there's no read lease is left If contend_level2_oplocks_begin_default() skips break it's own lease, we should not clear SHARE_MODE_LEASE_READ in share_mode_data->flags. Otherwise that lease won't see any lease break notifications for writes from other clients (file handles not using the same lease key). So we need to count the number existing read leases (including the one with the same lease key) in order to know it's safe to clear SMB2_LEASE_READ/SHARE_MODE_LEASE_READ. Otherwise the next run (likely from another client) will get the wrong result from file_has_read_lease(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=15148 Signed-off-by: Stefan Metzmacher Reviewed-by: Ralph Boehme Autobuild-User(master): Jeremy Allison Autobuild-Date(master): Thu Aug 18 19:41:33 UTC 2022 on sn-devel-184 --- selftest/knownfail.d/lease_bug_15148 | 2 -- source3/smbd/smb2_oplock.c | 11 ++++++----- 2 files changed, 6 insertions(+), 7 deletions(-) delete mode 100644 selftest/knownfail.d/lease_bug_15148 diff --git a/selftest/knownfail.d/lease_bug_15148 b/selftest/knownfail.d/lease_bug_15148 deleted file mode 100644 index e06a3d1b030..00000000000 --- a/selftest/knownfail.d/lease_bug_15148 +++ /dev/null @@ -1,2 +0,0 @@ -^samba3.smb2.lease.v1_bug15148 -^samba3.smb2.lease.v2_bug15148 diff --git a/source3/smbd/smb2_oplock.c b/source3/smbd/smb2_oplock.c index a555d3ae4fe..1f143840b34 100644 --- a/source3/smbd/smb2_oplock.c +++ b/source3/smbd/smb2_oplock.c @@ -1141,7 +1141,7 @@ struct break_to_none_state { struct file_id id; struct smb2_lease_key lease_key; struct GUID client_guid; - size_t num_broken; + size_t num_read_leases; }; static bool do_break_lease_to_none(struct share_mode_entry *e, @@ -1175,6 +1175,8 @@ static bool do_break_lease_to_none(struct share_mode_entry *e, return false; } + state->num_read_leases += 1; + our_own = smb2_lease_equal(&state->client_guid, &state->lease_key, &e->client_guid, @@ -1190,8 +1192,6 @@ static bool do_break_lease_to_none(struct share_mode_entry *e, send_break_to_none(state->sconn->msg_ctx, &state->id, e); - state->num_broken += 1; - return false; } @@ -1225,11 +1225,12 @@ static bool do_break_oplock_to_none(struct share_mode_entry *e, return false; } + state->num_read_leases += 1; + /* Paranoia .... */ SMB_ASSERT(!EXCLUSIVE_OPLOCK_TYPE(e->op_type)); send_break_to_none(state->sconn->msg_ctx, &state->id, e); - state->num_broken += 1; return false; } @@ -1303,7 +1304,7 @@ static void contend_level2_oplocks_begin_default(files_struct *fsp, DBG_WARNING("share_mode_forall_entries failed\n"); } - if (state.num_broken == 0) { + if (state.num_read_leases == 0) { /* * Lazy update here. It might be that the read lease * has gone in the meantime. -- 2.47.3