From: Jeremy Allison Date: Wed, 3 Jan 2018 17:52:33 +0000 (-0800) Subject: s3: smbd: Use identical logic to test for kernel oplocks on a share. X-Git-Tag: samba-4.6.13~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=579b6a4f603c97480a319353dcd7319dcbcb521e;p=thirdparty%2Fsamba.git s3: smbd: Use identical logic to test for kernel oplocks on a share. Due to inconsistent use of lp_kernel_oplocks() we could miss kernel oplocks being on/off in some of our oplock handling code, and thus use the wrong logic. Ensure all logic around koplocks and lp_kernel_oplocks() is consistent. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13193 Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke Autobuild-User(master): Volker Lendecke Autobuild-Date(master): Thu Jan 4 16:03:38 CET 2018 on sn-devel-144 (cherry picked from commit 114f5da2fab6f587de77e792274b396fb3d7ce71) Autobuild-User(v4-6-test): Karolin Seeger Autobuild-Date(v4-6-test): Fri Jan 5 13:40:55 CET 2018 on sn-devel-144 --- diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index d30de6a69e9..dc1159886ed 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -55,7 +55,8 @@ NTSTATUS set_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; + bool use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && + (koplocks != NULL); if (fsp->oplock_type == LEVEL_II_OPLOCK) { if (use_kernel && @@ -97,7 +98,8 @@ 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; + bool use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && + (koplocks != NULL); if ((fsp->oplock_type != NO_OPLOCK) && use_kernel) { @@ -130,13 +132,15 @@ static void downgrade_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 (!EXCLUSIVE_OPLOCK_TYPE(fsp->oplock_type)) { DEBUG(0, ("trying to downgrade an already-downgraded oplock!\n")); return; } - if (koplocks) { + if (use_kernel) { koplocks->ops->release_oplock(koplocks, fsp, LEVEL_II_OPLOCK); } fsp->oplock_type = LEVEL_II_OPLOCK; @@ -728,12 +732,14 @@ static void add_oplock_timeout_handler(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 kernel oplocks already notifies smbds when an oplock break times * out, just return. */ - if (koplocks && + if (use_kernel && (koplocks->flags & KOPLOCKS_TIMEOUT_NOTIFICATION)) { return; } @@ -844,7 +850,8 @@ static void process_oplock_break_message(struct messaging_context *msg_ctx, break_to &= ~SMB2_LEASE_READ; } - use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && koplocks; + use_kernel = lp_kernel_oplocks(SNUM(fsp->conn)) && + (koplocks != NULL); if (use_kernel && !(koplocks->flags & KOPLOCKS_LEVEL2_SUPPORTED)) { DEBUG(10, ("Kernel oplocks don't allow level2\n")); break_to &= ~SMB2_LEASE_READ; @@ -1254,8 +1261,10 @@ void smbd_contend_level2_oplocks_begin(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 (koplocks && koplocks->ops->contend_level2_oplocks_begin) { + if (use_kernel && koplocks->ops->contend_level2_oplocks_begin) { koplocks->ops->contend_level2_oplocks_begin(fsp, type); return; } @@ -1268,9 +1277,11 @@ void smbd_contend_level2_oplocks_end(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); /* Only kernel oplocks implement this so far */ - if (koplocks && koplocks->ops->contend_level2_oplocks_end) { + if (use_kernel && koplocks->ops->contend_level2_oplocks_end) { koplocks->ops->contend_level2_oplocks_end(fsp, type); } }