[SCM] Samba Shared Repository - branch master updated

Jeremy Allison jra at samba.org
Sat Sep 11 00:31:00 MDT 2010


The branch, master has been updated
       via  1787c1d Factor out the recent changes into a function - check_parent_exists(). Fix this to ensure that if "start" is manipulated, then "dirpath" is changed also.
      from  f76983a s3: Simplify the logic in generate_krb5_ccache

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


- Log -----------------------------------------------------------------
commit 1787c1dfc3a506c0afee6d2bb67ba8789c709b86
Author: Jeremy Allison <jra at samba.org>
Date:   Fri Sep 10 23:28:15 2010 -0700

    Factor out the recent changes into a function - check_parent_exists().
    Fix this to ensure that if "start" is manipulated, then "dirpath"
    is changed also.
    
    Ensures that when the path:
    
    /a/long/file/name/path.txt
    
    is processed, we first stat:
    
    /a/long/file/name/path.txt
    
    and if this fails, we try to stat:
    
    /a/long/file/name
    
    if this path exists (the normal case when creating a new
    entry in a directory) then we no longer do the individual
    path name walk, but only do case insensitive lookup on the
    last component. If the stat fails we do the full pathname
    walk as normal in 3.5.x and below. Metze, examine this
    change for your back-port.
    
    Jeremy.

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

Summary of changes:
 source3/smbd/filename.c |  180 +++++++++++++++++++++++++++--------------------
 1 files changed, 103 insertions(+), 77 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index eadb977..4917173 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -100,6 +100,88 @@ static NTSTATUS check_for_dot_component(const struct smb_filename *smb_fname)
 }
 
 /****************************************************************************
+ Optimization for common case where the missing part
+ is in the last component and the client already
+ sent the correct case.
+ Returns NT_STATUS_OK to mean continue the tree walk
+ (possibly with modified start pointer).
+ Any other NT_STATUS_XXX error means terminate the path
+ lookup here.
+****************************************************************************/
+
+static NTSTATUS check_parent_exists(TALLOC_CTX *ctx,
+				connection_struct *conn,
+				bool posix_pathnames,
+				struct smb_filename *smb_fname,
+				char **pp_dirpath,
+				char **pp_start)
+{
+	struct smb_filename parent_fname;
+	const char *last_component = NULL;
+	NTSTATUS status;
+	int ret;
+
+	ZERO_STRUCT(parent_fname);
+	if (!parent_dirname(ctx, smb_fname->base_name,
+				&parent_fname.base_name,
+				&last_component)) {
+		return NT_STATUS_NO_MEMORY;
+	}
+
+	/*
+	 * If there was no parent component in
+	 * smb_fname->base_name of the parent name
+	 * contained a wildcard then don't do this
+	 * optimization.
+	 */
+	if ((smb_fname->base_name == last_component) ||
+			ms_has_wild(parent_fname.base_name)) {
+		return NT_STATUS_OK;
+	}
+
+	if (posix_pathnames) {
+		ret = SMB_VFS_LSTAT(conn, &parent_fname);
+	} else {
+		ret = SMB_VFS_STAT(conn, &parent_fname);
+	}
+
+	/* If the parent stat failed, just continue
+	   with the normal tree walk. */
+
+	if (ret == -1) {
+		return NT_STATUS_OK;
+	}
+
+	status = check_for_dot_component(&parent_fname);
+	if (!NT_STATUS_IS_OK(status)) {
+		return status;
+	}
+
+	/* Parent exists - set "start" to be the
+	 * last compnent to shorten the tree walk. */
+
+	/*
+	 * Safe to use CONST_DISCARD
+	 * here as last_component points
+	 * into our smb_fname->base_name.
+	 */
+	*pp_start = CONST_DISCARD(char *,last_component);
+
+	/* Update dirpath. */
+	TALLOC_FREE(*pp_dirpath);
+	*pp_dirpath = talloc_strdup(ctx, parent_fname.base_name);
+
+	DEBUG(5,("check_parent_exists: name "
+		"= %s, dirpath = %s, "
+		"start = %s\n",
+		smb_fname->base_name,
+		*pp_dirpath,
+		*pp_start));
+
+	return NT_STATUS_OK;
+}
+
+/****************************************************************************
 This routine is called to convert names from the dos namespace to unix
 namespace. It needs to handle any case conversions, mangling, format changes,
 streams etc.
@@ -353,6 +435,20 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 			goto done;
 		}
 
+		if (errno == ENOENT) {
+			/* Optimization when creating a new file - only
+			   the last component doesn't exist. */
+			status = check_parent_exists(ctx,
+						conn,
+						posix_pathnames,
+						smb_fname,
+						&dirpath,
+						&start);
+			if (!NT_STATUS_IS_OK(status)) {
+				goto fail;
+			}
+		}
+
 		/*
 		 * A special case - if we don't have any wildcards or mangling chars and are case
 		 * sensitive or the underlying filesystem is case insentive then searching
@@ -403,38 +499,6 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 						status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
 						goto fail;
 					}
-				} else if (ret == 0) {
-					/*
-					 * stat() or lstat() of the parent dir
-					 * succeeded. So start the walk
-					 * at this point.
-					 */
-					status = check_for_dot_component(&parent_fname);
-					if (!NT_STATUS_IS_OK(status)) {
-						goto fail;
-					}
-
-		 			/*
-					 * If there was no parent component in
-					 * smb_fname->base_name then
-					 * don't do this optimization.
-					 */
-					if (smb_fname->base_name != last_component) {
-						/*
-						 * Safe to use CONST_DISCARD
-						 * here as last_component points
-						 * into our smb_fname->base_name.
-						 */
-						start = CONST_DISCARD(char *,
-							last_component);
-
-						DEBUG(5,("unix_convert optimize1: name "
-							"= %s, dirpath = %s, "
-							"start = %s\n",
-							smb_fname->base_name,
-							dirpath,
-							start));
-					}
 				}
 
 				/*
@@ -453,53 +517,15 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 		 * is in the last component and the client already
 		 * sent the correct case.
 		 */
-		struct smb_filename parent_fname;
-		const char *last_component = NULL;
-
-		ZERO_STRUCT(parent_fname);
-		if (!parent_dirname(ctx, smb_fname->base_name,
-					&parent_fname.base_name,
-					&last_component)) {
-			status = NT_STATUS_NO_MEMORY;
+		status = check_parent_exists(ctx,
+					conn,
+					posix_pathnames,
+					smb_fname,
+					&dirpath,
+					&start);
+		if (!NT_STATUS_IS_OK(status)) {
 			goto fail;
 		}
-		/*
-		 * If there was no parent component in
-		 * smb_fname->base_name then
-		 * don't do this optimization.
-		 */
-		if ((smb_fname->base_name != last_component) &&
-				!ms_has_wild(parent_fname.base_name)) {
-			/*
-			 * Wildcard isn't in the parent, i.e.
-			 * it must be in the last component.
-			 */
-			if (posix_pathnames) {
-				ret = SMB_VFS_LSTAT(conn, &parent_fname);
-			} else {
-				ret = SMB_VFS_STAT(conn, &parent_fname);
-			}
-			if (ret == 0) {
-				status = check_for_dot_component(&parent_fname);
-				if (!NT_STATUS_IS_OK(status)) {
-					goto fail;
-				}
-
-				/*
-				 * Safe to use CONST_DISCARD
-				 * here as last_component points
-				 * into our smb_fname->base_name.
-				 */
-				start = CONST_DISCARD(char *,last_component);
-
-				DEBUG(5,("unix_convert optimize2: name "
-					"= %s, dirpath = %s, "
-					"start = %s\n",
-					smb_fname->base_name,
-					dirpath,
-					start));
-			}
-		}
 	}
 
 	/*


-- 
Samba Shared Repository


More information about the samba-cvs mailing list