]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:smbd: call set_file_oplock() after set_share_mode()
authorStefan Metzmacher <metze@samba.org>
Wed, 10 Aug 2022 08:48:25 +0000 (08:48 +0000)
committerJeremy Allison <jra@samba.org>
Tue, 20 Sep 2022 00:34:35 +0000 (00:34 +0000)
The important part is the call to get a kernel oplock is deferred
until after set_share_mode(). The goal is to get the code
between get_share_mode_lock() and set_share_mode() free of any
blocking operation.

As we were optimistic to get the oplock that was asked for,
we need to remove_share_oplock() in order to set NO_OPLOCK
also in the share_mode entry.

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

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

index 596fa55eeed01a28cf03262f8803ea24539ec32f..4b22a0a703d7268b6121ba1ed4811dd900f0981d 100644 (file)
@@ -4170,20 +4170,6 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
 
        if (oplock_type == LEASE_OPLOCK) {
                lease_key = &lease->lease_key;
-
-               fsp->oplock_type = oplock_type;
-
-       } else if (oplock_type != NO_OPLOCK) {
-
-               fsp->oplock_type = oplock_type;
-
-               status = set_file_oplock(fsp);
-               if (!NT_STATUS_IS_OK(status)) {
-                       /*
-                        * Could not get the kernel oplock
-                        */
-                       fsp->oplock_type = oplock_type = NO_OPLOCK;
-               }
        }
 
        share_mode_flags_restrict(lck, access_mask, share_access, 0);
@@ -4215,6 +4201,23 @@ static NTSTATUS open_file_ntcreate(connection_struct *conn,
                DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
        }
 
+       fsp->oplock_type = oplock_type;
+
+       if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
+               /*
+                * Now ask for kernel oplocks
+                * and cleanup on failure.
+                */
+               status = set_file_oplock(fsp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       /*
+                        * Could not get the kernel oplock
+                        */
+                       remove_share_oplock(lck, fsp);
+                       fsp->oplock_type = oplock_type = NO_OPLOCK;
+               }
+       }
+
        /* Should we atomically (to the client at least) truncate ? */
        if ((!new_file_created) &&
            (flags2 & O_TRUNC) &&