summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVolker Lendecke <vl@samba.org>2009-11-15 10:46:23 +0100
committerVolker Lendecke <vl@samba.org>2009-11-18 23:16:13 +0100
commitd1c34d405421e2969d6cf4fc7438f783e7d6b0a5 (patch)
tree031d6a32c255db2a6a13d3a04bc4ea881129585d
parentf6650f5d19ad90b8e1f392efbe211c4ffa0e70c0 (diff)
downloadsamba-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.
-rw-r--r--source3/modules/vfs_default.c18
-rw-r--r--source3/smbd/dir.c48
-rw-r--r--source3/smbd/msdfs.c19
-rw-r--r--source3/smbd/notify.c16
-rw-r--r--source3/smbd/posix_acls.c28
-rw-r--r--source3/smbd/statcache.c18
-rw-r--r--source3/smbd/trans2.c31
7 files changed, 63 insertions, 115 deletions
diff --git a/source3/modules/vfs_default.c b/source3/modules/vfs_default.c
index 848440809c..258caf8299 100644
--- a/source3/modules/vfs_default.c
+++ b/source3/modules/vfs_default.c
@@ -1226,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/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);