[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Tue May 11 22:53:02 UTC 2021


The branch, master has been updated
       via  33f45491f8d s3: smbd: Remove a STAT/LSTAT call on the parent pathname in a hot code path.
       via  6e0680ce075 s3: smbd: Allow check_parent_exists() to return the errno from STAT/LSTAT on the parent name.
      from  3f57c6bba67 VFS: Update status of SMB_VFS_STREAMINFO

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 33f45491f8de52c3702c6f9e542261641e011c2e
Author: Jeremy Allison <jra at samba.org>
Date:   Tue May 11 11:41:42 2021 -0700

    s3: smbd: Remove a STAT/LSTAT call on the parent pathname in a hot code path.
    
    This optimization uses the stored errno result from check_parent_exists()
    which already did a STAT/LSTAT if needed.
    
    Best viewed with 'git show -b'.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>
    
    Autobuild-User(master): Jeremy Allison <jra at samba.org>
    Autobuild-Date(master): Tue May 11 22:52:58 UTC 2021 on sn-devel-184

commit 6e0680ce075c1eedc33be1ef7b0b16015901d536
Author: Jeremy Allison <jra at samba.org>
Date:   Tue May 11 11:31:55 2021 -0700

    s3: smbd: Allow check_parent_exists() to return the errno from STAT/LSTAT on the parent name.
    
    Not yet used.
    
    This will allow us to avoid an duplicate STAT/LSTAT system call
    on the parent pathname in a hot code path of the caller in the next commit.
    
    Signed-off-by: Jeremy Allison <jra at samba.org>
    Reviewed-by: Richard Sharpe <realrichardsharpe at gmail.com>

-----------------------------------------------------------------------

Summary of changes:
 source3/smbd/filename.c | 62 +++++++++++++++++++++++++++++++------------------
 1 file changed, 39 insertions(+), 23 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 5d7a51b8031..44a58a20c1f 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -162,7 +162,8 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
 				bool posix_pathnames,
 				const struct smb_filename *smb_fname,
 				char **pp_dirpath,
-				char **pp_start)
+				char **pp_start,
+				int *p_parent_stat_errno)
 {
 	char *parent_name = NULL;
 	struct smb_filename *parent_fname = NULL;
@@ -211,6 +212,16 @@ static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
 	   with the normal tree walk. */
 
 	if (ret == -1) {
+		/*
+		 * Optimization. Preserving the
+		 * errno from the STAT/LSTAT here
+		 * will allow us to save a duplicate
+		 * STAT/LSTAT system call of the parent
+		 * pathname in a hot code path in the caller.
+		 */
+		if (p_parent_stat_errno != NULL) {
+			*p_parent_stat_errno = errno;
+		}
 		goto no_optimization_out;
 	}
 
@@ -1163,6 +1174,8 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx,
 		  state->smb_fname->base_name, state->dirpath, state->name);
 
 	if (!state->name_has_wildcard) {
+		int parent_stat_errno = 0;
+
 		/*
 		 * stat the name - if it exists then we can add the stream back (if
 		 * there was one) and be done!
@@ -1206,7 +1219,8 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx,
 						state->posix_pathnames,
 						state->smb_fname,
 						&state->dirpath,
-						&state->name);
+						&state->name,
+						&parent_stat_errno);
 			errno = saved_errno;
 			if (!NT_STATUS_IS_OK(status)) {
 				goto fail;
@@ -1240,29 +1254,30 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx,
 				/*
 				 * Was it a missing last component ?
 				 * or a missing intermediate component ?
+				 *
+				 * Optimization.
+				 *
+				 * For this code path we can guarantee that
+				 * we have gone through check_parent_exists()
+				 * and it returned NT_STATUS_OK.
+				 *
+				 * Either there was no parent component (".")
+				 * parent_stat_errno == 0 and we have a missing
+				 * last component here.
+				 *
+				 * OR check_parent_exists() called STAT/LSTAT
+				 * and if it failed parent_stat_errno has been
+				 * set telling us if the parent existed or not.
+				 *
+				 * Either way we can avoid another STAT/LSTAT
+				 * system call on the parent here.
 				 */
-				struct smb_filename *parent_fname = NULL;
-				struct smb_filename *base_fname = NULL;
-				bool ok;
-
-				ok = parent_smb_fname(state->mem_ctx,
-						      state->smb_fname,
-						      &parent_fname,
-						      &base_fname);
-				if (!ok) {
-					status = NT_STATUS_NO_MEMORY;
+				if (parent_stat_errno == ENOTDIR ||
+						parent_stat_errno == ENOENT ||
+						parent_stat_errno == ELOOP) {
+					status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
 					goto fail;
 				}
-				ret = vfs_stat(state->conn, parent_fname);
-				TALLOC_FREE(parent_fname);
-				if (ret == -1) {
-					if (errno == ENOTDIR ||
-							errno == ENOENT ||
-							errno == ELOOP) {
-						status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
-						goto fail;
-					}
-				}
 
 				/*
 				 * Missing last component is ok - new file.
@@ -1287,7 +1302,8 @@ NTSTATUS unix_convert(TALLOC_CTX *mem_ctx,
 					state->posix_pathnames,
 					state->smb_fname,
 					&state->dirpath,
-					&state->name);
+					&state->name,
+					NULL);
 		errno = saved_errno;
 		if (!NT_STATUS_IS_OK(status)) {
 			goto fail;


-- 
Samba Shared Repository



More information about the samba-cvs mailing list