summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2022-02-02 12:42:08 +0100
committerJule Anger <janger@samba.org>2022-02-14 17:46:14 +0000
commita61a91d427fef0b29fbe4983ee2b9dd4d9f0c074 (patch)
tree76d46e31686dfd42472d5c21e8ea1aab96e3a655
parente8d165da42a89093b629d20fd4064b82100cc9b3 (diff)
downloadsamba-a61a91d427fef0b29fbe4983ee2b9dd4d9f0c074.tar.gz
smbd: Simplify the flow in close_file_free()
We are no longer called on base_fsp's in SHUTDOWN_CLOSE. That simplifies the logic in the common case, we now have a linear flow for the very often-called close_file() BUG: https://bugzilla.samba.org/show_bug.cgi?id=14975 Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Jeremy Allison <jra@samba.org> (cherry picked from commit 93fe9c83145d31ea11a9cd25049ac527ad4a000d)
-rw-r--r--source3/smbd/close.c69
1 files changed, 19 insertions, 50 deletions
diff --git a/source3/smbd/close.c b/source3/smbd/close.c
index 9160266c6fb..9e7f89a304f 100644
--- a/source3/smbd/close.c
+++ b/source3/smbd/close.c
@@ -1484,8 +1484,6 @@ NTSTATUS close_file_free(struct smb_request *req,
{
NTSTATUS status;
struct files_struct *fsp = *_fsp;
- struct files_struct *base_fsp = fsp->base_fsp;
- bool close_base_fsp = false;
/*
* This fsp can never be an internal dirfsp. They must
@@ -1493,44 +1491,10 @@ NTSTATUS close_file_free(struct smb_request *req,
*/
SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
- if (fsp->stream_fsp != NULL) {
- /*
- * fsp is the base for a stream.
- *
- * We're called with SHUTDOWN_CLOSE from files.c which walks the
- * complete list of files.
- *
- * We need to wait until the stream is closed.
- */
- SMB_ASSERT(close_type == SHUTDOWN_CLOSE);
- return NT_STATUS_OK;
- }
-
- if (base_fsp != NULL) {
- /*
- * We need to remove the link in order to
- * recurse for the base fsp below.
- */
- SMB_ASSERT(base_fsp->base_fsp == NULL);
- SMB_ASSERT(base_fsp->stream_fsp == fsp);
- base_fsp->stream_fsp = NULL;
-
- if (close_type == SHUTDOWN_CLOSE) {
- /*
- * We're called with SHUTDOWN_CLOSE from files.c
- * which walks the complete list of files.
- *
- * We may need to defer the SHUTDOWN_CLOSE
- * if it's the next in the linked list.
- *
- * So we only close if the base is *not* the
- * next in the list.
- */
- close_base_fsp = (fsp->next != base_fsp);
- } else {
- close_base_fsp = true;
- }
- }
+ /*
+ * Never call directly on a base fsp
+ */
+ SMB_ASSERT(fsp->stream_fsp == NULL);
if (fsp->fake_file_handle != NULL) {
status = close_fake_file(req, fsp);
@@ -1557,23 +1521,28 @@ NTSTATUS close_file_free(struct smb_request *req,
status = close_normal_file(req, fsp, close_type);
}
- file_free(req, fsp);
+ if (fsp->base_fsp != NULL) {
+ /*
+ * fsp was a stream, its base_fsp can't be a stream
+ * as well
+ */
+ SMB_ASSERT(fsp->base_fsp->base_fsp == NULL);
- if (close_base_fsp) {
+ /*
+ * There's a 1:1 relationship between fsp and a base_fsp
+ */
+ SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
/*
- * fsp was a stream, the base fsp can't be a stream as well
- *
- * For SHUTDOWN_CLOSE this is not possible here
- * (if the base_fsp was the next in the linked list), because
- * SHUTDOWN_CLOSE only happens from files.c which walks the
- * complete list of files. If we mess with more than one fsp
- * those loops will become confused.
+ * Make base_fsp look standalone now
*/
+ fsp->base_fsp->stream_fsp = NULL;
- close_file_free(req, &base_fsp, close_type);
+ close_file_free(req, &fsp->base_fsp, close_type);
}
+ file_free(req, fsp);
+
*_fsp = NULL;
return status;