mirror of
https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable.git
synced 2025-09-13 11:07:46 +10:00
fs/ntfs3: correctly create symlink for relative path
[ Upstream commit b1e9d89408
]
After applying this patch, could correctly create symlink:
ln -s "relative/path/to/file" symlink
Signed-off-by: Rong Zhang <ulin0208@gmail.com>
[almaz.alexandrovich@paragon-software.com: added cpu_to_le32 macro to
rs->Flags assignment]
Signed-off-by: Konstantin Komarov <almaz.alexandrovich@paragon-software.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
3572737a76
commit
6c7fadac6c
@ -1130,10 +1130,10 @@ int inode_write_data(struct inode *inode, const void *data, size_t bytes)
|
||||
* Number of bytes for REPARSE_DATA_BUFFER(IO_REPARSE_TAG_SYMLINK)
|
||||
* for unicode string of @uni_len length.
|
||||
*/
|
||||
static inline u32 ntfs_reparse_bytes(u32 uni_len)
|
||||
static inline u32 ntfs_reparse_bytes(u32 uni_len, bool is_absolute)
|
||||
{
|
||||
/* Header + unicode string + decorated unicode string. */
|
||||
return sizeof(short) * (2 * uni_len + 4) +
|
||||
return sizeof(short) * (2 * uni_len + (is_absolute ? 4 : 0)) +
|
||||
offsetof(struct REPARSE_DATA_BUFFER,
|
||||
SymbolicLinkReparseBuffer.PathBuffer);
|
||||
}
|
||||
@ -1146,8 +1146,11 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
|
||||
struct REPARSE_DATA_BUFFER *rp;
|
||||
__le16 *rp_name;
|
||||
typeof(rp->SymbolicLinkReparseBuffer) *rs;
|
||||
bool is_absolute;
|
||||
|
||||
rp = kzalloc(ntfs_reparse_bytes(2 * size + 2), GFP_NOFS);
|
||||
is_absolute = (strlen(symname) > 1 && symname[1] == ':');
|
||||
|
||||
rp = kzalloc(ntfs_reparse_bytes(2 * size + 2, is_absolute), GFP_NOFS);
|
||||
if (!rp)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
@ -1162,7 +1165,7 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
|
||||
goto out;
|
||||
|
||||
/* err = the length of unicode name of symlink. */
|
||||
*nsize = ntfs_reparse_bytes(err);
|
||||
*nsize = ntfs_reparse_bytes(err, is_absolute);
|
||||
|
||||
if (*nsize > sbi->reparse.max_size) {
|
||||
err = -EFBIG;
|
||||
@ -1182,7 +1185,7 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
|
||||
|
||||
/* PrintName + SubstituteName. */
|
||||
rs->SubstituteNameOffset = cpu_to_le16(sizeof(short) * err);
|
||||
rs->SubstituteNameLength = cpu_to_le16(sizeof(short) * err + 8);
|
||||
rs->SubstituteNameLength = cpu_to_le16(sizeof(short) * err + (is_absolute ? 8 : 0));
|
||||
rs->PrintNameLength = rs->SubstituteNameOffset;
|
||||
|
||||
/*
|
||||
@ -1190,16 +1193,18 @@ ntfs_create_reparse_buffer(struct ntfs_sb_info *sbi, const char *symname,
|
||||
* parse this path.
|
||||
* 0-absolute path 1- relative path (SYMLINK_FLAG_RELATIVE).
|
||||
*/
|
||||
rs->Flags = 0;
|
||||
rs->Flags = cpu_to_le32(is_absolute ? 0 : SYMLINK_FLAG_RELATIVE);
|
||||
|
||||
memmove(rp_name + err + 4, rp_name, sizeof(short) * err);
|
||||
memmove(rp_name + err + (is_absolute ? 4 : 0), rp_name, sizeof(short) * err);
|
||||
|
||||
/* Decorate SubstituteName. */
|
||||
rp_name += err;
|
||||
rp_name[0] = cpu_to_le16('\\');
|
||||
rp_name[1] = cpu_to_le16('?');
|
||||
rp_name[2] = cpu_to_le16('?');
|
||||
rp_name[3] = cpu_to_le16('\\');
|
||||
if (is_absolute) {
|
||||
/* Decorate SubstituteName. */
|
||||
rp_name += err;
|
||||
rp_name[0] = cpu_to_le16('\\');
|
||||
rp_name[1] = cpu_to_le16('?');
|
||||
rp_name[2] = cpu_to_le16('?');
|
||||
rp_name[3] = cpu_to_le16('\\');
|
||||
}
|
||||
|
||||
return rp;
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user