diff options
author | Volker Lendecke <vl@samba.org> | 2009-11-15 10:46:23 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-11-18 23:16:13 +0100 |
commit | d1c34d405421e2969d6cf4fc7438f783e7d6b0a5 (patch) | |
tree | 031d6a32c255db2a6a13d3a04bc4ea881129585d /source3/smbd | |
parent | f6650f5d19ad90b8e1f392efbe211c4ffa0e70c0 (diff) | |
download | samba-d1c34d405421e2969d6cf4fc7438f783e7d6b0a5.tar.gz samba-d1c34d405421e2969d6cf4fc7438f783e7d6b0a5.tar.bz2 samba-d1c34d405421e2969d6cf4fc7438f783e7d6b0a5.zip |
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.
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/dir.c | 48 | ||||
-rw-r--r-- | source3/smbd/msdfs.c | 19 | ||||
-rw-r--r-- | source3/smbd/notify.c | 16 | ||||
-rw-r--r-- | source3/smbd/posix_acls.c | 28 | ||||
-rw-r--r-- | source3/smbd/statcache.c | 18 | ||||
-rw-r--r-- | source3/smbd/trans2.c | 31 |
6 files changed, 56 insertions, 104 deletions
diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c index 5d18d452f8..5ce4a7b099 100644 --- a/source3/smbd/dir.c +++ b/source3/smbd/dir.c @@ -613,14 +613,13 @@ 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); @@ -673,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) { @@ -916,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; @@ -961,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; } @@ -984,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; } @@ -993,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; diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index fce8417045..dcef75e094 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -419,8 +419,7 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, #endif size_t bufsize = 0; char *link_target = NULL; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; + struct smb_filename smb_fname; if (pp_link_target) { bufsize = 1024; @@ -434,28 +433,22 @@ static bool is_msdfs_link_internal(TALLOC_CTX *ctx, link_target = link_target_buf; } - status = create_synthetic_smb_fname(talloc_tos(), path, NULL, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - goto err; - } + ZERO_STRUCT(smb_fname); + smb_fname.base_name = discard_const_p(char, path); - if (SMB_VFS_LSTAT(conn, smb_fname) != 0) { + if (SMB_VFS_LSTAT(conn, &smb_fname) != 0) { DEBUG(5,("is_msdfs_link_read_target: %s does not exist.\n", path)); - TALLOC_FREE(smb_fname); goto err; } - if (!S_ISLNK(smb_fname->st.st_ex_mode)) { + if (!S_ISLNK(smb_fname.st.st_ex_mode)) { DEBUG(5,("is_msdfs_link_read_target: %s is not a link.\n", path)); - TALLOC_FREE(smb_fname); goto err; } if (sbufp != NULL) { - *sbufp = smb_fname->st; + *sbufp = smb_fname.st; } - TALLOC_FREE(smb_fname); referral_len = SMB_VFS_READLINK(conn, path, link_target, bufsize - 1); if (referral_len == -1) { diff --git a/source3/smbd/notify.c b/source3/smbd/notify.c index e430fcfc04..0c75769594 100644 --- a/source3/smbd/notify.c +++ b/source3/smbd/notify.c @@ -367,20 +367,16 @@ void notify_fname(connection_struct *conn, uint32 action, uint32 filter, path += 2; } if (parent_dirname(talloc_tos(), path, &parent, &name)) { - struct smb_filename *smb_fname_parent = NULL; - NTSTATUS status; + struct smb_filename smb_fname_parent; - status = create_synthetic_smb_fname(talloc_tos(), parent, NULL, - NULL, &smb_fname_parent); - if (!NT_STATUS_IS_OK(status)) { - return; - } - if (SMB_VFS_STAT(conn, smb_fname_parent) != -1) { + ZERO_STRUCT(smb_fname_parent); + smb_fname_parent.base_name = parent; + + if (SMB_VFS_STAT(conn, &smb_fname_parent) != -1) { notify_onelevel(conn->notify_ctx, action, filter, - SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent->st), + SMB_VFS_FILE_ID_CREATE(conn, &smb_fname_parent.st), name); } - TALLOC_FREE(smb_fname_parent); } fullpath = talloc_asprintf(talloc_tos(), "%s/%s", conn->connectpath, diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index 15ea4d5fb2..65d0929024 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -3460,49 +3460,41 @@ NTSTATUS posix_get_nt_acl(struct connection_struct *conn, const char *name, SMB_ACL_T posix_acl = NULL; SMB_ACL_T def_acl = NULL; struct pai_val *pal; - struct smb_filename *smb_fname = NULL; - NTSTATUS status; + struct smb_filename smb_fname; int ret; *ppdesc = NULL; DEBUG(10,("posix_get_nt_acl: called for file %s\n", name )); - status = create_synthetic_smb_fname(talloc_tos(), name, NULL, NULL, - &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ZERO_STRUCT(smb_fname); + smb_fname.base_name = discard_const_p(char, name); /* Get the stat struct for the owner info. */ if (lp_posix_pathnames()) { - ret = SMB_VFS_LSTAT(conn, smb_fname); + ret = SMB_VFS_LSTAT(conn, &smb_fname); } else { - ret = SMB_VFS_STAT(conn, smb_fname); + ret = SMB_VFS_STAT(conn, &smb_fname); } if (ret == -1) { - status = map_nt_error_from_unix(errno); - goto out; + return map_nt_error_from_unix(errno); } /* Get the ACL from the path. */ posix_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_ACCESS); /* If it's a directory get the default POSIX ACL. */ - if(S_ISDIR(smb_fname->st.st_ex_mode)) { + if(S_ISDIR(smb_fname.st.st_ex_mode)) { def_acl = SMB_VFS_SYS_ACL_GET_FILE(conn, name, SMB_ACL_TYPE_DEFAULT); def_acl = free_empty_sys_acl(conn, def_acl); } pal = load_inherited_info(conn, name); - status = posix_get_nt_acl_common(conn, name, &smb_fname->st, pal, - posix_acl, def_acl, security_info, - ppdesc); - out: - TALLOC_FREE(smb_fname); - return status; + return posix_get_nt_acl_common(conn, name, &smb_fname.st, pal, + posix_acl, def_acl, security_info, + ppdesc); } /**************************************************************************** diff --git a/source3/smbd/statcache.c b/source3/smbd/statcache.c index da52cc05d4..db347b5b7e 100644 --- a/source3/smbd/statcache.c +++ b/source3/smbd/statcache.c @@ -175,8 +175,7 @@ bool stat_cache_lookup(connection_struct *conn, DATA_BLOB data_val; char *name; TALLOC_CTX *ctx = talloc_tos(); - struct smb_filename *smb_fname = NULL; - NTSTATUS status; + struct smb_filename smb_fname; *pp_dirpath = NULL; *pp_start = *pp_name; @@ -276,25 +275,18 @@ bool stat_cache_lookup(connection_struct *conn, "-> [%s]\n", chk_name, translated_path )); DO_PROFILE_INC(statcache_hits); - status = create_synthetic_smb_fname(talloc_tos(), translated_path, - NULL, NULL, &smb_fname); - if (!NT_STATUS_IS_OK(status)) { - TALLOC_FREE(chk_name); - TALLOC_FREE(translated_path); - return false; - } + ZERO_STRUCT(smb_fname); + smb_fname.base_name = translated_path; - if (SMB_VFS_STAT(conn, smb_fname) != 0) { + if (SMB_VFS_STAT(conn, &smb_fname) != 0) { /* Discard this entry - it doesn't exist in the filesystem. */ memcache_delete(smbd_memcache(), STAT_CACHE, data_blob_const(chk_name, strlen(chk_name))); TALLOC_FREE(chk_name); TALLOC_FREE(translated_path); - TALLOC_FREE(smb_fname); return False; } - *pst = smb_fname->st; - TALLOC_FREE(smb_fname); + *pst = smb_fname.st; if (!sizechanged) { memcpy(*pp_name, translated_path, diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c index dacf5f34e0..17ebd81313 100644 --- a/source3/smbd/trans2.c +++ b/source3/smbd/trans2.c @@ -2879,9 +2879,8 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, int snum = SNUM(conn); char *fstype = lp_fstype(SNUM(conn)); uint32 additional_flags = 0; - struct smb_filename *smb_fname_dot = NULL; + struct smb_filename smb_fname_dot; SMB_STRUCT_STAT st; - NTSTATUS status; if (IS_IPC(conn)) { if (info_level != SMB_QUERY_CIFS_UNIX_INFO) { @@ -2894,20 +2893,15 @@ NTSTATUS smbd_do_qfsinfo(connection_struct *conn, DEBUG(3,("smbd_do_qfsinfo: level = %d\n", info_level)); - status = create_synthetic_smb_fname(talloc_tos(), ".", NULL, NULL, - &smb_fname_dot); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + ZERO_STRUCT(smb_fname_dot); + smb_fname_dot.base_name = discard_const_p(char, "."); - if(SMB_VFS_STAT(conn, smb_fname_dot) != 0) { + if(SMB_VFS_STAT(conn, &smb_fname_dot) != 0) { DEBUG(2,("stat of . failed (%s)\n", strerror(errno))); - TALLOC_FREE(smb_fname_dot); return map_nt_error_from_unix(errno); } - st = smb_fname_dot->st; - TALLOC_FREE(smb_fname_dot); + st = smb_fname_dot.st; *ppdata = (char *)SMB_REALLOC( *ppdata, max_data_bytes + DIR_ENTRY_SAFETY_MARGIN); @@ -5392,12 +5386,11 @@ NTSTATUS smb_set_file_time(connection_struct *conn, struct smb_file_time *ft, bool setting_write_time) { - struct smb_filename *smb_fname_base = NULL; + struct smb_filename smb_fname_base; uint32 action = FILE_NOTIFY_CHANGE_LAST_ACCESS |FILE_NOTIFY_CHANGE_LAST_WRITE |FILE_NOTIFY_CHANGE_CREATION; - NTSTATUS status; if (!VALID_STAT(smb_fname->st)) { return NT_STATUS_OBJECT_NAME_NOT_FOUND; @@ -5469,18 +5462,12 @@ NTSTATUS smb_set_file_time(connection_struct *conn, DEBUG(10,("smb_set_file_time: setting utimes to modified values.\n")); /* Always call ntimes on the base, even if a stream was passed in. */ - status = create_synthetic_smb_fname(talloc_tos(), smb_fname->base_name, - NULL, &smb_fname->st, - &smb_fname_base); - if (!NT_STATUS_IS_OK(status)) { - return status; - } + smb_fname_base = *smb_fname; + smb_fname_base.stream_name = NULL; - if(file_ntimes(conn, smb_fname_base, ft)!=0) { - TALLOC_FREE(smb_fname_base); + if(file_ntimes(conn, &smb_fname_base, ft)!=0) { return map_nt_error_from_unix(errno); } - TALLOC_FREE(smb_fname_base); notify_fname(conn, NOTIFY_ACTION_MODIFIED, action, smb_fname->base_name); |