]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Simplify hardlink_internals()
authorVolker Lendecke <vl@samba.org>
Tue, 16 Sep 2025 20:15:39 +0000 (13:15 -0700)
committerRalph Boehme <slow@samba.org>
Tue, 21 Oct 2025 17:33:29 +0000 (17:33 +0000)
Avoid calling parent_pathref() in hardlink_internals. All but one
callers have the required information anyway. Unfortunately the one
that does not have it is the SMB2 one. So for SMB2+ this is not a real
optimization, but in some distant future we might have a dirfsp
attached to every fsp, so this might at some point also solve itself.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/proto.h
source3/smbd/smb1_nttrans.c
source3/smbd/smb1_trans2.c
source3/smbd/smb2_trans2.c

index dbc420d802784a5a066551b6aef28168aec805f4..b9e598810c30d35ad3505a713da0c30df76ea9c1 100644 (file)
@@ -1100,7 +1100,9 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                            connection_struct *conn,
                            struct smb_request *req,
                            bool overwrite_if_exists,
+                           struct files_struct *dirfsp_old,
                            const struct smb_filename *smb_fname_old,
+                           struct smb_filename *smb_fname_old_rel,
                            struct files_struct *dirfsp_new,
                            struct smb_filename *smb_fname_new,
                            struct smb_filename *smb_fname_new_rel);
index ed8cb67d14fd6ff4cbf465cc56fc9f8a1d738ff3..f6c8323a0dc86105737b993a1fef335e0344396c 100644 (file)
@@ -1420,6 +1420,7 @@ void reply_ntrename(struct smb_request *req)
        connection_struct *conn = req->conn;
        struct files_struct *src_dirfsp = NULL;
        struct smb_filename *smb_fname_old = NULL;
+       struct smb_filename *smb_fname_old_rel = NULL;
        struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_new = NULL;
        struct smb_filename *smb_fname_new_rel = NULL;
@@ -1480,13 +1481,15 @@ void reply_ntrename(struct smb_request *req)
                goto out;
        }
 
-       status = filename_convert_dirfsp(ctx,
-                                        conn,
-                                        oldname,
-                                        ucf_flags_src,
-                                        src_twrp,
-                                        &src_dirfsp,
-                                        &smb_fname_old);
+       status = filename_convert_dirfsp_rel(ctx,
+                                            conn,
+                                            conn->cwd_fsp,
+                                            oldname,
+                                            ucf_flags_src,
+                                            src_twrp,
+                                            &src_dirfsp,
+                                            &smb_fname_old,
+                                            &smb_fname_old_rel);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,
                                    NT_STATUS_PATH_NOT_COVERED)) {
@@ -1594,7 +1597,9 @@ void reply_ntrename(struct smb_request *req)
                                            conn,
                                            req,
                                            false,
+                                           src_dirfsp,
                                            smb_fname_old,
+                                           smb_fname_old_rel,
                                            dst_dirfsp,
                                            smb_fname_new,
                                            smb_fname_new_rel);
index f76eeaf76b744b1e5cb388ddefe337f746ec9a8f..0fd72e6c724433e9324e04a1abe1bef7d0622bca 100644 (file)
@@ -3709,6 +3709,7 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
        char *oldname = NULL;
        struct files_struct *src_dirfsp = NULL;
        struct smb_filename *smb_fname_old = NULL;
+       struct smb_filename *smb_fname_old_rel = NULL;
        uint32_t ucf_flags = ucf_flags_from_smb_request(req);
        NTTIME old_twrp = 0;
        TALLOC_CTX *ctx = talloc_tos();
@@ -3757,13 +3758,15 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       status = filename_convert_dirfsp(ctx,
-                                        conn,
-                                        oldname,
-                                        ucf_flags,
-                                        old_twrp,
-                                        &src_dirfsp,
-                                        &smb_fname_old);
+       status = filename_convert_dirfsp_rel(ctx,
+                                            conn,
+                                            conn->cwd_fsp,
+                                            oldname,
+                                            ucf_flags,
+                                            old_twrp,
+                                            &src_dirfsp,
+                                            &smb_fname_old,
+                                            &smb_fname_old_rel);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -3772,7 +3775,9 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
                                  conn,
                                  req,
                                  false,
+                                 src_dirfsp,
                                  smb_fname_old,
+                                 smb_fname_old_rel,
                                  dirfsp_new,
                                  smb_fname_new,
                                  smb_fname_new_rel);
index 3577563850f2a85ef7c4843c557615b6f8f5c8ca..13b3689197fa86f5dfcc4a892f44eb6e61a48ccd 100644 (file)
@@ -3688,7 +3688,9 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                            connection_struct *conn,
                            struct smb_request *req,
                            bool overwrite_if_exists,
+                           struct files_struct *dirfsp_old,
                            const struct smb_filename *smb_fname_old,
+                           struct smb_filename *smb_fname_old_rel,
                            struct files_struct *dirfsp_new,
                            struct smb_filename *smb_fname_new,
                            struct smb_filename *smb_fname_new_rel)
@@ -3696,8 +3698,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
        NTSTATUS status = NT_STATUS_OK;
        int ret;
        bool ok;
-       struct smb_filename *parent_fname_old = NULL;
-       struct smb_filename *base_name_old = NULL;
 
        /* source must already exist. */
        if (!VALID_STAT(smb_fname_old->st)) {
@@ -3730,15 +3730,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                goto out;
        }
 
-       status = parent_pathref(talloc_tos(),
-                               conn->cwd_fsp,
-                               smb_fname_old,
-                               &parent_fname_old,
-                               &base_name_old);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        if (VALID_STAT(smb_fname_new->st)) {
                if (overwrite_if_exists) {
                        if (S_ISDIR(smb_fname_new->st.st_ex_mode)) {
@@ -3765,8 +3756,8 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                  smb_fname_new->base_name);
 
        ret = SMB_VFS_LINKAT(conn,
-                            parent_fname_old->fsp,
-                            base_name_old,
+                            dirfsp_old,
+                            smb_fname_old_rel,
                             dirfsp_new,
                             smb_fname_new_rel,
                             0);
@@ -3788,8 +3779,6 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                     fsp_get_smb2_lease(smb_fname_old->fsp));
 
   out:
-
-       TALLOC_FREE(parent_fname_old);
        return status;
 }
 
@@ -4414,6 +4403,8 @@ static NTSTATUS smb_file_link_information(connection_struct *conn,
        bool overwrite;
        uint32_t len;
        char *newname = NULL;
+       struct smb_filename *src_parent = NULL;
+       struct smb_filename *smb_fname_src_rel = NULL;
        struct files_struct *dst_dirfsp = NULL;
        struct smb_filename *smb_fname_dst = NULL;
        struct smb_filename *smb_fname_dst_rel = NULL;
@@ -4512,6 +4503,15 @@ static NTSTATUS smb_file_link_information(connection_struct *conn,
                return NT_STATUS_NOT_SUPPORTED;
        }
 
+       status = parent_pathref(ctx,
+                               conn->cwd_fsp,
+                               fsp->fsp_name,
+                               &src_parent,
+                               &smb_fname_src_rel);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        DBG_DEBUG("SMB_FILE_LINK_INFORMATION (%s) %s -> %s\n",
                  fsp_fnum_dbg(fsp),
                  fsp_str_dbg(fsp),
@@ -4521,7 +4521,9 @@ static NTSTATUS smb_file_link_information(connection_struct *conn,
                                    conn,
                                    req,
                                    overwrite,
+                                   src_parent->fsp,
                                    fsp->fsp_name,
+                                   smb_fname_src_rel,
                                    dst_dirfsp,
                                    smb_fname_dst,
                                    smb_fname_dst_rel);