The branch, v3-5-test has been updated
       via  7d68566... s3: Replace some create_synthetic_smb_fname() calls
       via  5a80f89... s3: Do not talloc in readdir
      from  eb8f4d1... WHATSNEW: Remove rpcclient subcommands.

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-5-test


- Log -----------------------------------------------------------------
commit 7d68566b2cac0d686119f64946416199cc0ea0dc
Author: Volker Lendecke <v...@samba.org>
Date:   Sun Nov 15 10:46:23 2009 +0100

    s3: Replace some create_synthetic_smb_fname() calls
    
    In very hot codepaths like the statcache copy_smb_filename and the 
subsequent
    recursive talloc_free is noticable in the CPU load.

commit 5a80f89b39c367582419cdd2ce0ae29c691a0709
Author: Volker Lendecke <v...@samba.org>
Date:   Mon Nov 16 09:49:23 2009 +0100

    s3: Do not talloc in readdir
    
    This is a hot codepath (called from the stat cache)

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

Summary of changes:
 source3/include/proto.h             |    7 +-
 source3/include/vfs.h               |   12 ++-
 source3/include/vfs_macros.h        |    8 +-
 source3/modules/vfs_catia.c         |   23 ++++--
 source3/modules/vfs_default.c       |   34 ++++------
 source3/modules/vfs_full_audit.c    |   11 ++-
 source3/modules/vfs_streams_depot.c |   12 ++--
 source3/smbd/dir.c                  |  129 +++++++++++++++++++----------------
 source3/smbd/filename.c             |   13 ++--
 source3/smbd/msdfs.c                |   39 +++++------
 source3/smbd/notify.c               |   16 ++---
 source3/smbd/posix_acls.c           |   28 +++-----
 source3/smbd/reply.c                |   94 ++++++++++++++------------
 source3/smbd/statcache.c            |   18 ++----
 source3/smbd/trans2.c               |   31 +++------
 source3/smbd/vfs.c                  |   42 +++++++-----
 16 files changed, 261 insertions(+), 256 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/proto.h b/source3/include/proto.h
index 3e1b4ec..ff0156d 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -6205,8 +6205,8 @@ bool get_dir_entry(TALLOC_CTX *ctx,
 bool is_visible_file(connection_struct *conn, const char *dir_path, const char 
*name, SMB_STRUCT_STAT *pst, bool use_veto);
 struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn,
                        const char *name, const char *mask, uint32 attr);
-char *ReadDirName(struct smb_Dir *dirp, long *poffset,
-                       SMB_STRUCT_STAT *sbuf);
+const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+                       SMB_STRUCT_STAT *sbuf, char **talloced);
 void RewindDir(struct smb_Dir *dirp, long *poffset);
 void SeekDir(struct smb_Dir *dirp, long offset);
 long TellDir(struct smb_Dir *dirp);
@@ -7131,7 +7131,8 @@ int vfs_allocate_file_space(files_struct *fsp, uint64_t 
len);
 int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len);
 int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len);
 SMB_OFF_T vfs_transfer_file(files_struct *in, files_struct *out, SMB_OFF_T n);
-char *vfs_readdirname(connection_struct *conn, void *p, SMB_STRUCT_STAT *sbuf);
+const char *vfs_readdirname(connection_struct *conn, void *p,
+                           SMB_STRUCT_STAT *sbuf, char **talloced);
 int vfs_ChDir(connection_struct *conn, const char *path);
 char *vfs_GetWd(TALLOC_CTX *ctx, connection_struct *conn);
 NTSTATUS check_reduced_name(connection_struct *conn, const char *fname);
diff --git a/source3/include/vfs.h b/source3/include/vfs.h
index f9c1f0a..aee84a7 100644
--- a/source3/include/vfs.h
+++ b/source3/include/vfs.h
@@ -308,8 +308,10 @@ struct vfs_fn_pointers {
                              struct lock_struct *plock);
 
        NTSTATUS (*translate_name)(struct vfs_handle_struct *handle,
-                                  char **mapped_name,
-                                  enum vfs_translate_direction direction);
+                                  const char *name,
+                                  enum vfs_translate_direction direction,
+                                  TALLOC_CTX *mem_ctx,
+                                  char **mapped_name);
 
        /* NT ACL operations. */
 
@@ -658,8 +660,10 @@ void smb_vfs_call_strict_unlock(struct vfs_handle_struct 
*handle,
                                struct files_struct *fsp,
                                struct lock_struct *plock);
 NTSTATUS smb_vfs_call_translate_name(struct vfs_handle_struct *handle,
-                                    char **mapped_name,
-                                    enum vfs_translate_direction direction);
+                                    const char *name,
+                                    enum vfs_translate_direction direction,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **mapped_name);
 NTSTATUS smb_vfs_call_fget_nt_acl(struct vfs_handle_struct *handle,
                                  struct files_struct *fsp,
                                  uint32 security_info,
diff --git a/source3/include/vfs_macros.h b/source3/include/vfs_macros.h
index 7206bf4..c6f83bd 100644
--- a/source3/include/vfs_macros.h
+++ b/source3/include/vfs_macros.h
@@ -345,10 +345,10 @@
 #define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
        smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
 
-#define SMB_VFS_TRANSLATE_NAME(conn, mapped_name, direction)                   
\
-       smb_vfs_call_translate_name((conn)->vfs_handles, (mapped_name), 
(direction))
-#define SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction)            
\
-       smb_vfs_call_translate_name((handle)->next, (mapped_name), (direction))
+#define SMB_VFS_TRANSLATE_NAME(conn, name, direction, mem_ctx, mapped_name) \
+       smb_vfs_call_translate_name((conn)->vfs_handles, (name), (direction), 
(mem_ctx), (mapped_name))
+#define SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx, 
mapped_name) \
+       smb_vfs_call_translate_name((handle)->next, (name), (direction), 
(mem_ctx), (mapped_name))
 
 #define SMB_VFS_NEXT_STRICT_UNLOCK(handle, fsp, plock) \
        smb_vfs_call_strict_unlock((handle)->next, (fsp), (plock))
diff --git a/source3/modules/vfs_catia.c b/source3/modules/vfs_catia.c
index 14e404f..f1d0cad 100644
--- a/source3/modules/vfs_catia.c
+++ b/source3/modules/vfs_catia.c
@@ -286,11 +286,14 @@ static SMB_STRUCT_DIR *catia_opendir(vfs_handle_struct 
*handle,
  * TRANSLATE_NAME call which converts the given name to
  * "WINDOWS displayable" name
  */
-static NTSTATUS catia_translate_name(vfs_handle_struct *handle,
-                                    char **mapped_name,
-                                    enum vfs_translate_direction direction)
+static NTSTATUS catia_translate_name(struct vfs_handle_struct *handle,
+                                    const char *orig_name,
+                                    enum vfs_translate_direction direction,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **pmapped_name)
 {
        char *name = NULL;
+       char *mapped_name;
        NTSTATUS ret;
 
        /*
@@ -299,21 +302,27 @@ static NTSTATUS catia_translate_name(vfs_handle_struct 
*handle,
         * We will be allocating new memory for mapped_name in
         * catia_string_replace_allocate
         */
-       name = talloc_strdup(talloc_tos(), *mapped_name);
+       name = talloc_strdup(talloc_tos(), orig_name);
        if (!name) {
                errno = ENOMEM;
                return NT_STATUS_NO_MEMORY;
        }
-       TALLOC_FREE(*mapped_name);
        ret = catia_string_replace_allocate(handle->conn, name,
-                       mapped_name, direction);
+                       &mapped_name, direction);
 
        TALLOC_FREE(name);
        if (!NT_STATUS_IS_OK(ret)) {
                return ret;
        }
 
-       ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction);
+       ret = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction,
+                                         mem_ctx, pmapped_name);
+
+       if (NT_STATUS_EQUAL(ret, NT_STATUS_NONE_MAPPED)) {
+               *pmapped_name = talloc_move(mem_ctx, &mapped_name);
+       } else {
+               TALLOC_FREE(mapped_name);
+       }
 
        return ret;
 }
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 8fbea0c..258caf8 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -649,17 +649,15 @@ static int vfswrap_lstat(vfs_handle_struct *handle,
        return result;
 }
 
-static NTSTATUS vfswrap_translate_name(vfs_handle_struct *handle,
-                                      char **mapped_name,
-                                      enum vfs_translate_direction direction)
+static NTSTATUS vfswrap_translate_name(struct vfs_handle_struct *handle,
+                                      const char *name,
+                                      enum vfs_translate_direction direction,
+                                      TALLOC_CTX *mem_ctx,
+                                      char **mapped_name)
 {
-       /* Default behavior is a NOOP */
-
-       if (*mapped_name != NULL)
-               return NT_STATUS_OK;
-
-       return NT_STATUS_INVALID_PARAMETER;
+       return NT_STATUS_NONE_MAPPED;
 }
+
 /********************************************************************
  Given a stat buffer return the allocated size on disk, taking into
  account sparse files.
@@ -1228,21 +1226,17 @@ static NTSTATUS vfswrap_streaminfo(vfs_handle_struct 
*handle,
                ret = SMB_VFS_FSTAT(fsp, &sbuf);
        }
        else {
-               struct smb_filename *smb_fname = NULL;
-               NTSTATUS status;
+               struct smb_filename smb_fname;
+
+               ZERO_STRUCT(smb_fname);
+               smb_fname.base_name = discard_const_p(char, fname);
 
-               status = create_synthetic_smb_fname(talloc_tos(), fname, NULL,
-                                                   NULL, &smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return status;
-               }
                if (lp_posix_pathnames()) {
-                       ret = SMB_VFS_LSTAT(handle->conn, smb_fname);
+                       ret = SMB_VFS_LSTAT(handle->conn, &smb_fname);
                } else {
-                       ret = SMB_VFS_STAT(handle->conn, smb_fname);
+                       ret = SMB_VFS_STAT(handle->conn, &smb_fname);
                }
-               sbuf = smb_fname->st;
-               TALLOC_FREE(smb_fname);
+               sbuf = smb_fname.st;
        }
 
        if (ret == -1) {
diff --git a/source3/modules/vfs_full_audit.c b/source3/modules/vfs_full_audit.c
index 5305af4..d9d12a1 100644
--- a/source3/modules/vfs_full_audit.c
+++ b/source3/modules/vfs_full_audit.c
@@ -1517,13 +1517,16 @@ static void smb_full_audit_strict_unlock(struct 
vfs_handle_struct *handle,
        return;
 }
 
-static NTSTATUS smb_full_audit_translate_name(vfs_handle_struct *handle,
-                                             char **mapped_name,
-                                             enum vfs_translate_direction 
direction)
+static NTSTATUS smb_full_audit_translate_name(struct vfs_handle_struct *handle,
+                                             const char *name,
+                                             enum vfs_translate_direction 
direction,
+                                             TALLOC_CTX *mem_ctx,
+                                             char **mapped_name)
 {
        NTSTATUS result;
 
-       result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, mapped_name, direction);
+       result = SMB_VFS_NEXT_TRANSLATE_NAME(handle, name, direction, mem_ctx,
+                                            mapped_name);
 
        do_log(SMB_VFS_OP_TRANSLATE_NAME, NT_STATUS_IS_OK(result), handle, "");
 
diff --git a/source3/modules/vfs_streams_depot.c 
b/source3/modules/vfs_streams_depot.c
index d7b878b..853d7b4 100644
--- a/source3/modules/vfs_streams_depot.c
+++ b/source3/modules/vfs_streams_depot.c
@@ -382,7 +382,8 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
 {
        char *dirname;
        SMB_STRUCT_DIR *dirhandle = NULL;
-       char *dirent = NULL;
+       const char *dirent = NULL;
+       char *talloced = NULL;
 
        dirname = stream_dir(handle, smb_fname_base, &smb_fname_base->st,
                             false);
@@ -406,20 +407,21 @@ static NTSTATUS walk_streams(vfs_handle_struct *handle,
                return map_nt_error_from_unix(errno);
        }
 
-       while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL)) != 
NULL) {
+       while ((dirent = vfs_readdirname(handle->conn, dirhandle, NULL,
+                                        &talloced)) != NULL) {
 
                if (ISDOT(dirent) || ISDOTDOT(dirent)) {
-                       TALLOC_FREE(dirent);
+                       TALLOC_FREE(talloced);
                        continue;
                }
 
                DEBUG(10, ("walk_streams: dirent=%s\n", dirent));
 
                if (!fn(dirname, dirent, private_data)) {
-                       TALLOC_FREE(dirent);
+                       TALLOC_FREE(talloced);
                        break;
                }
-               TALLOC_FREE(dirent);
+               TALLOC_FREE(talloced);
        }
 
        SMB_VFS_NEXT_CLOSEDIR(handle, dirhandle);
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c
index 60fa030..5ce4a7b 100644
--- a/source3/smbd/dir.c
+++ b/source3/smbd/dir.c
@@ -585,16 +585,21 @@ int dptr_dnum(struct dptr_struct *dptr)
  Return the next visible file name, skipping veto'd and invisible files.
 ****************************************************************************/
 
-static char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
-                                          long *poffset, SMB_STRUCT_STAT *pst)
+static const char *dptr_normal_ReadDirName(struct dptr_struct *dptr,
+                                          long *poffset, SMB_STRUCT_STAT *pst,
+                                          char **ptalloced)
 {
        /* Normal search for the next file. */
-       char *name;
-       while ((name = ReadDirName(dptr->dir_hnd, poffset, pst)) != NULL) {
+       const char *name;
+       char *talloced = NULL;
+
+       while ((name = ReadDirName(dptr->dir_hnd, poffset, pst, &talloced))
+              != NULL) {
                if (is_visible_file(dptr->conn, dptr->path, name, pst, True)) {
+                       *ptalloced = talloced;
                        return name;
                }
-               TALLOC_FREE(name);
+               TALLOC_FREE(talloced);
        }
        return NULL;
 }
@@ -608,18 +613,26 @@ char *dptr_ReadDirName(TALLOC_CTX *ctx,
                        long *poffset,
                        SMB_STRUCT_STAT *pst)
 {
-       struct smb_filename *smb_fname_base = NULL;
+       struct smb_filename smb_fname_base;
        char *name = NULL;
+       const char *name_temp = NULL;
+       char *talloced = NULL;
        char *pathreal = NULL;
        char *found_name = NULL;
        int ret;
-       NTSTATUS status;
 
        SET_STAT_INVALID(*pst);
 
        if (dptr->has_wild || dptr->did_stat) {
-               name = dptr_normal_ReadDirName(dptr, poffset, pst);
-               return name;
+               name_temp = dptr_normal_ReadDirName(dptr, poffset, pst,
+                                                   &talloced);
+               if (name_temp == NULL) {
+                       return NULL;
+               }
+               if (talloced != NULL) {
+                       return talloc_move(ctx, &talloced);
+               }
+               return talloc_strdup(ctx, name_temp);
        }
 
        /* If poffset is -1 then we know we returned this name before and we
@@ -659,19 +672,14 @@ char *dptr_ReadDirName(TALLOC_CTX *ctx,
                return NULL;
 
        /* Create an smb_filename with stream_name == NULL. */
-       status = create_synthetic_smb_fname(ctx, pathreal, NULL, NULL,
-                                           &smb_fname_base);
-       if (!NT_STATUS_IS_OK(status)) {
-               return NULL;
-       }
+       ZERO_STRUCT(smb_fname_base);
+       smb_fname_base.base_name = pathreal;
 
-       if (SMB_VFS_STAT(dptr->conn, smb_fname_base) == 0) {
-               *pst = smb_fname_base->st;
-               TALLOC_FREE(smb_fname_base);
+       if (SMB_VFS_STAT(dptr->conn, &smb_fname_base) == 0) {
+               *pst = smb_fname_base.st;
                name = talloc_strdup(ctx, dptr->wcard);
                goto clean;
        } else {
-               TALLOC_FREE(smb_fname_base);
                /* If we get any other error than ENOENT or ENOTDIR
                   then the file exists we just can't stat it. */
                if (errno != ENOENT && errno != ENOTDIR) {
@@ -706,9 +714,14 @@ char *dptr_ReadDirName(TALLOC_CTX *ctx,
 
        TALLOC_FREE(pathreal);
 
-       name = dptr_normal_ReadDirName(dptr, poffset, pst);
-
-       return name;
+       name_temp = dptr_normal_ReadDirName(dptr, poffset, pst, &talloced);
+       if (name_temp == NULL) {
+               return NULL;
+       }
+       if (talloced != NULL) {
+               return talloc_move(ctx, &talloced);
+       }
+       return talloc_strdup(ctx, name_temp);
 
 clean:
        TALLOC_FREE(pathreal);
@@ -897,7 +910,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                bool isdots;
                char *fname = NULL;
                char *pathreal = NULL;
-               struct smb_filename *smb_fname = NULL;
+               struct smb_filename smb_fname;
                uint32_t mode = 0;
                bool ok;
                NTSTATUS status;
@@ -942,21 +955,15 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                }
 
                /* Create smb_fname with NULL stream_name. */
-               status = create_synthetic_smb_fname(ctx, pathreal,
-                                                   NULL, &sbuf,
-                                                   &smb_fname);
-               TALLOC_FREE(pathreal);
-               if (!NT_STATUS_IS_OK(status)) {
-                       TALLOC_FREE(dname);
-                       TALLOC_FREE(fname);
-                       return false;
-               }
+               ZERO_STRUCT(smb_fname);
+               smb_fname.base_name = pathreal;
+               smb_fname.st = sbuf;
 
-               ok = mode_fn(ctx, private_data, smb_fname, &mode);
+               ok = mode_fn(ctx, private_data, &smb_fname, &mode);
                if (!ok) {
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(smb_fname);
+                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -965,7 +972,7 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                                fname, (unsigned int)mode, (unsigned 
int)dirtype));
                        TALLOC_FREE(dname);
                        TALLOC_FREE(fname);
-                       TALLOC_FREE(smb_fname);
+                       TALLOC_FREE(pathreal);
                        continue;
                }
 
@@ -974,25 +981,29 @@ bool smbd_dirptr_get_entry(TALLOC_CTX *ctx,
                        struct file_id fileid;
 
                        fileid = vfs_file_id_from_sbuf(conn,
-                                                      &smb_fname->st);
+                                                      &smb_fname.st);
                        get_file_infos(fileid, NULL, &write_time_ts);
                        if (!null_timespec(write_time_ts)) {
-                               update_stat_ex_mtime(&smb_fname->st,
+                               update_stat_ex_mtime(&smb_fname.st,
                                                     write_time_ts);
                        }
                }
 
                DEBUG(3,("smbd_dirptr_get_entry mask=[%s] found %s "
                        "fname=%s (%s)\n",
-                       mask, smb_fname_str_dbg(smb_fname),
+                       mask, smb_fname_str_dbg(&smb_fname),
                        dname, fname));
 
                DirCacheAdd(dirptr->dir_hnd, dname, cur_offset);
 
                TALLOC_FREE(dname);
 
+               status = copy_smb_filename(ctx, &smb_fname, _smb_fname);
+               TALLOC_FREE(pathreal);
+               if (!NT_STATUS_IS_OK(status)) {
+                       return false;
+               }
                *_fname = fname;
-               *_smb_fname = smb_fname;
                *_mode = mode;
                *_prev_offset = prev_offset;
 
@@ -1336,10 +1347,11 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, 
connection_struct *conn,
  Don't check for veto or invisible files.
 ********************************************************************/
 
-char *ReadDirName(struct smb_Dir *dirp, long *poffset,
-                       SMB_STRUCT_STAT *sbuf)
+const char *ReadDirName(struct smb_Dir *dirp, long *poffset,
+                       SMB_STRUCT_STAT *sbuf, char **ptalloced)
 {
-       char *n;
+       const char *n;
+       char *talloced = NULL;
        connection_struct *conn = dirp->conn;
 
        /* Cheat to allow . and .. to be the first entries returned. */
@@ -1347,17 +1359,14 @@ char *ReadDirName(struct smb_Dir *dirp, long *poffset,
             (*poffset == DOT_DOT_DIRECTORY_OFFSET)) && (dirp->file_number < 2))
        {
                if (dirp->file_number == 0) {
-                       n = talloc_strdup(talloc_tos(), ".");
-                       if (n == NULL)
-                               return NULL;
+                       n = ".";
                        *poffset = dirp->offset = START_OF_DIRECTORY_OFFSET;
                } else {
+                       n = "..";
                        *poffset = dirp->offset = DOT_DOT_DIRECTORY_OFFSET;
-                       n = talloc_strdup(talloc_tos(), "..");
-                       if (n == NULL)
-                               return NULL;
                }
                dirp->file_number++;
+               *ptalloced = NULL;
                return n;
        } else if (*poffset == END_OF_DIRECTORY_OFFSET) {
                *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
@@ -1367,19 +1376,21 @@ char *ReadDirName(struct smb_Dir *dirp, long *poffset,
                SeekDir(dirp, *poffset);
        }
 
-       while ((n = vfs_readdirname(conn, dirp->dir, sbuf))) {
+       while ((n = vfs_readdirname(conn, dirp->dir, sbuf, &talloced))) {
                /* Ignore . and .. - we've already returned them. */
                if (*n == '.') {
                        if ((n[1] == '\0') || (n[1] == '.' && n[2] == '\0')) {
-                               TALLOC_FREE(n);
+                               TALLOC_FREE(talloced);
                                continue;
                        }
                }
                *poffset = dirp->offset = SMB_VFS_TELLDIR(conn, dirp->dir);
+               *ptalloced = talloced;
                dirp->file_number++;
                return n;
        }
        *poffset = dirp->offset = END_OF_DIRECTORY_OFFSET;
+       *ptalloced = NULL;
        return NULL;
 }
 
@@ -1474,7 +1485,8 @@ void DirCacheAdd(struct smb_Dir *dirp, const char *name, 
long offset)
 bool SearchDir(struct smb_Dir *dirp, const char *name, long *poffset)
 {
        int i;
-       char *entry = NULL;
+       const char *entry = NULL;


-- 
Samba Shared Repository

Reply via email to