s3:smbd: only clear LEASE_READ if there's no read lease is left
authorStefan Metzmacher <metze@samba.org>
Mon, 15 Aug 2022 20:45:17 +0000 (22:45 +0200)
committerJeremy Allison <jra@samba.org>
Thu, 18 Aug 2022 19:41:33 +0000 (19:41 +0000)
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 <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Thu Aug 18 19:41:33 UTC 2022 on sn-devel-184

selftest/knownfail.d/lease_bug_15148 [deleted file]
source3/smbd/smb2_oplock.c

diff --git a/selftest/knownfail.d/lease_bug_15148 b/selftest/knownfail.d/lease_bug_15148
deleted file mode 100644 (file)
index e06a3d1..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba3.smb2.lease.v1_bug15148
-^samba3.smb2.lease.v2_bug15148
index a555d3ae4fe2e53d618e70fb786c23950338e8db..1f143840b34103860ddf7d961118d00441d57e04 100644 (file)
@@ -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.