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