s3: Replace some create_synthetic_smb_fname() calls
authorVolker Lendecke <vl@samba.org>
Sun, 15 Nov 2009 09:46:23 +0000 (10:46 +0100)
committerVolker Lendecke <vl@samba.org>
Wed, 18 Nov 2009 22:16:13 +0000 (23:16 +0100)
In very hot codepaths like the statcache copy_smb_filename and the subsequent
recursive talloc_free is noticable in the CPU load.

source3/modules/vfs_default.c
source3/smbd/dir.c
source3/smbd/msdfs.c
source3/smbd/notify.c
source3/smbd/posix_acls.c
source3/smbd/statcache.c
source3/smbd/trans2.c

index 848440809c4ff2129ccd6e3fb1cfc670eed62728..258caf82994905d536cb4a4e1bc6c06b1df8adf5 100644 (file)
@@ -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) {
index 5d18d452f83a0fa38436257212887321d8ce8b2d..5ce4a7b09945abf11f4e023cd774df471561ab0c 100644 (file)
@@ -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;
 
index fce84170454f215dadaa9f6de236dd302078cea9..dcef75e094fdc09966555554a1edf46b80de117f 100644 (file)
@@ -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) {
index e430fcfc04c4a039f6ac24e107a08200f025400e..0c75769594f6e350ebe7930df0b9edb3d35d684d 100644 (file)
@@ -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,
index 15ea4d5fb2a92fad08163d2279fb0ee07faab938..65d0929024f558dfea28bd01f2fd6dc243d742bb 100644 (file)
@@ -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);
 }
 
 /****************************************************************************
index da52cc05d4e0f0dab797afd063f0f33cb85c6a90..db347b5b7e86755f0618027f04e3306772cd3786 100644 (file)
@@ -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,
index dacf5f34e0e16aedd684952c7e9798acbdd04391..17ebd81313c137d907ae7b7ceaaa8e0f47019e55 100644 (file)
@@ -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);