]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
ntfs: clean up target name conversion for WSL symlinks
authorHyunchul Lee <hyc.lee@gmail.com>
Sun, 14 Jun 2026 23:49:56 +0000 (08:49 +0900)
committerNamjae Jeon <linkinjeon@kernel.org>
Mon, 15 Jun 2026 10:39:41 +0000 (19:39 +0900)
WSL symlink target names are stored as narrow NLS/UTF-8 strings on
disk. Converting the target name to Unicode in ntfs_symlink and
converting it back to NLS in ntfs_reparse_set_wsl_symlink is
redundant.

Remove this conversion and pass the symname directly to the reparse
data setter.

Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
fs/ntfs/namei.c
fs/ntfs/reparse.c
fs/ntfs/reparse.h

index 9c1c36acfad24e20997b7c3f27ad1fc056faa27c..88c0b05dde3bed914dbc36b6553b3c6a92a30df2 100644 (file)
@@ -394,7 +394,7 @@ static int ntfs_sd_add_everyone(struct ntfs_inode *ni)
 
 static struct ntfs_inode *__ntfs_create(struct mnt_idmap *idmap, struct inode *dir,
                __le16 *name, u8 name_len, mode_t mode, dev_t dev,
-               __le16 *target, int target_len)
+               const char *target, int target_len)
 {
        struct ntfs_inode *dir_ni = NTFS_I(dir);
        struct ntfs_volume *vol = dir_ni->vol;
@@ -1409,9 +1409,7 @@ static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
        int err = 0;
        struct ntfs_inode *ni;
        __le16 *usrc;
-       __le16 *utarget;
        int usrc_len;
-       int utarget_len;
        int symlen = strlen(symname);
 
        if (NVolShutdown(vol))
@@ -1432,23 +1430,12 @@ static int ntfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
                goto out;
        }
 
-       utarget_len = ntfs_nlstoucs(vol, symname, symlen, &utarget,
-                                   PATH_MAX);
-       if (utarget_len < 0) {
-               if (utarget_len != -ENAMETOOLONG)
-                       ntfs_error(sb, "Failed to convert target name to Unicode.");
-               err =  -ENOMEM;
-               kmem_cache_free(ntfs_name_cache, usrc);
-               goto out;
-       }
-
        if (!(vol->vol_flags & VOLUME_IS_DIRTY))
                ntfs_set_volume_flags(vol, VOLUME_IS_DIRTY);
 
        ni = __ntfs_create(idmap, dir, usrc, usrc_len, S_IFLNK | 0777, 0,
-                       utarget, utarget_len);
+                          symname, symlen);
        kmem_cache_free(ntfs_name_cache, usrc);
-       kvfree(utarget);
        if (IS_ERR(ni)) {
                err = PTR_ERR(ni);
                goto out;
index 33e5a4198e9bbf30ba72c9947037111cdc32bbb1..91ae0c75e275463f6d2457364f49e7314506c521 100644 (file)
@@ -753,43 +753,41 @@ out:
  * Set reparse data for a WSL type symlink
  */
 int ntfs_reparse_set_wsl_symlink(struct ntfs_inode *ni,
-               const __le16 *target, int target_len)
+                                const char *target, int target_len)
 {
        int err = 0;
-       int len;
        int reparse_len;
-       unsigned char *utarget = NULL;
        struct reparse_point *reparse;
        struct wsl_link_reparse_data *data;
 
-       len = ntfs_ucstonls(ni->vol, target, target_len, &utarget, 0);
-       if (len <= 0)
-               return -EINVAL;
-
-       reparse_len = sizeof(struct reparse_point) + sizeof(data->type) + len;
+       reparse_len = sizeof(struct reparse_point) + sizeof(data->type) +
+               target_len;
        reparse = kvzalloc(reparse_len, GFP_NOFS);
-       if (!reparse) {
-               err = -ENOMEM;
-               kfree(utarget);
-       } else {
-               data = (struct wsl_link_reparse_data *)reparse->reparse_data;
-               reparse->reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
-               reparse->reparse_data_length =
-                       cpu_to_le16(sizeof(data->type) + len);
-               reparse->reserved = 0;
-               data->type = cpu_to_le32(2);
-               memcpy(data->link, utarget, len);
-               err = ntfs_set_ntfs_reparse_data(ni,
-                               (char *)reparse, reparse_len);
+       if (!reparse)
+               return -ENOMEM;
+
+       ni->target = kstrdup(target, GFP_NOFS);
+       if (!ni->target) {
                kvfree(reparse);
-               if (!err) {
-                       ni->target = utarget;
-                       ni->reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
-                       ni->reparse_flags = 0;
-               } else {
-                       kfree(utarget);
-                       ni->target = NULL;
-               }
+               return -ENOMEM;
+       }
+
+       data = (struct wsl_link_reparse_data *)reparse->reparse_data;
+       reparse->reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
+       reparse->reparse_data_length =
+               cpu_to_le16(sizeof(data->type) + target_len);
+       reparse->reserved = 0;
+       data->type = cpu_to_le32(2);
+       memcpy(data->link, target, target_len);
+       err = ntfs_set_ntfs_reparse_data(ni,
+                                        (char *)reparse, reparse_len);
+       kvfree(reparse);
+       if (err) {
+               kfree(ni->target);
+               ni->target = NULL;
+       } else {
+               ni->reparse_tag = IO_REPARSE_TAG_LX_SYMLINK;
+               ni->reparse_flags = 0;
        }
        return err;
 }
index ed7b93c359c122304f33f79b33820582a2afecc5..e36557f29677de95f8c29470de6a8a11b40ca2e8 100644 (file)
@@ -14,7 +14,7 @@ unsigned int ntfs_reparse_tag_dt_types(struct ntfs_volume *vol, unsigned long mr
 int ntfs_translate_symlink_path(struct dentry *dentry, const char *target,
                                char **translated);
 int ntfs_reparse_set_wsl_symlink(struct ntfs_inode *ni,
-                       const __le16 *target, int target_len);
+                                const char *target, int target_len);
 int ntfs_reparse_set_wsl_not_symlink(struct ntfs_inode *ni, mode_t mode);
 int ntfs_delete_reparse_index(struct ntfs_inode *ni);
 int ntfs_remove_ntfs_reparse_data(struct ntfs_inode *ni);