ntfs: clean up target name conversion for WSL symlinks

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>
This commit is contained in:
Hyunchul Lee 2026-06-15 08:49:56 +09:00 committed by Namjae Jeon
parent 115446b06f
commit 7266767f67
3 changed files with 30 additions and 45 deletions

View 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;

View File

@ -753,43 +753,41 @@ static int ntfs_set_ntfs_reparse_data(struct ntfs_inode *ni, char *value, size_t
* 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;
}

View 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);