// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * Processing of reparse points
 *
 * Part of this file is based on code from the NTFS-3G.
 *
 * Copyright (c) 2008-2021 Jean-Pierre Andre
 * Copyright (c) 2025 LG Electronics Co., Ltd.
 */

#include "ntfs.h"
#include "layout.h"
#include "attrib.h"
#include "inode.h"
#include "dir.h"
#include "volume.h"
#include "mft.h"
#include "index.h"
#include "lcnalloc.h"
#include "reparse.h"

struct wsl_link_reparse_data {
	__le32	type;
	char	link[];
};

struct wof_reparse_data {
	__le32 version;
	__le32 provider;
	__le32 provider_version;
	__le32 compression_format;
} __packed;

#define WOF_CURRENT_VERSION			cpu_to_le32(1)

#define WOF_PROVIDER_WIM			cpu_to_le32(1)
#define WOF_PROVIDER_FILE			cpu_to_le32(2)

#define WOF_PROVIDER_CURRENT_VERSION		cpu_to_le32(1)

#define WOF_COMPRESSION_XPRESS4K		cpu_to_le32(0)
#define WOF_COMPRESSION_LZX			cpu_to_le32(1)
#define WOF_COMPRESSION_XPRESS8K		cpu_to_le32(2)
#define WOF_COMPRESSION_XPRESS16K		cpu_to_le32(3)

static bool reparse_name_is_valid(size_t size, size_t name_off, u16 len)
{
	if ((name_off | len) & 1)
		return false;

	return name_off + len <= size;
}

/*
 * Windows-native reparse payloads store pathnames as UTF-16 strings with '\\'
 * separators. Convert the on-disk UTF-16 target into the mount's NLS and
 * normalize path separators.
 */
static int ntfs_reparse_target_to_nls(struct ntfs_volume *vol,
				      const __le16 *uname, u16 ulen,
				      char **target)
{
	int err, i;

	*target = NULL;
	ulen >>= 1;
	if (!ulen)
		return -EINVAL;

	if (!uname[ulen - 1])
		ulen--;

	err = ntfs_ucstonls(vol, uname, ulen, (unsigned char **)target, 0);
	if (err < 0) {
		ntfs_attr_name_free((unsigned char **)target);
		return err;
	}

	for (i = 0; i < err; i++) {
		if ((*target)[i] == '\\')
			(*target)[i] = '/';
	}

	return 0;
}

/* Index entry in $Extend/$Reparse */
struct reparse_index {
	struct index_entry_header header;
	struct reparse_index_key key;
	__le32 filling;
};

__le16 reparse_index_name[] = {cpu_to_le16('$'), cpu_to_le16('R'), 0};


/*
 * Check if the reparse point attribute buffer is valid.
 * Returns true if valid, false otherwise.
 */
static bool valid_reparse_buffer(struct ntfs_inode *ni,
				 const struct reparse_point *reparse_attr,
				 size_t size,
				 size_t payload_min_len)
{
	size_t expected;

	if (!ni || !reparse_attr)
		return false;

	/* Minimum size must cover reparse_point header */
	if (size < sizeof(struct reparse_point))
		return false;

	/* The payload must contain the fixed fields for the current tag. */
	if (payload_min_len &&
	    le16_to_cpu(reparse_attr->reparse_data_length) < payload_min_len)
		return false;

	/* Reserved zero tag is invalid */
	if (reparse_attr->reparse_tag == IO_REPARSE_TAG_RESERVED_ZERO)
		return false;

	/* Calculate expected total size */
	expected = sizeof(struct reparse_point) +
		le16_to_cpu(reparse_attr->reparse_data_length);

	/* Add GUID size for non-Microsoft tags */
	if (!(reparse_attr->reparse_tag & IO_REPARSE_TAG_IS_MICROSOFT))
		expected += sizeof(struct guid);

	/* Buffer must exactly match the expected size */
	return expected == size;
}

/*
 * Do some sanity checks on reparse data
 *
 * Microsoft reparse points have an 8-byte header whereas
 * non-Microsoft reparse points have a 24-byte header.  In each case,
 * 'reparse_data_length' must equal the number of non-header bytes.
 *
 * If the reparse data looks like a junction point or symbolic
 * link, more checks can be done.
 */
static bool valid_reparse_data(struct ntfs_inode *ni,
		const struct reparse_point *reparse_attr, size_t size)
{
	if (size < sizeof(*reparse_attr))
		return false;

	switch (reparse_attr->reparse_tag) {
	case IO_REPARSE_TAG_MOUNT_POINT:
	{
		struct mount_point_reparse_data *data;
		size_t data_offs;

		if (!valid_reparse_buffer(ni, reparse_attr, size, sizeof(*data)))
			return false;

		data = (struct mount_point_reparse_data *)reparse_attr->reparse_data;
		data_offs = offsetof(struct reparse_point, reparse_data) +
			offsetof(struct mount_point_reparse_data, path_buffer);

		if (!reparse_name_is_valid(size,
					   data_offs +
					   le16_to_cpu(data->substitute_name_offset),
					   le16_to_cpu(data->substitute_name_length)) ||
		    !reparse_name_is_valid(size,
					   data_offs +
					   le16_to_cpu(data->print_name_offset),
					   le16_to_cpu(data->print_name_length)))
			return false;
		break;
	}
	case IO_REPARSE_TAG_SYMLINK:
	{
		struct symlink_reparse_data *data;
		size_t data_offs;

		if (!valid_reparse_buffer(ni, reparse_attr, size,
					  sizeof(*data)))
			return false;

		data = (struct symlink_reparse_data *)reparse_attr->reparse_data;
		data_offs = offsetof(struct reparse_point, reparse_data) +
			offsetof(struct symlink_reparse_data, path_buffer);

		if (!reparse_name_is_valid(size,
					   data_offs +
					   le16_to_cpu(data->substitute_name_offset),
					   le16_to_cpu(data->substitute_name_length)) ||
		    !reparse_name_is_valid(size,
					   data_offs +
					   le16_to_cpu(data->print_name_offset),
					   le16_to_cpu(data->print_name_length)))
			return false;
		break;
	}
	case IO_REPARSE_TAG_LX_SYMLINK:
	{
		struct wsl_link_reparse_data *data;

		if (!valid_reparse_buffer(ni, reparse_attr, size,
					  sizeof(*data)))
			return false;

		data = (struct wsl_link_reparse_data *)reparse_attr->reparse_data;

		if (le16_to_cpu(reparse_attr->reparse_data_length) <= sizeof(data->type) ||
		    data->type != cpu_to_le32(2))
			return false;
		break;
	}
	case IO_REPARSE_TAG_AF_UNIX:
	case IO_REPARSE_TAG_LX_FIFO:
	case IO_REPARSE_TAG_LX_CHR:
	case IO_REPARSE_TAG_LX_BLK:
		if (!valid_reparse_buffer(ni, reparse_attr, size, 0))
			return false;
		if (le16_to_cpu(reparse_attr->reparse_data_length) ||
		    !(ni->flags & FILE_ATTRIBUTE_RECALL_ON_OPEN))
			return false;
		break;
	case IO_REPARSE_TAG_WOF: {
		if (!valid_reparse_buffer(ni, reparse_attr, size,
					  sizeof(struct wof_reparse_data)))
			return false;
		break;
	}
	default:
		if (!valid_reparse_buffer(ni, reparse_attr, size, 0))
			return false;
		break;
	}

	return true;
}

static unsigned int ntfs_reparse_tag_mode(__le32 reparse_tag)
{
	unsigned int mode = 0;

	switch (reparse_tag) {
	case IO_REPARSE_TAG_MOUNT_POINT:
	case IO_REPARSE_TAG_SYMLINK:
	case IO_REPARSE_TAG_LX_SYMLINK:
		mode = S_IFLNK;
		break;
	case IO_REPARSE_TAG_AF_UNIX:
		mode = S_IFSOCK;
		break;
	case IO_REPARSE_TAG_LX_FIFO:
		mode = S_IFIFO;
		break;
	case IO_REPARSE_TAG_LX_CHR:
		mode = S_IFCHR;
		break;
	case IO_REPARSE_TAG_LX_BLK:
		mode = S_IFBLK;
	}

	return mode;
}

/*
 * Parse reparse point data and initialize its in-memory representation.
 */
int ntfs_parse_reparse(struct ntfs_inode *ni, unsigned int *mode)
{
	s64 attr_size = 0;
	int err = -EINVAL;
	unsigned int lth;
	struct reparse_point *reparse_attr;

	kvfree(ni->target);
	ni->target = NULL;
	ni->reparse_tag = 0;
	ni->reparse_flags = 0;
	*mode = 0;

	reparse_attr = ntfs_attr_readall(ni, AT_REPARSE_POINT, NULL, 0,
					 &attr_size);
	if (IS_ERR(reparse_attr)) {
		err = PTR_ERR(reparse_attr);
		ntfs_error(ni->vol->sb,
			   "Failed to read reparse point: %d.", err);
		return err;
	}
	if (!valid_reparse_data(ni, reparse_attr, attr_size)) {
		ntfs_error(ni->vol->sb, "Invalid reparse point.");
		err = -EFSCORRUPTED;
		goto out;
	}

	switch (reparse_attr->reparse_tag) {
	case IO_REPARSE_TAG_MOUNT_POINT:
	{
		struct mount_point_reparse_data *data =
			(struct mount_point_reparse_data *)reparse_attr->reparse_data;
		const __le16 *name = (const __le16 *)((u8 *)data->path_buffer +
				      le16_to_cpu(data->substitute_name_offset));

		err = ntfs_reparse_target_to_nls(ni->vol,
						 name,
						 le16_to_cpu(data->substitute_name_length),
						 &ni->target);
		break;
	}
	case IO_REPARSE_TAG_SYMLINK:
	{
		struct symlink_reparse_data *data =
			(struct symlink_reparse_data *)reparse_attr->reparse_data;
		const __le16 *name = (const __le16 *)((u8 *)data->path_buffer +
						le16_to_cpu(data->substitute_name_offset));

		err = ntfs_reparse_target_to_nls(ni->vol,
						 name,
						 le16_to_cpu(data->substitute_name_length),
						 &ni->target);
		if (!err)
			ni->reparse_flags = data->flags;
		break;
	}
	case IO_REPARSE_TAG_LX_SYMLINK:
	{
		struct wsl_link_reparse_data *wsl_link_data =
			(struct wsl_link_reparse_data *)reparse_attr->reparse_data;

		if (wsl_link_data->type == cpu_to_le32(2)) {
			lth = le16_to_cpu(reparse_attr->reparse_data_length) -
				  sizeof(wsl_link_data->type);
			ni->target = kvzalloc(lth + 1, GFP_NOFS);
			if (ni->target) {
				memcpy(ni->target, wsl_link_data->link, lth);
				ni->target[lth] = 0;
				err = 0;
			}
		}
		break;
	}
	case IO_REPARSE_TAG_WOF:
	{
#ifdef CONFIG_NTFS_FS_WOF_COMPRESSION
		const struct wof_reparse_data *wof_data =
			(const struct wof_reparse_data *)reparse_attr->reparse_data;

		ni->itype.compressed.block_size_bits = 0;
		ni->itype.compressed.block_size = 0;
		if (wof_data->version == WOF_CURRENT_VERSION &&
		    wof_data->provider == WOF_PROVIDER_FILE &&
		    wof_data->provider_version ==
			    WOF_PROVIDER_CURRENT_VERSION) {
			switch (wof_data->compression_format) {
			case WOF_COMPRESSION_XPRESS4K:
				ni->itype.compressed.block_size_bits =
					12;
				break;
			case WOF_COMPRESSION_XPRESS8K:
				ni->itype.compressed.block_size_bits =
					13;
				break;
			case WOF_COMPRESSION_XPRESS16K:
				ni->itype.compressed.block_size_bits =
					14;
				break;
			case WOF_COMPRESSION_LZX:
				ni->itype.compressed.block_size_bits =
					15;
				break;
			}
		}
		if (ni->itype.compressed.block_size_bits)
			ni->itype.compressed.block_size =
				1
				<< ni->itype.compressed.block_size_bits;
#endif
		NInoSetWofCompressed(ni);
		VFS_I(ni)->i_mode &= ~0222;
		err = 0;
		break;
	}
	default:
		err = 0;
	}

	if (!err) {
		*mode = ntfs_reparse_tag_mode(
			reparse_attr->reparse_tag);
		ni->reparse_tag = reparse_attr->reparse_tag;
	}

out:
	kvfree(reparse_attr);

	return err;
}

unsigned int ntfs_reparse_tag_dt_types(struct ntfs_volume *vol, unsigned long mref)
{
	s64 attr_size = 0;
	struct reparse_point *reparse_attr;
	unsigned int dt_type = DT_UNKNOWN;
	struct inode *vi;

	vi = ntfs_iget(vol->sb, mref);
	if (IS_ERR(vi))
		return DT_UNKNOWN;

	reparse_attr = (struct reparse_point *)ntfs_attr_readall(NTFS_I(vi),
			AT_REPARSE_POINT, NULL, 0, &attr_size);
	if (IS_ERR(reparse_attr))
		reparse_attr = NULL;

	if (reparse_attr && attr_size >= sizeof(*reparse_attr)) {
		switch (reparse_attr->reparse_tag) {
		case IO_REPARSE_TAG_MOUNT_POINT:
		case IO_REPARSE_TAG_SYMLINK:
		case IO_REPARSE_TAG_LX_SYMLINK:
			dt_type = DT_LNK;
			break;
		case IO_REPARSE_TAG_AF_UNIX:
			dt_type = DT_SOCK;
			break;
		case IO_REPARSE_TAG_LX_FIFO:
			dt_type = DT_FIFO;
			break;
		case IO_REPARSE_TAG_LX_CHR:
			dt_type = DT_CHR;
			break;
		case IO_REPARSE_TAG_LX_BLK:
			dt_type = DT_BLK;
		}
	}

	kvfree(reparse_attr);

	iput(vi);
	return dt_type;
}

static bool ntfs_is_drive_letter(const char *target)
{
	return ((target[0] >= 'A' && target[0] <= 'Z') ||
		(target[0] >= 'a' && target[0] <= 'z')) &&
		target[1] == ':';
}

/*
 * ntfs_translate_symlink_path
 *
 * @dentry: dentry of the symlink/junction being resolved
 * @target: NUL-terminated NLS target string with '\\' already normalized to '/'
 * @translated: out parameter, set to a newly kmalloc'd relative path on success
 *
 * Windows junctions (IO_REPARSE_TAG_MOUNT_POINT) and non-relative symlinks
 * (IO_REPARSE_TAG_SYMLINK without SYMLINK_FLAG_RELATIVE) store substitute
 * names such as "/??/C:/foo", "//?/C:/foo", "/foo", or "C:/foo". Linux
 * cannot continue pathname lookup from those syntaxes, so rewrite them as a
 * path relative to the symlink's containing directory on this NTFS volume,
 * anchored at the volume root via "../".
 *
 * Note: bind-mounted subtrees of the volume may resolve to unexpected
 * locations because the computed "../" depth is relative to the NTFS volume
 * root, not the bind-mounted subtree root.
 *
 * Return: 0 on success with *translated set to a newly allocated string the
 * caller must kfree(); negative errno on failure.
 */
int ntfs_translate_symlink_path(struct dentry *dentry, const char *target,
				char **translated)
{
	char *buf, *link_path, *out, *p;
	const char *path, *tail;
	unsigned int up_levels = 0;
	size_t tail_len, out_len;
	int err;

	if (!dentry || !target || !translated)
		return -EINVAL;

	path = target;
	/* reject UNC path. */
	if (path[0] == '/' && path[1] == '/' &&
	    !(path[2] == '?' && path[3] == '/'))
		return -EOPNOTSUPP;

	/* target starts with "/??/" or "//?/"? */
	if ((path[0] == '/' && path[1] == '?' && path[2] == '?' && path[3] == '/') ||
	    (path[0] == '/' && path[1] == '/' && path[2] == '?' && path[3] == '/'))
		path += 4;

	/* target must start with a drive character or '/'. */
	if (ntfs_is_drive_letter(path)) {
		if (path[2] && path[2] != '/')
			return -EOPNOTSUPP;
		tail = path + 2;
		if (*tail == '/')
			tail++;
	} else if (*path == '/') {
		tail = path + 1;
	} else {
		return -EOPNOTSUPP;
	}

	tail_len = strlen(tail);

	buf = kmalloc(PATH_MAX, GFP_NOFS);
	if (!buf)
		return -ENOMEM;

	link_path = dentry_path_raw(dentry, buf, PATH_MAX);
	if (IS_ERR(link_path)) {
		err = PTR_ERR(link_path);
		goto out;
	}

	/* count '/' after the leading slash. */
	for (p = link_path + 1; *p; p++)
		if (*p == '/')
			up_levels++;

	/* build "./" + ("../" * up_levels) + tail. */
	out_len = 2 + up_levels * 3 + tail_len;
	if (out_len >= PATH_MAX) {
		err = -ENAMETOOLONG;
		goto out;
	}

	out = kmalloc(out_len + 1, GFP_NOFS);
	if (!out) {
		err = -ENOMEM;
		goto out;
	}

	memcpy(out, "./", 2);
	p = out + 2;
	while (up_levels--) {
		memcpy(p, "../", 3);
		p += 3;
	}
	memcpy(p, tail, tail_len + 1);

	*translated = out;
	err = 0;
out:
	kfree(buf);
	return err;
}

/*
 * Set the index for new reparse data
 */
static int set_reparse_index(struct ntfs_inode *ni, struct ntfs_index_context *xr,
		__le32 reparse_tag)
{
	struct reparse_index indx;
	u64 file_id_cpu;
	__le64 file_id;

	file_id_cpu = MK_MREF(ni->mft_no, ni->seq_no);
	file_id = cpu_to_le64(file_id_cpu);
	indx.header.data.vi.data_offset =
		cpu_to_le16(sizeof(struct index_entry_header) + sizeof(struct reparse_index_key));
	indx.header.data.vi.data_length = 0;
	indx.header.data.vi.reservedV = 0;
	indx.header.length = cpu_to_le16(sizeof(struct reparse_index));
	indx.header.key_length = cpu_to_le16(sizeof(struct reparse_index_key));
	indx.header.flags = 0;
	indx.header.reserved = 0;
	indx.key.reparse_tag = reparse_tag;
	/* danger on processors which require proper alignment! */
	memcpy(&indx.key.file_id, &file_id, 8);
	indx.filling = 0;
	ntfs_index_ctx_reinit(xr);

	return ntfs_ie_add(xr, (struct index_entry *)&indx);
}

/*
 * Remove a reparse data index entry if attribute present
 */
static int remove_reparse_index(struct inode *rp, struct ntfs_index_context *xr,
				__le32 *preparse_tag)
{
	struct reparse_index_key key;
	u64 file_id_cpu;
	__le64 file_id;
	s64 size;
	struct ntfs_inode *ni = NTFS_I(rp);
	int err = 0, ret = ni->data_size;

	if (ni->data_size == 0)
		return 0;

	/* read the existing reparse_tag */
	size = ntfs_inode_attr_pread(rp, 0, 4, (char *)preparse_tag);
	if (size != 4)
		return -ENODATA;

	file_id_cpu = MK_MREF(ni->mft_no, ni->seq_no);
	file_id = cpu_to_le64(file_id_cpu);
	key.reparse_tag = *preparse_tag;
	/* danger on processors which require proper alignment! */
	memcpy(&key.file_id, &file_id, 8);
	if (!ntfs_index_lookup(&key, sizeof(struct reparse_index_key), xr)) {
		err = ntfs_index_rm(xr);
		if (err)
			ret = err;
	}
	return ret;
}

/*
 * Open the $Extend/$Reparse file and its index
 */
static struct ntfs_index_context *open_reparse_index(struct ntfs_volume *vol)
{
	struct ntfs_index_context *xr = NULL;
	u64 mref;
	__le16 *uname;
	struct ntfs_name *name = NULL;
	int uname_len;
	struct inode *vi, *dir_vi;

	/* do not use path_name_to inode - could reopen root */
	dir_vi = ntfs_iget(vol->sb, FILE_Extend);
	if (IS_ERR(dir_vi))
		return NULL;

	uname_len = ntfs_nlstoucs(vol, "$Reparse", 8, &uname,
				  NTFS_MAX_NAME_LEN);
	if (uname_len < 0) {
		iput(dir_vi);
		return NULL;
	}

	mutex_lock_nested(&NTFS_I(dir_vi)->mrec_lock, NTFS_EXTEND_MUTEX_PARENT);
	mref = ntfs_lookup_inode_by_name(NTFS_I(dir_vi), uname, uname_len,
					 &name);
	mutex_unlock(&NTFS_I(dir_vi)->mrec_lock);
	kfree(name);
	kmem_cache_free(ntfs_name_cache, uname);
	if (IS_ERR_MREF(mref))
		goto put_dir_vi;

	vi = ntfs_iget(vol->sb, MREF(mref));
	if (IS_ERR(vi))
		goto put_dir_vi;

	xr = ntfs_index_ctx_get(NTFS_I(vi), reparse_index_name, 2);
	if (!xr)
		iput(vi);
put_dir_vi:
	iput(dir_vi);
	return xr;
}


/*
 * Update the reparse data and index
 *
 * The reparse data attribute should have been created, and
 * an existing index is expected if there is an existing value.
 *
 */
static int update_reparse_data(struct ntfs_inode *ni, struct ntfs_index_context *xr,
		char *value, size_t size)
{
	struct inode *rp_inode;
	int err = 0;
	s64 written;
	int oldsize;
	__le32 reparse_tag;
	struct ntfs_inode *rp_ni;

	rp_inode = ntfs_attr_iget(VFS_I(ni), AT_REPARSE_POINT, AT_UNNAMED, 0);
	if (IS_ERR(rp_inode))
		return -EINVAL;
	rp_ni = NTFS_I(rp_inode);

	/* remove the existing reparse data */
	oldsize = remove_reparse_index(rp_inode, xr, &reparse_tag);
	if (oldsize < 0) {
		err = oldsize;
		goto put_rp_inode;
	}

	/* overwrite value if any */
	written = ntfs_inode_attr_pwrite(rp_inode, 0, size, value, false);
	if (written != size) {
		ntfs_error(ni->vol->sb, "Failed to update reparse data\n");
		err = -EIO;
		goto put_rp_inode;
	}

	err = set_reparse_index(ni, xr,
				((const struct reparse_point *)value)->reparse_tag);
	if (err && oldsize > 0) {
		/*
		 * If cannot index, try to remove the reparse
		 * data and log the error. There will be an
		 * inconsistency if removal fails.
		 */
		ntfs_attr_rm(rp_ni);
		ntfs_error(ni->vol->sb,
			   "Failed to index reparse data. Possible corruption.\n");
	}

	mark_mft_record_dirty(ni);
put_rp_inode:
	iput(rp_inode);

	return err;
}

/*
 * Delete a reparse index entry
 */
int ntfs_delete_reparse_index(struct ntfs_inode *ni)
{
	struct inode *vi;
	struct ntfs_index_context *xr;
	struct ntfs_inode *xrni;
	__le32 reparse_tag;
	int err = 0;

	if (!(ni->flags & FILE_ATTR_REPARSE_POINT))
		return 0;

	vi = ntfs_attr_iget(VFS_I(ni), AT_REPARSE_POINT, AT_UNNAMED, 0);
	if (IS_ERR(vi))
		return PTR_ERR(vi);

	/*
	 * read the existing reparse data (the tag is enough)
	 * and un-index it
	 */
	xr = open_reparse_index(ni->vol);
	if (xr) {
		xrni = xr->idx_ni;
		mutex_lock_nested(&xrni->mrec_lock, NTFS_EXTEND_MUTEX_PARENT);
		err = remove_reparse_index(vi, xr, &reparse_tag);
		if (err < 0) {
			ntfs_index_ctx_put(xr);
			mutex_unlock(&xrni->mrec_lock);
			iput(VFS_I(xrni));
			goto out;
		}
		mark_mft_record_dirty(xrni);
		ntfs_index_ctx_put(xr);
		mutex_unlock(&xrni->mrec_lock);
		iput(VFS_I(xrni));
	}

	ni->flags &= ~FILE_ATTR_REPARSE_POINT;
	NInoSetFileNameDirty(ni);
	mark_mft_record_dirty(ni);

out:
	iput(vi);
	return err;
}

/*
 * Set the reparse data from an extended attribute
 */
static int ntfs_set_ntfs_reparse_data(struct ntfs_inode *ni, char *value, size_t size)
{
	int err = 0;
	struct ntfs_inode *xrni;
	struct ntfs_index_context *xr;

	if (!ni)
		return -EINVAL;

	/*
	 * reparse data compatibily with EA is not checked
	 * any more, it is required by Windows 10, but may
	 * lead to problems with earlier versions.
	 */
	if (valid_reparse_data(ni, (const struct reparse_point *)value, size) == false)
		return -EINVAL;

	xr = open_reparse_index(ni->vol);
	if (!xr)
		return -EINVAL;
	xrni = xr->idx_ni;

	if (!ntfs_attr_exist(ni, AT_REPARSE_POINT, AT_UNNAMED, 0)) {
		struct reparse_point rp = {0, };

		/*
		 * no reparse data attribute : add one,
		 * apparently, this does not feed the new value in
		 * Note : NTFS version must be >= 3
		 */
		if (ni->vol->major_ver < 3) {
			err = -EOPNOTSUPP;
			ntfs_index_ctx_put(xr);
			goto out;
		}

		err = ntfs_attr_add(ni, AT_REPARSE_POINT, AT_UNNAMED, 0, (u8 *)&rp, sizeof(rp));
		if (err) {
			ntfs_index_ctx_put(xr);
			goto out;
		}
		ni->flags |= FILE_ATTR_REPARSE_POINT;
		NInoSetFileNameDirty(ni);
		mark_mft_record_dirty(ni);
	}

	/* update value and index */
	mutex_lock_nested(&xrni->mrec_lock, NTFS_EXTEND_MUTEX_PARENT);
	err = update_reparse_data(ni, xr, value, size);
	if (err) {
		ni->flags &= ~FILE_ATTR_REPARSE_POINT;
		NInoSetFileNameDirty(ni);
		mark_mft_record_dirty(ni);
	}
	ntfs_index_ctx_put(xr);
	mutex_unlock(&xrni->mrec_lock);

out:
	if (!err)
		mark_mft_record_dirty(xrni);
	iput(VFS_I(xrni));

	return err;
}

/*
 * Set reparse data for a WSL type symlink
 */
int ntfs_reparse_set_wsl_symlink(struct ntfs_inode *ni,
				 const char *target, int target_len)
{
	int err = 0;
	int reparse_len;
	struct reparse_point *reparse;
	struct wsl_link_reparse_data *data;

	reparse_len = sizeof(struct reparse_point) + sizeof(data->type) +
		target_len;
	reparse = kvzalloc(reparse_len, GFP_NOFS);
	if (!reparse)
		return -ENOMEM;

	ni->target = kstrdup(target, GFP_NOFS);
	if (!ni->target) {
		kvfree(reparse);
		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;
}

int ntfs_reparse_set_native_symlink(struct ntfs_inode *ni,
				    const char *target, int target_len)
{
	int err = 0;
	bool is_absolute, prt_sub_shared = true;
	char *sub_name = NULL;
	char *prt_name = NULL;
	__le16 *sub_name_utf16 = NULL;
	__le16 *prt_name_utf16 = NULL;
	int sub_len, prt_len;
	int total_data_len, total_reparse_len;
	struct reparse_point *reparse = NULL;
	struct symlink_reparse_data *data;
	int i;

	/* Determine if target is absolute (starts with drive letter like C:/ or C:\) */
	is_absolute = target_len > 2 &&
		ntfs_is_drive_letter(target) &&
		(target[2] == '/' || target[2] == '\\');


	/* Normalize and prepare NLS paths */
	prt_name = kstrdup(target, GFP_NOFS);
	if (!prt_name)
		return -ENOMEM;

	/* Replace '/' with '\' */
	for (i = 0; i < target_len; i++) {
		if (prt_name[i] == '/')
			prt_name[i] = '\\';
	}

	if (is_absolute) {
		/* Prepend '\??\' to Substitutename */
		sub_name = kmalloc(target_len + 5, GFP_NOFS);
		if (!sub_name) {
			err = -ENOMEM;
			goto out;
		}
		snprintf(sub_name, target_len + 5, "\\??\\%s", prt_name);
		prt_sub_shared = false;
	} else {
		/* For relative symlinks (including absolute paths without drive letters),
		 * SubstituteName and PrintName are identical.
		 */
		sub_name = prt_name;
	}

	/* Convert NLS paths to UTF-16 */
	sub_len = ntfs_nlstoucs(ni->vol, sub_name, strlen(sub_name),
				&sub_name_utf16, PATH_MAX);
	if (sub_len < 0) {
		err = sub_len;
		goto out;
	}

	prt_len = ntfs_nlstoucs(ni->vol, prt_name, strlen(prt_name),
				&prt_name_utf16, PATH_MAX);
	if (prt_len < 0) {
		err = prt_len;
		goto out;
	}

	/* Check for buffer size limits */
	total_data_len = sizeof(struct symlink_reparse_data) +
		(sub_len + prt_len) * sizeof(__le16);
	if (total_data_len > 16384) { /* 16KB max reparse tag size */
		err = -EFBIG;
		goto out;
	}

	total_reparse_len = sizeof(struct reparse_point) + total_data_len;
	reparse = kvzalloc(total_reparse_len, GFP_NOFS);
	if (!reparse) {
		err = -ENOMEM;
		goto out;
	}

	/* Pack fields in reparse buffer */
	reparse->reparse_tag = IO_REPARSE_TAG_SYMLINK;
	reparse->reparse_data_length = cpu_to_le16(total_data_len);
	reparse->reserved = 0;

	data = (struct symlink_reparse_data *)reparse->reparse_data;
	data->substitute_name_offset = 0;
	data->substitute_name_length = cpu_to_le16(sub_len * sizeof(__le16));
	data->print_name_offset = data->substitute_name_length;
	data->print_name_length = cpu_to_le16(prt_len * sizeof(__le16));
	data->flags = is_absolute ? 0 : cpu_to_le32(SYMLINK_FLAG_RELATIVE);

	/* Copy names to path_buffer */
	memcpy(data->path_buffer, sub_name_utf16, sub_len * sizeof(__le16));
	memcpy(data->path_buffer + sub_len, prt_name_utf16, prt_len * sizeof(__le16));

	err = ntfs_set_ntfs_reparse_data(ni, (char *)reparse, total_reparse_len);
	if (!err) {
		strreplace(sub_name, '\\', '/');
		ni->target = sub_name;
		sub_name = NULL;
		if (prt_sub_shared)
			prt_name = NULL;
		ni->reparse_tag = IO_REPARSE_TAG_SYMLINK;
		ni->reparse_flags = is_absolute ? 0 :
			cpu_to_le32(SYMLINK_FLAG_RELATIVE);
	}

out:
	kfree(prt_name);
	if (!prt_sub_shared)
		kfree(sub_name);
	kvfree(sub_name_utf16);
	kvfree(prt_name_utf16);
	kvfree(reparse);
	return err;
}

/*
 * Set reparse data for a WSL special file other than a symlink
 * (socket, fifo, character or block device)
 */
int ntfs_reparse_set_wsl_not_symlink(struct ntfs_inode *ni, mode_t mode)
{
	int err;
	int len;
	int reparse_len;
	__le32 reparse_tag;
	struct reparse_point *reparse;

	len = 0;
	if (S_ISSOCK(mode))
		reparse_tag = IO_REPARSE_TAG_AF_UNIX;
	else if (S_ISFIFO(mode))
		reparse_tag = IO_REPARSE_TAG_LX_FIFO;
	else if (S_ISCHR(mode))
		reparse_tag = IO_REPARSE_TAG_LX_CHR;
	else if (S_ISBLK(mode))
		reparse_tag = IO_REPARSE_TAG_LX_BLK;
	else
		return -EOPNOTSUPP;

	reparse_len = sizeof(struct reparse_point) + len;
	reparse = kvzalloc(reparse_len, GFP_NOFS);
	if (!reparse)
		err = -ENOMEM;
	else {
		reparse->reparse_tag = reparse_tag;
		reparse->reparse_data_length = cpu_to_le16(len);
		reparse->reserved = cpu_to_le16(0);
		err = ntfs_set_ntfs_reparse_data(ni, (char *)reparse,
						 reparse_len);
		kvfree(reparse);
		if (!err) {
			ni->reparse_tag = reparse_tag;
			ni->reparse_flags = 0;
		}
	}

	return err;
}
