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

#include <linux/fs.h>
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
#include <linux/xattr.h>

#include "layout.h"
#include "attrib.h"
#include "index.h"
#include "dir.h"
#include "ea.h"

static int ntfs_write_ea(struct ntfs_inode *ni, __le32 type, char *value, s64 ea_off,
		s64 ea_size, bool need_truncate)
{
	struct inode *ea_vi;
	int err = 0;
	s64 written;

	ea_vi = ntfs_attr_iget(VFS_I(ni), type, AT_UNNAMED, 0);
	if (IS_ERR(ea_vi))
		return PTR_ERR(ea_vi);

	written = ntfs_inode_attr_pwrite(ea_vi, ea_off, ea_size, value, false);
	if (written != ea_size)
		err = -EIO;
	else {
		struct ntfs_inode *ea_ni = NTFS_I(ea_vi);

		if (need_truncate && ea_ni->data_size > ea_off + ea_size)
			ntfs_attr_truncate(ea_ni, ea_off + ea_size);
		mark_mft_record_dirty(ni);
	}

	iput(ea_vi);
	return err;
}

static int ntfs_ea_lookup(char *ea_buf, s64 ea_buf_size, const char *name,
			  int name_len, s64 *ea_offset, s64 *ea_size)
{
	const struct ea_attr *p_ea;
	size_t actual_size;
	loff_t offset, p_ea_size;
	unsigned int next;

	offset = 0;
	do {
		if (ea_buf_size - offset < sizeof(struct ea_attr))
			break;

		p_ea = (const struct ea_attr *)&ea_buf[offset];
		next = le32_to_cpu(p_ea->next_entry_offset);
		p_ea_size = next ? next : (ea_buf_size - offset);

		if (p_ea_size < sizeof(struct ea_attr) ||
		    offset + p_ea_size > ea_buf_size)
			break;

		if ((s64)p_ea->ea_name_length + 1 >
		    p_ea_size - offsetof(struct ea_attr, ea_name))
			break;

		actual_size = ALIGN(struct_size(p_ea, ea_name, 1 + p_ea->ea_name_length +
					le16_to_cpu(p_ea->ea_value_length)), 4);
		if (actual_size > p_ea_size)
			break;

		if (p_ea->ea_name_length == name_len &&
		    !memcmp(p_ea->ea_name, name, name_len)) {
			*ea_offset = offset;
			*ea_size = next ? next : actual_size;

			if (ea_buf_size < *ea_offset + *ea_size)
				goto out;

			return 0;
		}
		offset += next;
	} while (next > 0 && offset < ea_buf_size);

out:
	return -ENOENT;
}

/*
 * Return the existing EA
 *
 * The EA_INFORMATION is not examined and the consistency of the
 * existing EA is not checked.
 *
 * If successful, the full attribute is returned unchanged
 * and its size is returned.
 * If the designated buffer is too small, the needed size is
 * returned, and the buffer is left unchanged.
 * If there is an error, a negative value is returned and errno
 * is set according to the error.
 */
static int ntfs_get_ea(struct inode *inode, const char *name, size_t name_len,
		void *buffer, size_t size)
{
	struct ntfs_inode *ni = NTFS_I(inode);
	const struct ea_attr *p_ea;
	char *ea_buf;
	s64 ea_off, ea_size, all_ea_size, ea_info_size;
	int err;
	u32 ea_info_qlen;
	u16 ea_value_len;
	struct ea_information *p_ea_info;

	if (!NInoHasEA(ni))
		return -ENODATA;

	p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
			&ea_info_size);
	if (!p_ea_info || ea_info_size != sizeof(struct ea_information)) {
		kvfree(p_ea_info);
		return -ENODATA;
	}

	ea_info_qlen = le32_to_cpu(p_ea_info->ea_query_length);
	kvfree(p_ea_info);

	ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
	if (!ea_buf)
		return -ENODATA;

	if (ea_info_qlen > all_ea_size) {
		err = -EIO;
		goto free_ea_buf;
	}

	err = ntfs_ea_lookup(ea_buf, ea_info_qlen, name, name_len, &ea_off,
			&ea_size);
	if (!err) {
		p_ea = (struct ea_attr *)&ea_buf[ea_off];
		ea_value_len = le16_to_cpu(p_ea->ea_value_length);
		if (!buffer) {
			kvfree(ea_buf);
			return ea_value_len;
		}

		if (ea_value_len > size) {
			err = -ERANGE;
			goto free_ea_buf;
		}

		memcpy(buffer, &p_ea->ea_name[p_ea->ea_name_length + 1],
				ea_value_len);
		kvfree(ea_buf);
		return ea_value_len;
	}

	err = -ENODATA;
free_ea_buf:
	kvfree(ea_buf);
	return err;
}

static inline int ea_packed_size(const struct ea_attr *p_ea)
{
	/*
	 * 4 bytes for header (flags and lengths) + name length + 1 +
	 * value length.
	 */
	return 5 + p_ea->ea_name_length + le16_to_cpu(p_ea->ea_value_length);
}

/*
 * Set a new EA, and set EA_INFORMATION accordingly
 *
 * This is roughly the same as ZwSetEaFile() on Windows, however
 * the "offset to next" of the last EA should not be cleared.
 *
 * Consistency of the new EA is first checked.
 *
 * EA_INFORMATION is set first, and it is restored to its former
 * state if setting EA fails.
 */
static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
		const void *value, size_t val_size, int flags,
		__le16 *packed_ea_size)
{
	struct ntfs_inode *ni = NTFS_I(inode);
	struct ea_information *p_ea_info = NULL;
	int ea_packed, err = 0;
	struct ea_attr *p_ea;
	u32 ea_info_qsize = 0;
	char *ea_buf = NULL;
	size_t new_ea_size = ALIGN(struct_size(p_ea, ea_name, 1 + name_len + val_size), 4);
	s64 ea_off, ea_info_size, all_ea_size, ea_size;

	if (name_len > 255)
		return -ENAMETOOLONG;

	if (ntfs_attr_exist(ni, AT_EA_INFORMATION, AT_UNNAMED, 0)) {
		p_ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
						&ea_info_size);
		if (!p_ea_info || ea_info_size != sizeof(struct ea_information))
			goto out;

		ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &all_ea_size);
		if (!ea_buf) {
			ea_info_qsize = 0;
			kvfree(p_ea_info);
			goto create_ea_info;
		}

		ea_info_qsize = le32_to_cpu(p_ea_info->ea_query_length);
	} else {
create_ea_info:
		p_ea_info = kzalloc(sizeof(struct ea_information), GFP_NOFS);
		if (!p_ea_info)
			return -ENOMEM;

		ea_info_qsize = 0;
		err = ntfs_attr_add(ni, AT_EA_INFORMATION, AT_UNNAMED, 0,
				(char *)p_ea_info, sizeof(struct ea_information));
		if (err)
			goto out;

		if (ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
			err = ntfs_attr_remove(ni, AT_EA, AT_UNNAMED, 0);
			if (err)
				goto out;
		}

		goto alloc_new_ea;
	}

	if (ea_info_qsize > all_ea_size) {
		err = -EIO;
		goto out;
	}

	err = ntfs_ea_lookup(ea_buf, ea_info_qsize, name, name_len, &ea_off,
			&ea_size);
	if (ea_info_qsize && !err) {
		if (flags & XATTR_CREATE) {
			err = -EEXIST;
			goto out;
		}

		p_ea = (struct ea_attr *)(ea_buf + ea_off);

		if (val_size &&
		    le16_to_cpu(p_ea->ea_value_length) == val_size &&
		    !memcmp(p_ea->ea_name + p_ea->ea_name_length + 1, value,
			    val_size))
			goto out;

		le16_add_cpu(&p_ea_info->ea_length, 0 - ea_packed_size(p_ea));

		if (p_ea->flags & NEED_EA)
			le16_add_cpu(&p_ea_info->need_ea_count, -1);

		memmove((char *)p_ea, (char *)p_ea + ea_size, ea_info_qsize - (ea_off + ea_size));
		ea_info_qsize -= ea_size;
		p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize);

		err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info, 0,
				sizeof(struct ea_information), false);
		if (err)
			goto out;

		err = ntfs_write_ea(ni, AT_EA, ea_buf, 0, ea_info_qsize, true);
		if (err)
			goto out;

		if ((flags & XATTR_REPLACE) && !val_size) {
			/* Remove xattr. */
			goto out;
		}
	} else {
		if (flags & XATTR_REPLACE) {
			err = -ENODATA;
			goto out;
		}
	}
	kvfree(ea_buf);

alloc_new_ea:
	ea_buf = kzalloc(new_ea_size, GFP_NOFS);
	if (!ea_buf) {
		err = -ENOMEM;
		goto out;
	}

	/*
	 * EA and REPARSE_POINT compatibility not checked any more,
	 * required by Windows 10, but having both may lead to
	 * problems with earlier versions.
	 */
	p_ea = (struct ea_attr *)ea_buf;
	memcpy(p_ea->ea_name, name, name_len);
	p_ea->ea_name_length = name_len;
	p_ea->ea_name[name_len] = 0;
	memcpy(p_ea->ea_name + name_len + 1, value, val_size);
	p_ea->ea_value_length = cpu_to_le16(val_size);
	p_ea->next_entry_offset = cpu_to_le32(new_ea_size);

	ea_packed = le16_to_cpu(p_ea_info->ea_length) + ea_packed_size(p_ea);
	p_ea_info->ea_length = cpu_to_le16(ea_packed);
	p_ea_info->ea_query_length = cpu_to_le32(ea_info_qsize + new_ea_size);

	if (ea_packed > 0xffff ||
	    ntfs_attr_size_bounds_check(ni->vol, AT_EA, new_ea_size)) {
		err = -EFBIG;
		goto out;
	}

	/*
	 * no EA or EA_INFORMATION : add them
	 */
	if (!ntfs_attr_exist(ni, AT_EA, AT_UNNAMED, 0)) {
		err = ntfs_attr_add(ni, AT_EA, AT_UNNAMED, 0, (char *)p_ea,
				new_ea_size);
		if (err)
			goto out;
	} else {
		err = ntfs_write_ea(ni, AT_EA, (char *)p_ea, ea_info_qsize,
				new_ea_size, false);
		if (err)
			goto out;
	}

	err = ntfs_write_ea(ni, AT_EA_INFORMATION, (char *)p_ea_info, 0,
			sizeof(struct ea_information), false);
	if (err)
		goto out;

	if (packed_ea_size)
		*packed_ea_size = p_ea_info->ea_length;
	mark_mft_record_dirty(ni);
out:
	if (ea_info_qsize > 0)
		NInoSetHasEA(ni);
	else
		NInoClearHasEA(ni);

	kvfree(ea_buf);
	kvfree(p_ea_info);

	return err;
}

/*
 * Check for the presence of an EA "$LXDEV" (used by WSL)
 * and return its value as a device address
 */
int ntfs_ea_get_wsl_inode(struct inode *inode, dev_t *rdevp, unsigned int flags)
{
	int err;
	__le32 v;

	if (!(flags & NTFS_VOL_UID)) {
		/* Load uid to lxuid EA */
		err = ntfs_get_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
				sizeof(v));
		if (err < 0)
			return err;
		if (err != sizeof(v))
			return -EIO;
		i_uid_write(inode, le32_to_cpu(v));
	}

	if (!(flags & NTFS_VOL_GID)) {
		/* Load gid to lxgid EA */
		err = ntfs_get_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
				sizeof(v));
		if (err < 0)
			return err;
		if (err != sizeof(v))
			return -EIO;
		i_gid_write(inode, le32_to_cpu(v));
	}

	/* Load mode to lxmod EA */
	err = ntfs_get_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v, sizeof(v));
	if (err == sizeof(v)) {
		inode->i_mode = le32_to_cpu(v);
	} else {
		/* Everyone gets all permissions. */
		inode->i_mode |= 0777;
	}

	/* Load mode to lxdev EA */
	err = ntfs_get_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v));
	if (err == sizeof(v))
		*rdevp = le32_to_cpu(v);
	err = 0;

	return err;
}

int ntfs_ea_set_wsl_inode(struct inode *inode, dev_t rdev, __le16 *ea_size,
		unsigned int flags)
{
	__le32 v;
	int err = 0;

	if (ea_size)
		*ea_size = 0;

	if (flags & NTFS_EA_UID) {
		/* Store uid to lxuid EA */
		v = cpu_to_le32(i_uid_read(inode));
		err = ntfs_set_ea(inode, "$LXUID", sizeof("$LXUID") - 1, &v,
				sizeof(v), 0, ea_size);
		if (err)
			return err;
	}

	if (flags & NTFS_EA_GID) {
		/* Store gid to lxgid EA */
		v = cpu_to_le32(i_gid_read(inode));
		err = ntfs_set_ea(inode, "$LXGID", sizeof("$LXGID") - 1, &v,
				sizeof(v), 0, ea_size);
		if (err)
			return err;
	}

	if (flags & NTFS_EA_MODE) {
		/* Store mode to lxmod EA */
		v = cpu_to_le32(inode->i_mode);
		err = ntfs_set_ea(inode, "$LXMOD", sizeof("$LXMOD") - 1, &v,
				sizeof(v), 0, ea_size);
		if (err)
			return err;
	}

	if (rdev) {
		v = cpu_to_le32(rdev);
		err = ntfs_set_ea(inode, "$LXDEV", sizeof("$LXDEV") - 1, &v, sizeof(v),
				0, ea_size);
	}

	return err;
}

ssize_t ntfs_listxattr(struct dentry *dentry, char *buffer, size_t size)
{
	struct inode *inode = d_inode(dentry);
	struct ntfs_inode *ni = NTFS_I(inode);
	const struct ea_attr *p_ea;
	s64 offset, ea_buf_size, ea_info_size;
	s64 ea_size;
	u32 next;
	int err = 0;
	u32 ea_info_qsize;
	char *ea_buf = NULL;
	ssize_t ret = 0;
	struct ea_information *ea_info;

	if (!NInoHasEA(ni))
		return 0;

	mutex_lock(&NTFS_I(inode)->mrec_lock);
	ea_info = ntfs_attr_readall(ni, AT_EA_INFORMATION, NULL, 0,
			&ea_info_size);
	if (!ea_info || ea_info_size != sizeof(struct ea_information))
		goto out;

	ea_info_qsize = le32_to_cpu(ea_info->ea_query_length);

	ea_buf = ntfs_attr_readall(ni, AT_EA, NULL, 0, &ea_buf_size);
	if (!ea_buf)
		goto out;

	if (ea_info_qsize > ea_buf_size || ea_info_qsize == 0)
		goto out;

	offset = 0;
	do {
		if (ea_info_qsize - offset < sizeof(struct ea_attr)) {
			err = -EIO;
			goto out;
		}

		p_ea = (const struct ea_attr *)&ea_buf[offset];
		next = le32_to_cpu(p_ea->next_entry_offset);
		ea_size = next ? next : (ea_info_qsize - offset);

		if (ea_size < sizeof(struct ea_attr) ||
		    offset + ea_size > ea_info_qsize) {
			err = -EIO;
			goto out;
		}

		if ((int)p_ea->ea_name_length + 1 >
			ea_size - offsetof(struct ea_attr, ea_name)) {
			err = -EIO;
			goto out;
		}

		if (buffer) {
			if (ret + p_ea->ea_name_length + 1 > size) {
				err = -ERANGE;
				goto out;
			}

			memcpy(buffer + ret, p_ea->ea_name, p_ea->ea_name_length);
			buffer[ret + p_ea->ea_name_length] = 0;
		}

		ret += p_ea->ea_name_length + 1;
		offset += ea_size;
	} while (next > 0 && offset < ea_info_qsize);

out:
	mutex_unlock(&NTFS_I(inode)->mrec_lock);
	kvfree(ea_info);
	kvfree(ea_buf);

	return err ? err : ret;
}

// clang-format off
#define SYSTEM_DOS_ATTRIB     "system.dos_attrib"
#define SYSTEM_NTFS_ATTRIB    "system.ntfs_attrib"
#define SYSTEM_NTFS_ATTRIB_BE "system.ntfs_attrib_be"
// clang-format on

static int ntfs_getxattr(const struct xattr_handler *handler,
		struct dentry *unused, struct inode *inode, const char *name,
		void *buffer, size_t size)
{
	struct ntfs_inode *ni = NTFS_I(inode);
	int err;

	if (NVolShutdown(ni->vol))
		return -EIO;

	if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
		if (!buffer) {
			err = sizeof(u8);
		} else if (size < sizeof(u8)) {
			err = -ENODATA;
		} else {
			err = sizeof(u8);
			*(u8 *)buffer = (u8)(le32_to_cpu(ni->flags) & 0x3F);
		}
		goto out;
	}

	if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
	    !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
		if (!buffer) {
			err = sizeof(u32);
		} else if (size < sizeof(u32)) {
			err = -ENODATA;
		} else {
			err = sizeof(u32);
			*(u32 *)buffer = le32_to_cpu(ni->flags);
			if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
				*(__be32 *)buffer = cpu_to_be32(*(u32 *)buffer);
		}
		goto out;
	}

	mutex_lock(&ni->mrec_lock);
	err = ntfs_get_ea(inode, name, strlen(name), buffer, size);
	mutex_unlock(&ni->mrec_lock);

out:
	return err;
}

static int ntfs_new_attr_flags(struct ntfs_inode *ni, __le32 fattr)
{
	struct ntfs_attr_search_ctx *ctx;
	struct mft_record *m;
	struct attr_record *a;
	__le16 new_aflags;
	int mp_size, mp_ofs, name_ofs, arec_size, err;

	m = map_mft_record(ni);
	if (IS_ERR(m))
		return PTR_ERR(m);

	ctx = ntfs_attr_get_search_ctx(ni, m);
	if (!ctx) {
		err = -ENOMEM;
		goto err_out;
	}

	err = ntfs_attr_lookup(ni->type, ni->name, ni->name_len,
			CASE_SENSITIVE, 0, NULL, 0, ctx);
	if (err) {
		err = -EINVAL;
		goto err_out;
	}

	a = ctx->attr;
	new_aflags = ctx->attr->flags;

	if (fattr & FILE_ATTR_SPARSE_FILE)
		new_aflags |= ATTR_IS_SPARSE;
	else
		new_aflags &= ~ATTR_IS_SPARSE;

	if (fattr & FILE_ATTR_COMPRESSED)
		new_aflags |= ATTR_IS_COMPRESSED;
	else
		new_aflags &= ~ATTR_IS_COMPRESSED;

	if (new_aflags == a->flags)
		return 0;

	if ((new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) ==
			  (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
		pr_err("file can't be sparsed and compressed\n");
		err = -EOPNOTSUPP;
		goto err_out;
	}

	if (!a->non_resident)
		goto out;

	if (a->data.non_resident.data_size) {
		pr_err("Can't change sparsed/compressed for non-empty file\n");
		err = -EOPNOTSUPP;
		goto err_out;
	}

	if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED))
		name_ofs = (offsetof(struct attr_record,
				     data.non_resident.compressed_size) +
					sizeof(a->data.non_resident.compressed_size) + 7) & ~7;
	else
		name_ofs = (offsetof(struct attr_record,
				     data.non_resident.compressed_size) + 7) & ~7;

	mp_size = ntfs_get_size_for_mapping_pairs(ni->vol, ni->runlist.rl, 0, -1, -1);
	if (unlikely(mp_size < 0)) {
		err = mp_size;
		ntfs_debug("Failed to get size for mapping pairs array, error code %i.\n", err);
		goto err_out;
	}

	mp_ofs = (name_ofs + a->name_length * sizeof(__le16) + 7) & ~7;
	arec_size = (mp_ofs + mp_size + 7) & ~7;

	err = ntfs_attr_record_resize(m, a, arec_size);
	if (unlikely(err))
		goto err_out;

	if (new_aflags & (ATTR_IS_SPARSE | ATTR_IS_COMPRESSED)) {
		a->data.non_resident.compression_unit = 0;
		if (new_aflags & ATTR_IS_COMPRESSED || ni->vol->major_ver < 3)
			a->data.non_resident.compression_unit = 4;
		a->data.non_resident.compressed_size = 0;
		ni->itype.compressed.size = 0;
		if (a->data.non_resident.compression_unit) {
			ni->itype.compressed.block_size = 1U <<
				(a->data.non_resident.compression_unit +
				 ni->vol->cluster_size_bits);
			ni->itype.compressed.block_size_bits =
					ffs(ni->itype.compressed.block_size) -
					1;
			ni->itype.compressed.block_clusters = 1U <<
					a->data.non_resident.compression_unit;
		} else {
			ni->itype.compressed.block_size = 0;
			ni->itype.compressed.block_size_bits = 0;
			ni->itype.compressed.block_clusters = 0;
		}

		if (new_aflags & ATTR_IS_SPARSE) {
			NInoSetSparse(ni);
			ni->flags |= FILE_ATTR_SPARSE_FILE;
		}

		if (new_aflags & ATTR_IS_COMPRESSED) {
			NInoSetCompressed(ni);
			ni->flags |= FILE_ATTR_COMPRESSED;
		}
	} else {
		ni->flags &= ~(FILE_ATTR_SPARSE_FILE | FILE_ATTR_COMPRESSED);
		a->data.non_resident.compression_unit = 0;
		NInoClearSparse(ni);
		NInoClearCompressed(ni);
	}

	a->name_offset = cpu_to_le16(name_ofs);
	a->data.non_resident.mapping_pairs_offset = cpu_to_le16(mp_ofs);

out:
	a->flags = new_aflags;
	mark_mft_record_dirty(ctx->ntfs_ino);
err_out:
	if (ctx)
		ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(ni);
	return err;
}

static int ntfs_setxattr(const struct xattr_handler *handler,
		struct mnt_idmap *idmap, struct dentry *unused,
		struct inode *inode, const char *name, const void *value,
		size_t size, int flags)
{
	struct ntfs_inode *ni = NTFS_I(inode);
	int err;
	__le32 fattr;

	if (NVolShutdown(ni->vol))
		return -EIO;

	if (!strcmp(name, SYSTEM_DOS_ATTRIB)) {
		if (sizeof(u8) != size) {
			err = -EINVAL;
			goto out;
		}
		fattr = cpu_to_le32(*(u8 *)value);
		goto set_fattr;
	}

	if (!strcmp(name, SYSTEM_NTFS_ATTRIB) ||
	    !strcmp(name, SYSTEM_NTFS_ATTRIB_BE)) {
		if (size != sizeof(u32)) {
			err = -EINVAL;
			goto out;
		}
		if (!strcmp(name, SYSTEM_NTFS_ATTRIB_BE))
			fattr = cpu_to_le32(be32_to_cpu(*(__be32 *)value));
		else
			fattr = cpu_to_le32(*(u32 *)value);

		if (S_ISREG(inode->i_mode)) {
			mutex_lock(&ni->mrec_lock);
			err = ntfs_new_attr_flags(ni, fattr);
			mutex_unlock(&ni->mrec_lock);
			if (err)
				goto out;
		}

set_fattr:
		if (S_ISDIR(inode->i_mode))
			fattr |= FILE_ATTR_DIRECTORY;
		else
			fattr &= ~FILE_ATTR_DIRECTORY;

		if (ni->flags != fattr) {
			ni->flags = fattr;
			if (fattr & FILE_ATTR_READONLY)
				inode->i_mode &= ~0222;
			else
				inode->i_mode |= 0222;
			NInoSetFileNameDirty(ni);
			mark_inode_dirty(inode);
		}
		err = 0;
		goto out;
	}

	mutex_lock(&ni->mrec_lock);
	err = ntfs_set_ea(inode, name, strlen(name), value, size, flags, NULL);
	mutex_unlock(&ni->mrec_lock);

out:
	inode_set_ctime_current(inode);
	mark_inode_dirty(inode);
	return err;
}

static bool ntfs_xattr_user_list(struct dentry *dentry)
{
	return true;
}

// clang-format off
static const struct xattr_handler ntfs_other_xattr_handler = {
	.prefix	= "",
	.get	= ntfs_getxattr,
	.set	= ntfs_setxattr,
	.list	= ntfs_xattr_user_list,
};

const struct xattr_handler * const ntfs_xattr_handlers[] = {
	&ntfs_other_xattr_handler,
	NULL,
};
// clang-format on

#ifdef CONFIG_NTFS_FS_POSIX_ACL
struct posix_acl *ntfs_get_acl(struct mnt_idmap *idmap, struct dentry *dentry,
			       int type)
{
	struct inode *inode = d_inode(dentry);
	struct ntfs_inode *ni = NTFS_I(inode);
	const char *name;
	size_t name_len;
	struct posix_acl *acl;
	int err;
	void *buf;

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

	/* Possible values of 'type' was already checked above. */
	if (type == ACL_TYPE_ACCESS) {
		name = XATTR_NAME_POSIX_ACL_ACCESS;
		name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
	} else {
		name = XATTR_NAME_POSIX_ACL_DEFAULT;
		name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
	}

	mutex_lock(&ni->mrec_lock);
	err = ntfs_get_ea(inode, name, name_len, buf, PATH_MAX);
	mutex_unlock(&ni->mrec_lock);

	/* Translate extended attribute to acl. */
	if (err >= 0)
		acl = posix_acl_from_xattr(&init_user_ns, buf, err);
	else if (err == -ENODATA)
		acl = NULL;
	else
		acl = ERR_PTR(err);

	if (!IS_ERR(acl))
		set_cached_acl(inode, type, acl);

	kfree(buf);

	return acl;
}

static noinline int ntfs_set_acl_ex(struct mnt_idmap *idmap,
				    struct inode *inode, struct posix_acl *acl,
				    int type, bool init_acl)
{
	const char *name;
	size_t size, name_len;
	void *value;
	int err;
	int flags;
	umode_t mode;

	if (S_ISLNK(inode->i_mode))
		return -EOPNOTSUPP;

	mode = inode->i_mode;
	switch (type) {
	case ACL_TYPE_ACCESS:
		/* Do not change i_mode if we are in init_acl */
		if (acl && !init_acl) {
			err = posix_acl_update_mode(idmap, inode, &mode, &acl);
			if (err)
				return err;
		}
		name = XATTR_NAME_POSIX_ACL_ACCESS;
		name_len = sizeof(XATTR_NAME_POSIX_ACL_ACCESS) - 1;
		break;

	case ACL_TYPE_DEFAULT:
		if (!S_ISDIR(inode->i_mode))
			return acl ? -EACCES : 0;
		name = XATTR_NAME_POSIX_ACL_DEFAULT;
		name_len = sizeof(XATTR_NAME_POSIX_ACL_DEFAULT) - 1;
		break;

	default:
		return -EINVAL;
	}

	if (!acl) {
		/* Remove xattr if it can be presented via mode. */
		size = 0;
		value = NULL;
		flags = XATTR_REPLACE;
	} else {
		value = posix_acl_to_xattr(&init_user_ns, acl, &size, GFP_NOFS);
		if (!value)
			return -ENOMEM;
		flags = 0;
	}

	mutex_lock(&NTFS_I(inode)->mrec_lock);
	err = ntfs_set_ea(inode, name, name_len, value, size, flags, NULL);
	mutex_unlock(&NTFS_I(inode)->mrec_lock);
	if (err == -ENODATA && !size)
		err = 0; /* Removing non existed xattr. */
	if (!err) {
		__le16 ea_size = 0;
		umode_t old_mode = inode->i_mode;

		inode->i_mode = mode;
		mutex_lock(&NTFS_I(inode)->mrec_lock);
		err = ntfs_ea_set_wsl_inode(inode, 0, &ea_size, NTFS_EA_MODE);
		if (err) {
			ntfs_set_ea(inode, name, name_len, NULL, 0,
				    XATTR_REPLACE, NULL);
			mutex_unlock(&NTFS_I(inode)->mrec_lock);
			inode->i_mode = old_mode;
			goto out;
		}
		mutex_unlock(&NTFS_I(inode)->mrec_lock);

		set_cached_acl(inode, type, acl);
		inode_set_ctime_current(inode);
		mark_inode_dirty(inode);
	}

out:
	kfree(value);

	return err;
}

int ntfs_set_acl(struct mnt_idmap *idmap, struct dentry *dentry,
		 struct posix_acl *acl, int type)
{
	return ntfs_set_acl_ex(idmap, d_inode(dentry), acl, type, false);
}

int ntfs_init_acl(struct mnt_idmap *idmap, struct inode *inode,
		  struct inode *dir)
{
	struct posix_acl *default_acl, *acl;
	int err;

	err = posix_acl_create(dir, &inode->i_mode, &default_acl, &acl);
	if (err)
		return err;

	if (default_acl) {
		err = ntfs_set_acl_ex(idmap, inode, default_acl,
				      ACL_TYPE_DEFAULT, true);
		posix_acl_release(default_acl);
	} else {
		inode->i_default_acl = NULL;
	}

	if (acl) {
		if (!err)
			err = ntfs_set_acl_ex(idmap, inode, acl,
					      ACL_TYPE_ACCESS, true);
		posix_acl_release(acl);
	} else {
		inode->i_acl = NULL;
	}

	return err;
}
#endif
