summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGordon Ross <gordon.ross@tintri.com>2020-08-26 17:48:44 +0000
committerGordon Ross <gwr@racktopsystems.com>2022-08-09 16:23:36 -0400
commite8754e84740733dd9f21c60b5a5ac47d32dacb6b (patch)
tree2d34b9716a2e3e88171d5bebab71f458621f9243
parent345881c57eafd2f92f73791646936638889af149 (diff)
downloadillumos-joyent-e8754e84740733dd9f21c60b5a5ac47d32dacb6b.tar.gz
14866 SMB oplock not recalled when there is a request from NFS
Reviewed by: Prashanth Badari <prbadari@tintri.com> Reviewed by: Suresh Jayaraman <sjayaraman@tintri.com> Reviewed by: Jerry Jelinek <gjelinek@gmail.com> Reviewed by: Garrett D'Amore <garrett@damore.org> Reviewed by: Matt Barden <mbarden@tintri.com> Approved by: Dan McDonald <danmcd@mnx.io>
-rw-r--r--usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h4
-rw-r--r--usr/src/cmd/smbsrv/testoplock/tol_main.c13
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_cmn_oplock.c53
-rw-r--r--usr/src/uts/common/fs/smbsrv/smb_node.c13
4 files changed, 75 insertions, 8 deletions
diff --git a/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h
index 4ccf839f51..f743dcd179 100644
--- a/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h
+++ b/usr/src/cmd/smbsrv/testoplock/smbsrv/smb_kproto.h
@@ -21,7 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
*/
/*
@@ -103,6 +103,8 @@ uint32_t smb_oplock_wait_break(smb_node_t *, int);
int smb_lock_range_access(smb_request_t *, smb_node_t *,
uint64_t, uint64_t, boolean_t);
+int smb_fem_oplock_install(smb_node_t *);
+void smb_fem_oplock_uninstall(smb_node_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/cmd/smbsrv/testoplock/tol_main.c b/usr/src/cmd/smbsrv/testoplock/tol_main.c
index 5382802b82..f78729a9d6 100644
--- a/usr/src/cmd/smbsrv/testoplock/tol_main.c
+++ b/usr/src/cmd/smbsrv/testoplock/tol_main.c
@@ -10,7 +10,7 @@
*/
/*
- * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2020 Tintri by DDN, Inc. All rights reserved.
* Copyright 2019 Joyent, Inc.
* Copyright 2022 RackTop Systems, Inc.
*/
@@ -645,6 +645,17 @@ smb_oplock_wait_break(smb_node_t *node, int timeout)
return (0);
}
+int
+smb_fem_oplock_install(smb_node_t *node)
+{
+ return (0);
+}
+
+void
+smb_fem_oplock_uninstall(smb_node_t *node)
+{
+}
+
/*
* There are a couple DTRACE_PROBE* in smb_cmn_oplock.c but we're
* not linking with the user-level dtrace support, so just
diff --git a/usr/src/uts/common/fs/smbsrv/smb_cmn_oplock.c b/usr/src/uts/common/fs/smbsrv/smb_cmn_oplock.c
index 1b9ccce688..0afd313281 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_cmn_oplock.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_cmn_oplock.c
@@ -977,7 +977,9 @@ smb_oplock_req_excl(
* This operation MUST be made cancelable...
* This operation waits until the oplock is
* broken or canceled, as specified in
- * section 2.1.5.17.3.
+ * section 2.1.5.17.3. Note: This function
+ * does not cause breaks that require a wait,
+ * so never returns ..._BREAK_IN_PROGRESS.
*
* When the operation specified in section
* 2.1.5.17.3 is called, its following input
@@ -990,11 +992,18 @@ smb_oplock_req_excl(
* section 2.1.5.17.3.
*/
/* Keep *rop = ... from caller. */
- if ((node->n_oplock.ol_state & BREAK_ANY) != 0) {
- status = NT_STATUS_OPLOCK_BREAK_IN_PROGRESS;
- /* Caller does smb_oplock_wait_break() */
- } else {
- status = NT_STATUS_SUCCESS;
+ status = NT_STATUS_SUCCESS;
+
+ /*
+ * First oplock grant installs FEM hooks.
+ */
+ if (node->n_oplock.ol_fem == B_FALSE) {
+ if (smb_fem_oplock_install(node) != 0) {
+ cmn_err(CE_NOTE,
+ "smb_fem_oplock_install failed");
+ } else {
+ node->n_oplock.ol_fem = B_TRUE;
+ }
}
}
@@ -1387,6 +1396,18 @@ smb_oplock_req_shared(
} else {
status = NT_STATUS_SUCCESS;
}
+
+ /*
+ * First oplock grant installs FEM hooks.
+ */
+ if (node->n_oplock.ol_fem == B_FALSE) {
+ if (smb_fem_oplock_install(node) != 0) {
+ cmn_err(CE_NOTE,
+ "smb_fem_oplock_install failed");
+ } else {
+ node->n_oplock.ol_fem = B_TRUE;
+ }
+ }
}
out:
@@ -2075,6 +2096,18 @@ out:
}
/*
+ * If this node no longer has any oplock grants, let's
+ * go ahead and remove the FEM hooks now. We could leave
+ * that until close, but this lets access outside of SMB
+ * be free of FEM oplock work after a "break to none".
+ */
+ if (node->n_oplock.ol_state == NO_OPLOCK &&
+ node->n_oplock.ol_fem == B_TRUE) {
+ smb_fem_oplock_uninstall(node);
+ node->n_oplock.ol_fem = B_FALSE;
+ }
+
+ /*
* The spec. describes waiting for a break here,
* but we let the caller do that (when needed) if
* status == NT_STATUS_OPLOCK_BREAK_IN_PROGRESS
@@ -2506,6 +2539,14 @@ smb_oplock_break_CLOSE(smb_node_t *node, smb_ofile_t *ofile)
if ((node->n_oplock.ol_state & BREAK_ANY) == 0)
cv_broadcast(&node->n_oplock.WaitingOpenCV);
+ /*
+ * If no longer any oplock, remove FEM hooks.
+ */
+ if (node->n_oplock.ol_state == NO_OPLOCK &&
+ node->n_oplock.ol_fem == B_TRUE) {
+ smb_fem_oplock_uninstall(node);
+ node->n_oplock.ol_fem = B_FALSE;
+ }
}
/*
diff --git a/usr/src/uts/common/fs/smbsrv/smb_node.c b/usr/src/uts/common/fs/smbsrv/smb_node.c
index a204326514..fd37c2b328 100644
--- a/usr/src/uts/common/fs/smbsrv/smb_node.c
+++ b/usr/src/uts/common/fs/smbsrv/smb_node.c
@@ -21,6 +21,7 @@
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
* Copyright 2020 Tintri by DDN, Inc. All rights reserved.
+ * Copyright 2021 RackTop Systems, Inc.
*/
/*
* SMB Node State Machine
@@ -492,6 +493,18 @@ smb_node_release(smb_node_t *node)
mutex_exit(&node->n_mutex);
+ /*
+ * Out of caution, make sure FEM hooks
+ * used by oplocks are also gone.
+ */
+ mutex_enter(&node->n_oplock.ol_mutex);
+ ASSERT(node->n_oplock.ol_fem == B_FALSE);
+ if (node->n_oplock.ol_fem == B_TRUE) {
+ smb_fem_oplock_uninstall(node);
+ node->n_oplock.ol_fem = B_FALSE;
+ }
+ mutex_exit(&node->n_oplock.ol_mutex);
+
smb_llist_enter(node->n_hash_bucket, RW_WRITER);
smb_llist_remove(node->n_hash_bucket, node);
smb_llist_exit(node->n_hash_bucket);