]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smbd: avoid false positives for got_oplock and have_other_lease in delay_for_oplock_fn
authorStefan Metzmacher <metze@samba.org>
Fri, 30 Aug 2024 12:16:12 +0000 (14:16 +0200)
committerStefan Metzmacher <metze@samba.org>
Thu, 10 Oct 2024 13:59:18 +0000 (13:59 +0000)
stat opens should not cause a oplock/lease downgrade if
they don't have a lease attached to itself.

Note that opens broken to NONE still count if they are
non-stat opens...

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

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
Autobuild-Date(master): Thu Oct 10 13:59:18 UTC 2024 on atb-devel-224

selftest/knownfail
selftest/knownfail.d/smb2.durable-v2-open.bug15649 [deleted file]
source3/smbd/open.c

index 03f8b46699446c6c0c5422e7258646543cb62f21..31e70a1a9d345d143428b7f1b5c1b8d6c7fd45ff 100644 (file)
 ^samba3.smb2.compound.interim2 # wrong return code (STATUS_CANCELLED)
 ^samba3.smb2.compound.aio.interim2 # wrong return code (STATUS_CANCELLED)
 ^samba3.smb2.lock.*replay_broken_windows # This tests the windows behaviour
-^samba3.smb2.lease.statopen3
 ^samba3.smb2.lease.unlink # we currently do not downgrade RH lease to R after unlink
 ^samba4.smb2.ioctl.compress_notsup.*\(ad_dc_ntvfs\)
 ^samba3.raw.session.*reauth2 # maybe fix this?
diff --git a/selftest/knownfail.d/smb2.durable-v2-open.bug15649 b/selftest/knownfail.d/smb2.durable-v2-open.bug15649
deleted file mode 100644 (file)
index 748b6c3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-^samba3.smb2.durable-v2-open.stat-and-lease
-^samba3.smb2.durable-v2-open.nonstat-and-lease
index 4f69a7749d8c870ebb0c650f0eff3cc52e379e35..736c6740b3557c80dfb562b5280921cfe370b499 100644 (file)
@@ -2464,7 +2464,7 @@ struct delay_for_oplock_state {
        bool first_open_attempt;
        bool got_handle_lease;
        bool got_oplock;
-       bool have_other_lease;
+       bool disallow_write_lease;
        uint32_t total_lease_types;
        bool delay;
        struct blocker_debug_state *blocker_debug_state;
@@ -2572,15 +2572,27 @@ static bool delay_for_oplock_fn(
        }
 
        if (!state->got_oplock &&
+           (e->op_type != NO_OPLOCK) &&
            (e->op_type != LEASE_OPLOCK) &&
            !share_entry_stale_pid(e)) {
                state->got_oplock = true;
        }
 
-       if (!state->have_other_lease &&
+       /*
+        * Two things prevent a write lease
+        * to be granted:
+        *
+        * 1. Any oplock or lease (even broken to NONE)
+        * 2. An open with an access mask other than
+        *    FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES
+        *    or SYNCHRONIZE_ACCESS
+        */
+       if (!state->disallow_write_lease &&
+           (e->op_type != NO_OPLOCK || !is_oplock_stat_open(e->access_mask)) &&
            !is_same_lease(fsp, e, lease) &&
-           !share_entry_stale_pid(e)) {
-               state->have_other_lease = true;
+           !share_entry_stale_pid(e))
+       {
+               state->disallow_write_lease = true;
        }
 
        if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
@@ -2814,9 +2826,11 @@ grant:
                granted &= ~SMB2_LEASE_READ;
        }
 
-       if (state.have_other_lease) {
+       if (state.disallow_write_lease) {
                /*
-                * Can grant only one writer
+                * Can grant only a write lease
+                * if there are no other leases
+                * and no other non-stat opens.
                 */
                granted &= ~SMB2_LEASE_WRITE;
        }