smbd: Don't try to release a kernel oplock for a leased file
authorVolker Lendecke <vl@samba.org>
Fri, 14 Dec 2018 12:05:50 +0000 (13:05 +0100)
committerJeremy Allison <jra@samba.org>
Tue, 18 Dec 2018 01:00:44 +0000 (02:00 +0100)
If we have

[global]
  smb2 leases = yes
  kernel oplocks = no
[share]
  kernel oplocks = yes

for clients requesting leases we don't even try to acquire kernel
oplocks, because the kernel API is not compatible. Kernel oplocks are
per fd, leases are roughly "per inode".

We don't however special-case the LEASE_OPLOCK case in
release_file_oplock, leading to nasty error messages like "bad file
descriptor" on the fcntl(fd,F_SETLEASE,F_UNLCK) call. They are
harmless, but they raise eyebrows.

To simplify the if-condition, I factored out the kernel call and
applied early returns.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): Jeremy Allison <jra@samba.org>
Autobuild-Date(master): Tue Dec 18 02:00:44 CET 2018 on sn-devel-144

source3/smbd/oplock.c

index 426b9e7faeabe0bdcce1acfcb89faf283fe6c741..d733bec2d2662ff3429c672a4a991573074f1321 100644 (file)
@@ -87,6 +87,32 @@ NTSTATUS set_file_oplock(files_struct *fsp)
        return NT_STATUS_OK;
 }
 
+static void release_fsp_kernel_oplock(files_struct *fsp)
+{
+       struct smbd_server_connection *sconn = fsp->conn->sconn;
+       struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
+       bool use_kernel;
+
+       if (koplocks == NULL) {
+               return;
+       }
+       use_kernel = lp_kernel_oplocks(SNUM(fsp->conn));
+       if (!use_kernel) {
+               return;
+       }
+       if (fsp->oplock_type == NO_OPLOCK) {
+               return;
+       }
+       if (fsp->oplock_type == LEASE_OPLOCK) {
+               /*
+                * For leases we don't touch kernel oplocks at all
+                */
+               return;
+       }
+
+       koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK);
+}
+
 /****************************************************************************
  Attempt to release an oplock on a file. Decrements oplock count.
 ****************************************************************************/
@@ -94,14 +120,8 @@ NTSTATUS set_file_oplock(files_struct *fsp)
 static void release_file_oplock(files_struct *fsp)
 {
        struct smbd_server_connection *sconn = fsp->conn->sconn;
-       struct kernel_oplocks *koplocks = sconn->oplocks.kernel_ops;
-       bool use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) &&
-                       (koplocks != NULL);
 
-       if ((fsp->oplock_type != NO_OPLOCK) &&
-           use_kernel) {
-               koplocks->ops->release_oplock(koplocks, fsp, NO_OPLOCK);
-       }
+       release_fsp_kernel_oplock(fsp);
 
        if (fsp->oplock_type == LEVEL_II_OPLOCK) {
                sconn->oplocks.level_II_open--;