// SPDX-License-Identifier: GPL-2.0
/*
 *
 * Copyright (C) 2019-2021 Paragon Software GmbH, All rights reserved.
 *
 */

#include <linux/fiemap.h>
#include <linux/fs.h>
#include <linux/minmax.h>
#include <linux/vmalloc.h>

#include "debug.h"
#include "ntfs.h"
#include "ntfs_fs.h"
#ifdef CONFIG_NTFS3_LZX_XPRESS
#include "lib/lib.h"
#endif

static struct mft_inode *ni_ins_mi(struct ntfs_inode *ni, struct rb_root *tree,
				   CLST ino, struct rb_node *ins)
{
	struct rb_node **p = &tree->rb_node;
	struct rb_node *pr = NULL;

	while (*p) {
		struct mft_inode *mi;

		pr = *p;
		mi = rb_entry(pr, struct mft_inode, node);
		if (mi->rno > ino)
			p = &pr->rb_left;
		else if (mi->rno < ino)
			p = &pr->rb_right;
		else
			return mi;
	}

	if (!ins)
		return NULL;

	rb_link_node(ins, pr, p);
	rb_insert_color(ins, tree);
	return rb_entry(ins, struct mft_inode, node);
}

/*
 * ni_find_mi - Find mft_inode by record number.
 */
static struct mft_inode *ni_find_mi(struct ntfs_inode *ni, CLST rno)
{
	return ni_ins_mi(ni, &ni->mi_tree, rno, NULL);
}

/*
 * ni_add_mi - Add new mft_inode into ntfs_inode.
 */
static void ni_add_mi(struct ntfs_inode *ni, struct mft_inode *mi)
{
	ni_ins_mi(ni, &ni->mi_tree, mi->rno, &mi->node);
}

/*
 * ni_remove_mi - Remove mft_inode from ntfs_inode.
 */
void ni_remove_mi(struct ntfs_inode *ni, struct mft_inode *mi)
{
	rb_erase(&mi->node, &ni->mi_tree);
}

/*
 * ni_std - Return: Pointer into std_info from primary record.
 */
struct ATTR_STD_INFO *ni_std(struct ntfs_inode *ni)
{
	const struct ATTRIB *attr;

	attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL);
	return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO)) :
		      NULL;
}

/*
 * ni_std5
 *
 * Return: Pointer into std_info from primary record.
 */
struct ATTR_STD_INFO5 *ni_std5(struct ntfs_inode *ni)
{
	const struct ATTRIB *attr;

	attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_STD, NULL, 0, NULL);

	return attr ? resident_data_ex(attr, sizeof(struct ATTR_STD_INFO5)) :
		      NULL;
}

/*
 * ni_clear - Clear resources allocated by ntfs_inode.
 */
void ni_clear(struct ntfs_inode *ni)
{
	struct rb_node *node;

	if (!ni->vfs_inode.i_nlink && ni->mi.mrec &&
	    is_rec_inuse(ni->mi.mrec) &&
	    !(ni->mi.sbi->flags & NTFS_FLAGS_LOG_REPLAYING))
		ni_delete_all(ni);

	al_destroy(ni);

	for (node = rb_first(&ni->mi_tree); node;) {
		struct rb_node *next = rb_next(node);
		struct mft_inode *mi = rb_entry(node, struct mft_inode, node);

		rb_erase(node, &ni->mi_tree);
		mi_put(mi);
		node = next;
	}

	/* Bad inode always has mode == S_IFREG. */
	if (ni->ni_flags & NI_FLAG_DIR)
		indx_clear(&ni->dir);
	else {
		run_close(&ni->file.run);
		ntfs_sub_da(ni->mi.sbi, run_len(&ni->file.run_da));
		run_close(&ni->file.run_da);
#ifdef CONFIG_NTFS3_LZX_XPRESS
		if (ni->file.offs_folio) {
			/* On-demand allocated page for offsets. */
			folio_put(ni->file.offs_folio);
			ni->file.offs_folio = NULL;
		}
#endif
		kfree(ni->file.ads.name);
		ni->file.ads.name = NULL;
	}

	if (ni->base && ni->base != ni) {
		iput(&ni->base->vfs_inode);
		ni->base = NULL;
	}

	mi_clear(&ni->mi);
}

/*
 * ni_load_mi_ex - Find mft_inode by record number.
 */
int ni_load_mi_ex(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi)
{
	int err;
	struct mft_inode *r;

	ni = ni->base;
	r = ni_find_mi(ni, rno);
	if (r)
		goto out;

	err = mi_get(ni->mi.sbi, rno, &r);
	if (err) {
		_ntfs_bad_inode(&ni->vfs_inode);
		return err;
	}

	ni_add_mi(ni, r);

out:
	if (mi)
		*mi = r;
	return 0;
}

/*
 * ni_load_mi - Load mft_inode corresponded list_entry.
 */
int ni_load_mi(struct ntfs_inode *ni, const struct ATTR_LIST_ENTRY *le,
	       struct mft_inode **mi)
{
	u64 rno;

	ni = ni->base;
	if (!le) {
		*mi = &ni->mi;
		return 0;
	}

	rno = ino_get(&le->ref);
	if (rno == ni->mi.rno) {
		*mi = &ni->mi;
		return 0;
	}
	return ni_load_mi_ex(ni, rno, mi);
}

/*
 * ni_find_attr
 *
 * Return: Attribute and record this attribute belongs to.
 */
struct ATTRIB *ni_find_attr(struct ntfs_inode *ni, struct ATTRIB *attr,
			    struct ATTR_LIST_ENTRY **le_o, enum ATTR_TYPE type,
			    const __le16 *name, u8 name_len, const CLST *vcn,
			    struct mft_inode **mi)
{
	struct ATTR_LIST_ENTRY *le;
	struct mft_inode *m;

	ni = ni->base;
	if (!ni->attr_list.size ||
	    (!name_len && (type == ATTR_LIST || type == ATTR_STD))) {
		if (le_o)
			*le_o = NULL;
		if (mi)
			*mi = &ni->mi;

		/* Look for required attribute in primary record. */
		return mi_find_attr(ni, &ni->mi, attr, type, name, name_len,
				    NULL);
	}

	/* First look for list entry of required type. */
	le = al_find_ex(ni, le_o ? *le_o : NULL, type, name, name_len, vcn);
	if (!le)
		return NULL;

	if (le_o)
		*le_o = le;

	/* Load record that contains this attribute. */
	if (ni_load_mi(ni, le, &m))
		return NULL;

	/* Look for required attribute. */
	attr = mi_find_attr(ni, m, NULL, type, name, name_len, &le->id);

	if (!attr)
		goto out;

	if (!attr->non_res) {
		if (vcn && *vcn)
			goto out;
	} else if (!vcn) {
		if (attr->nres.svcn)
			goto out;
	} else if (le64_to_cpu(attr->nres.svcn) > *vcn ||
		   *vcn > le64_to_cpu(attr->nres.evcn)) {
		goto out;
	}

	if (mi)
		*mi = m;
	return attr;

out:
	_ntfs_bad_inode(&ni->vfs_inode);
	return NULL;
}

/*
 * ni_enum_attr_ex - Enumerates attributes in ntfs_inode.
 */
struct ATTRIB *ni_enum_attr_ex(struct ntfs_inode *ni, struct ATTRIB *attr,
			       struct ATTR_LIST_ENTRY **le,
			       struct mft_inode **mi)
{
	struct mft_inode *mi2;
	struct ATTR_LIST_ENTRY *le2;

	ni = ni->base;
	/* Do we have an attribute list? */
	if (!ni->attr_list.size) {
		*le = NULL;
		if (mi)
			*mi = &ni->mi;
		/* Enum attributes in primary record. */
		return mi_enum_attr(ni, &ni->mi, attr);
	}

	/* Get next list entry. */
	le2 = *le = al_enumerate(ni, attr ? *le : NULL);
	if (!le2)
		return NULL;

	/* Load record that contains the required attribute. */
	if (ni_load_mi(ni, le2, &mi2))
		return NULL;

	if (mi)
		*mi = mi2;

	/* Find attribute in loaded record. */
	return rec_find_attr_le(ni, mi2, le2);
}

/*
 * ni_load_all_mi - Load all subrecords.
 */
int ni_load_all_mi(struct ntfs_inode *ni)
{
	int err;
	struct ATTR_LIST_ENTRY *le;

	ni = ni->base;
	if (!ni->attr_list.size)
		return 0;

	le = NULL;

	while ((le = al_enumerate(ni, le))) {
		CLST rno = ino_get(&le->ref);

		if (rno == ni->mi.rno)
			continue;

		err = ni_load_mi_ex(ni, rno, NULL);
		if (err)
			return err;
	}

	return 0;
}

/*
 * ni_add_subrecord - Allocate + format + attach a new subrecord.
 */
bool ni_add_subrecord(struct ntfs_inode *ni, CLST rno, struct mft_inode **mi)
{
	struct mft_inode *m;

	ni = ni->base;
	m = kzalloc_obj(struct mft_inode, GFP_NOFS);
	if (!m)
		return false;

	if (mi_format_new(m, ni->mi.sbi, rno, 0, ni->mi.rno == MFT_REC_MFT)) {
		mi_put(m);
		return false;
	}

	mi_get_ref(&ni->mi, &m->mrec->parent_ref);

	*mi = ni_ins_mi(ni, &ni->mi_tree, m->rno, &m->node);
	if (*mi != m)
		mi_put(m);

	return true;
}

/*
 * ni_remove_attr - Remove all attributes for the given type/name/id.
 */
int ni_remove_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
		   const __le16 *name, u8 name_len, bool base_only,
		   const __le16 *id)
{
	int err;
	struct ATTRIB *attr;
	struct ATTR_LIST_ENTRY *le;
	struct mft_inode *mi;
	u32 type_in;
	int diff;

	ni = ni->base;
	if (base_only || type == ATTR_LIST || !ni->attr_list.size) {
		attr = mi_find_attr(ni, &ni->mi, NULL, type, name, name_len,
				    id);
		if (!attr)
			return -ENOENT;

		mi_remove_attr(ni, &ni->mi, attr);
		return 0;
	}

	type_in = le32_to_cpu(type);
	le = NULL;

	for (;;) {
		le = al_enumerate(ni, le);
		if (!le)
			return 0;

next_le2:
		diff = le32_to_cpu(le->type) - type_in;
		if (diff < 0)
			continue;

		if (diff > 0)
			return 0;

		if (le->name_len != name_len)
			continue;

		if (name_len &&
		    memcmp(le_name(le), name, name_len * sizeof(short)))
			continue;

		if (id && le->id != *id)
			continue;
		err = ni_load_mi(ni, le, &mi);
		if (err)
			return err;

		al_remove_le(ni, le);

		attr = mi_find_attr(ni, mi, NULL, type, name, name_len, id);
		if (!attr)
			return -ENOENT;

		mi_remove_attr(ni, mi, attr);

		if (PtrOffset(ni->attr_list.le, le) >= ni->attr_list.size)
			return 0;
		goto next_le2;
	}
}

/*
 * ni_ins_new_attr - Insert the attribute into record.
 *
 * Return: Not full constructed attribute or NULL if not possible to create.
 */
static struct ATTRIB *
ni_ins_new_attr(struct ntfs_inode *ni, struct mft_inode *mi,
		struct ATTR_LIST_ENTRY *le, enum ATTR_TYPE type,
		const __le16 *name, u8 name_len, u32 asize, u16 name_off,
		CLST svcn, struct ATTR_LIST_ENTRY **ins_le)
{
	int err;
	struct ATTRIB *attr;
	bool le_added = false;
	struct MFT_REF ref;

	ni = ni->base;
	mi_get_ref(mi, &ref);

	if (type != ATTR_LIST && !le && ni->attr_list.size) {
		err = al_add_le(ni, type, name, name_len, svcn, cpu_to_le16(-1),
				&ref, &le);
		if (err) {
			/* No memory or no space. */
			return ERR_PTR(err);
		}
		le_added = true;

		/*
		 * al_add_le -> attr_set_size (list) -> ni_expand_list
		 * which moves some attributes out of primary record
		 * this means that name may point into moved memory
		 * reinit 'name' from le.
		 */
		name = le->name;
	}

	attr = mi_insert_attr(ni, mi, type, name, name_len, asize, name_off);
	if (!attr) {
		if (le_added)
			al_remove_le(ni, le);
		return NULL;
	}

	if (type == ATTR_LIST) {
		/* Attr list is not in list entry array. */
		goto out;
	}

	if (!le)
		goto out;

	/* Update ATTRIB Id and record reference. */
	le->id = attr->id;
	ni->attr_list.dirty = true;
	le->ref = ref;

out:
	if (ins_le)
		*ins_le = le;
	return attr;
}

/*
 * ni_repack
 *
 * Random write access to sparsed or compressed file may result to
 * not optimized packed runs.
 * Here is the place to optimize it.
 */
static int ni_repack(struct ntfs_inode *ni)
{
#if 1
	return 0;
#else
	int err = 0;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct mft_inode *mi, *mi_p = NULL;
	struct ATTRIB *attr = NULL, *attr_p;
	struct ATTR_LIST_ENTRY *le = NULL, *le_p;
	CLST alloc = 0;
	u8 cluster_bits = sbi->cluster_bits;
	CLST svcn, evcn = 0, svcn_p, evcn_p, next_svcn;
	u32 roff, rs = sbi->record_size;
	struct runs_tree run;

	run_init(&run);

	while ((attr = ni_enum_attr_ex(ni, attr, &le, &mi))) {
		if (!attr->non_res)
			continue;

		svcn = le64_to_cpu(attr->nres.svcn);
		if (svcn != le64_to_cpu(le->vcn)) {
			err = -EINVAL;
			break;
		}

		if (!svcn) {
			alloc = le64_to_cpu(attr->nres.alloc_size) >>
				cluster_bits;
			mi_p = NULL;
		} else if (svcn != evcn + 1) {
			err = -EINVAL;
			break;
		}

		evcn = le64_to_cpu(attr->nres.evcn);

		if (svcn > evcn + 1) {
			err = -EINVAL;
			break;
		}

		if (!mi_p) {
			/* Do not try if not enough free space. */
			if (le32_to_cpu(mi->mrec->used) + 8 >= rs)
				continue;

			/* Do not try if last attribute segment. */
			if (evcn + 1 == alloc)
				continue;
			run_close(&run);
		}

		roff = le16_to_cpu(attr->nres.run_off);

		if (roff > le32_to_cpu(attr->size)) {
			err = -EINVAL;
			break;
		}

		err = run_unpack(&run, sbi, ni->mi.rno, svcn, evcn, svcn,
				 Add2Ptr(attr, roff),
				 le32_to_cpu(attr->size) - roff);
		if (err < 0)
			break;

		if (!mi_p) {
			mi_p = mi;
			attr_p = attr;
			svcn_p = svcn;
			evcn_p = evcn;
			le_p = le;
			err = 0;
			continue;
		}

		/*
		 * Run contains data from two records: mi_p and mi
		 * Try to pack in one.
		 */
		err = mi_pack_runs(mi_p, attr_p, &run, evcn + 1 - svcn_p);
		if (err)
			break;

		next_svcn = le64_to_cpu(attr_p->nres.evcn) + 1;

		if (next_svcn >= evcn + 1) {
			/* We can remove this attribute segment. */
			al_remove_le(ni, le);
			mi_remove_attr(NULL, mi, attr);
			le = le_p;
			continue;
		}

		attr->nres.svcn = le->vcn = cpu_to_le64(next_svcn);
		mi->dirty = true;
		ni->attr_list.dirty = true;

		if (evcn + 1 == alloc) {
			err = mi_pack_runs(mi, attr, &run,
					   evcn + 1 - next_svcn);
			if (err)
				break;
			mi_p = NULL;
		} else {
			mi_p = mi;
			attr_p = attr;
			svcn_p = next_svcn;
			evcn_p = evcn;
			le_p = le;
			run_truncate_head(&run, next_svcn);
		}
	}

	if (err) {
		ntfs_inode_warn(&ni->vfs_inode, "repack problem");
		ntfs_set_state(sbi, NTFS_DIRTY_ERROR);

		/* Pack loaded but not packed runs. */
		if (mi_p)
			mi_pack_runs(mi_p, attr_p, &run, evcn_p + 1 - svcn_p);
	}

	run_close(&run);
	return err;
#endif
}

/*
 * ni_try_remove_attr_list
 *
 * Can we remove attribute list?
 * Check the case when primary record contains enough space for all attributes.
 */
static int ni_try_remove_attr_list(struct ntfs_inode *ni)
{
	int err = 0;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct ATTRIB *attr, *attr_list, *attr_ins;
	struct ATTR_LIST_ENTRY *le;
	struct mft_inode *mi;
	u32 asize, free;
	struct MFT_REF ref;
	struct MFT_REC *mrec;
	__le16 id;

	ni = ni->base;
	if (!ni->attr_list.dirty)
		return 0;

	err = ni_repack(ni);
	if (err)
		return err;

	attr_list = mi_find_attr(ni, &ni->mi, NULL, ATTR_LIST, NULL, 0, NULL);
	if (!attr_list)
		return 0;

	asize = le32_to_cpu(attr_list->size);

	/* Free space in primary record without attribute list. */
	free = sbi->record_size - le32_to_cpu(ni->mi.mrec->used) + asize;
	mi_get_ref(&ni->mi, &ref);

	le = NULL;
	while ((le = al_enumerate(ni, le))) {
		if (!memcmp(&le->ref, &ref, sizeof(ref)))
			continue;

		if (le->vcn)
			return 0;

		mi = ni_find_mi(ni, ino_get(&le->ref));
		if (!mi)
			return 0;

		attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
				    le->name_len, &le->id);
		if (!attr)
			return 0;

		asize = le32_to_cpu(attr->size);
		if (asize > free)
			return 0;

		free -= asize;
	}

	/* Make a copy of primary record to restore if error. */
	mrec = kmemdup(ni->mi.mrec, sbi->record_size, GFP_NOFS);
	if (!mrec)
		return 0; /* Not critical. */

	/* It seems that attribute list can be removed from primary record. */
	mi_remove_attr(NULL, &ni->mi, attr_list);

	/*
	 * Repeat the cycle above and copy all attributes to primary record.
	 * Do not remove original attributes from subrecords!
	 * It should be success!
	 */
	le = NULL;
	while ((le = al_enumerate(ni, le))) {
		if (!memcmp(&le->ref, &ref, sizeof(ref)))
			continue;

		mi = ni_find_mi(ni, ino_get(&le->ref));
		if (!mi) {
			/* Should never happened, 'cause already checked. */
			goto out;
		}

		attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
				    le->name_len, &le->id);
		if (!attr) {
			/* Should never happened, 'cause already checked. */
			goto out;
		}
		asize = le32_to_cpu(attr->size);

		/* Insert into primary record. */
		attr_ins = mi_insert_attr(ni, &ni->mi, le->type, le_name(le),
					  le->name_len, asize,
					  le16_to_cpu(attr->name_off));
		if (!attr_ins) {
			/*
			 * No space in primary record (already checked).
			 */
			goto out;
		}

		/* Copy all except id. */
		id = attr_ins->id;
		memcpy(attr_ins, attr, asize);
		attr_ins->id = id;
	}

	/*
	 * Repeat the cycle above and remove all attributes from subrecords.
	 */
	le = NULL;
	while ((le = al_enumerate(ni, le))) {
		if (!memcmp(&le->ref, &ref, sizeof(ref)))
			continue;

		mi = ni_find_mi(ni, ino_get(&le->ref));
		if (!mi)
			continue;

		attr = mi_find_attr(ni, mi, NULL, le->type, le_name(le),
				    le->name_len, &le->id);
		if (!attr)
			continue;

		/* Remove from original record. */
		mi_remove_attr(NULL, mi, attr);
	}

	run_deallocate(sbi, &ni->attr_list.run, true);
	run_close(&ni->attr_list.run);
	ni->attr_list.size = 0;
	kvfree(ni->attr_list.le);
	ni->attr_list.le = NULL;
	ni->attr_list.dirty = false;

	kfree(mrec);
	return 0;
out:
	/* Restore primary record. */
	swap(mrec, ni->mi.mrec);
	kfree(mrec);
	return 0;
}

/*
 * ni_create_attr_list - Generates an attribute list for this primary record.
 */
int ni_create_attr_list(struct ntfs_inode *ni)
{
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	int err;
	u32 lsize;
	struct ATTRIB *attr;
	struct ATTRIB *arr_move[7];
	struct ATTR_LIST_ENTRY *le, *le_b[7];
	struct MFT_REC *rec;
	bool is_mft;
	CLST rno = 0;
	struct mft_inode *mi;
	u32 free_b, nb, to_free, rs;
	u16 sz;

	ni = ni->base;
	is_mft = ni->mi.rno == MFT_REC_MFT;
	rec = ni->mi.mrec;
	rs = sbi->record_size;

	/*
	 * Compute the exact size of the attribute list.  Each attribute in the
	 * record yields one ATTR_LIST_ENTRY of le_size(name_len) bytes.  The
	 * minimum on-disk attribute is SIZEOF_RESIDENT (0x18) bytes, but an
	 * unnamed one expands to le_size(0) (0x20) here, so a record crafted
	 * with many such attributes needs more than a single record_size; the
	 * previous fixed kzalloc(record_size) could therefore be overflowed by
	 * an attacker-controlled record.
	 */
	lsize = 0;
	attr = NULL;
	while ((attr = mi_enum_attr(ni, &ni->mi, attr)))
		lsize += le_size(attr->name_len);

	if (!lsize)
		return -EINVAL;

	le = kzalloc(al_aligned(lsize), GFP_NOFS);
	if (!le)
		return -ENOMEM;

	mi_get_ref(&ni->mi, &le->ref);
	ni->attr_list.le = le;

	attr = NULL;
	nb = 0;
	free_b = 0;

	for (; (attr = mi_enum_attr(ni, &ni->mi, attr)); le = Add2Ptr(le, sz)) {
		sz = le_size(attr->name_len);
		le->type = attr->type;
		le->size = cpu_to_le16(sz);
		le->name_len = attr->name_len;
		le->name_off = offsetof(struct ATTR_LIST_ENTRY, name);
		le->vcn = 0;
		if (le != ni->attr_list.le)
			le->ref = ni->attr_list.le->ref;
		le->id = attr->id;

		if (attr->name_len)
			memcpy(le->name, attr_name(attr),
			       sizeof(short) * attr->name_len);
		else if (attr->type == ATTR_STD)
			continue;
		else if (attr->type == ATTR_LIST)
			continue;
		else if (is_mft && attr->type == ATTR_DATA)
			continue;

		if (!nb || nb < ARRAY_SIZE(arr_move)) {
			le_b[nb] = le;
			arr_move[nb++] = attr;
			free_b += le32_to_cpu(attr->size);
		}
	}

	lsize = PtrOffset(ni->attr_list.le, le);
	ni->attr_list.size = lsize;

	to_free = le32_to_cpu(rec->used) + lsize + SIZEOF_RESIDENT;
	if (to_free <= rs) {
		to_free = 0;
	} else {
		to_free -= rs;

		if (to_free > free_b) {
			err = -EINVAL;
			goto out;
		}
	}

	/* Allocate child MFT. */
	err = ntfs_look_free_mft(sbi, &rno, is_mft, ni, &mi);
	if (err)
		goto out;

	err = -EINVAL;
	/* Call mi_remove_attr() in reverse order to keep pointers 'arr_move' valid. */
	while (to_free > 0) {
		struct ATTRIB *b = arr_move[--nb];
		u32 asize = le32_to_cpu(b->size);
		u16 name_off = le16_to_cpu(b->name_off);

		attr = mi_insert_attr(ni, mi, b->type, Add2Ptr(b, name_off),
				      b->name_len, asize, name_off);
		if (!attr)
			goto out;

		mi_get_ref(mi, &le_b[nb]->ref);
		le_b[nb]->id = attr->id;

		/* Copy all except id. */
		memcpy(attr, b, asize);
		attr->id = le_b[nb]->id;

		/* Remove from primary record. */
		if (!mi_remove_attr(NULL, &ni->mi, b))
			goto out;

		if (to_free <= asize)
			break;
		to_free -= asize;
		if (!nb)
			goto out;
	}

	attr = mi_insert_attr(ni, &ni->mi, ATTR_LIST, NULL, 0,
			      lsize + SIZEOF_RESIDENT, SIZEOF_RESIDENT);
	if (!attr)
		goto out;

	attr->non_res = 0;
	attr->flags = 0;
	attr->res.data_size = cpu_to_le32(lsize);
	attr->res.data_off = SIZEOF_RESIDENT_LE;
	attr->res.flags = 0;
	attr->res.res = 0;

	memcpy(resident_data_ex(attr, lsize), ni->attr_list.le, lsize);

	ni->attr_list.dirty = false;

	mark_inode_dirty(&ni->vfs_inode);
	return 0;

out:
	kvfree(ni->attr_list.le);
	ni->attr_list.le = NULL;
	ni->attr_list.size = 0;
	return err;
}

/*
 * ni_ins_attr_ext - Add an external attribute to the ntfs_inode.
 */
static int ni_ins_attr_ext(struct ntfs_inode *ni, struct ATTR_LIST_ENTRY *le,
			   enum ATTR_TYPE type, const __le16 *name, u8 name_len,
			   u32 asize, CLST svcn, u16 name_off, bool force_ext,
			   struct ATTRIB **ins_attr, struct mft_inode **ins_mi,
			   struct ATTR_LIST_ENTRY **ins_le)
{
	struct ATTRIB *attr;
	struct mft_inode *mi;
	CLST rno;
	u64 vbo;
	struct rb_node *node;
	int err;
	bool is_mft, is_mft_data;
	struct ntfs_sb_info *sbi = ni->mi.sbi;

	ni = ni->base;
	is_mft = ni->mi.rno == MFT_REC_MFT;
	is_mft_data = is_mft && type == ATTR_DATA && !name_len;

	if (asize > sbi->max_bytes_per_attr) {
		err = -EINVAL;
		goto out;
	}

	/*
	 * Standard information and attr_list cannot be made external.
	 * The Log File cannot have any external attributes.
	 */
	if (type == ATTR_STD || type == ATTR_LIST ||
	    ni->mi.rno == MFT_REC_LOG) {
		err = -EINVAL;
		goto out;
	}

	/* Create attribute list if it is not already existed. */
	if (!ni->attr_list.size) {
		err = ni_create_attr_list(ni);
		if (err)
			goto out;
	}

	vbo = is_mft_data ? ((u64)svcn << sbi->cluster_bits) : 0;

	if (force_ext)
		goto insert_ext;

	/* Load all subrecords into memory. */
	err = ni_load_all_mi(ni);
	if (err)
		goto out;

	/* Check each of loaded subrecord. */
	for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
		mi = rb_entry(node, struct mft_inode, node);

		if (is_mft_data &&
		    (mi_enum_attr(ni, mi, NULL) ||
		     vbo <= ((u64)mi->rno << sbi->record_bits))) {
			/* We can't accept this record 'cause MFT's bootstrapping. */
			continue;
		}
		if (is_mft &&
		    mi_find_attr(ni, mi, NULL, ATTR_DATA, NULL, 0, NULL)) {
			/*
			 * This child record already has a ATTR_DATA.
			 * So it can't accept any other records.
			 */
			continue;
		}

		if ((type != ATTR_NAME || name_len) &&
		    mi_find_attr(ni, mi, NULL, type, name, name_len, NULL)) {
			/* Only indexed attributes can share same record. */
			continue;
		}

		/*
		 * Do not try to insert this attribute
		 * if there is no room in record.
		 */
		if (le32_to_cpu(mi->mrec->used) + asize > sbi->record_size)
			continue;

		/* Try to insert attribute into this subrecord. */
		attr = ni_ins_new_attr(ni, mi, le, type, name, name_len, asize,
				       name_off, svcn, ins_le);
		if (!attr)
			continue;
		if (IS_ERR(attr))
			return PTR_ERR(attr);

		if (ins_attr)
			*ins_attr = attr;
		if (ins_mi)
			*ins_mi = mi;
		return 0;
	}

insert_ext:
	/* We have to allocate a new child subrecord. */
	err = ntfs_look_free_mft(sbi, &rno, is_mft_data, ni, &mi);
	if (err)
		goto out;

	if (is_mft_data && vbo <= ((u64)rno << sbi->record_bits)) {
		err = -EINVAL;
		goto out1;
	}

	attr = ni_ins_new_attr(ni, mi, le, type, name, name_len, asize,
			       name_off, svcn, ins_le);
	if (!attr) {
		err = -EINVAL;
		goto out2;
	}

	if (IS_ERR(attr)) {
		err = PTR_ERR(attr);
		goto out2;
	}

	if (ins_attr)
		*ins_attr = attr;
	if (ins_mi)
		*ins_mi = mi;

	return 0;

out2:
	ni_remove_mi(ni, mi);

out1:
	mi_put(mi);
	ntfs_mark_rec_free(sbi, rno, is_mft);

out:
	return err;
}

/*
 * ni_insert_attr - Insert an attribute into the file.
 *
 * If the primary record has room, it will just insert the attribute.
 * If not, it may make the attribute external.
 * For $MFT::Data it may make room for the attribute by
 * making other attributes external.
 *
 * NOTE:
 * The ATTR_LIST and ATTR_STD cannot be made external.
 * This function does not fill new attribute full.
 * It only fills 'size'/'type'/'id'/'name_len' fields.
 */
static int ni_insert_attr(struct ntfs_inode *ni, enum ATTR_TYPE type,
			  const __le16 *name, u8 name_len, u32 asize,
			  u16 name_off, CLST svcn, struct ATTRIB **ins_attr,
			  struct mft_inode **ins_mi,
			  struct ATTR_LIST_ENTRY **ins_le)
{
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	int err;
	struct ATTRIB *attr, *eattr;
	struct MFT_REC *rec;
	bool is_mft;
	struct ATTR_LIST_ENTRY *le;
	u32 list_reserve, max_free, free, used, t32;
	__le16 id;
	u16 t16;

	ni = ni->base;
	is_mft = ni->mi.rno == MFT_REC_MFT;
	rec = ni->mi.mrec;

	list_reserve = SIZEOF_NONRESIDENT + 3 * (1 + 2 * sizeof(u32));
	used = le32_to_cpu(rec->used);
	free = sbi->record_size - used;

	if (is_mft && type != ATTR_LIST) {
		/* Reserve space for the ATTRIB list. */
		if (free < list_reserve)
			free = 0;
		else
			free -= list_reserve;
	}

	if (asize <= free) {
		attr = ni_ins_new_attr(ni, &ni->mi, NULL, type, name, name_len,
				       asize, name_off, svcn, ins_le);
		if (IS_ERR(attr)) {
			err = PTR_ERR(attr);
			goto out;
		}

		if (attr) {
			if (ins_attr)
				*ins_attr = attr;
			if (ins_mi)
				*ins_mi = &ni->mi;
			err = 0;
			goto out;
		}
	}

	if (!is_mft || type != ATTR_DATA || svcn) {
		/* This ATTRIB will be external. */
		err = ni_ins_attr_ext(ni, NULL, type, name, name_len, asize,
				      svcn, name_off, false, ins_attr, ins_mi,
				      ins_le);
		goto out;
	}

	/*
	 * Here we have: "is_mft && type == ATTR_DATA && !svcn"
	 *
	 * The first chunk of the $MFT::Data ATTRIB must be the base record.
	 * Evict as many other attributes as possible.
	 */
	max_free = free;

	/* Estimate the result of moving all possible attributes away. */
	attr = NULL;

	while ((attr = mi_enum_attr(ni, &ni->mi, attr))) {
		if (attr->type == ATTR_STD)
			continue;
		if (attr->type == ATTR_LIST)
			continue;
		max_free += le32_to_cpu(attr->size);
	}

	if (max_free < asize + list_reserve) {
		/* Impossible to insert this attribute into primary record. */
		err = -EINVAL;
		goto out;
	}

	/* Start real attribute moving. */
	attr = NULL;

	for (;;) {
		attr = mi_enum_attr(ni, &ni->mi, attr);
		if (!attr) {
			/* We should never be here 'cause we have already check this case. */
			err = -EINVAL;
			goto out;
		}

		/* Skip attributes that MUST be primary record. */
		if (attr->type == ATTR_STD || attr->type == ATTR_LIST)
			continue;

		le = NULL;
		if (ni->attr_list.size) {
			le = al_find_le(ni, NULL, attr);
			if (!le) {
				/* Really this is a serious bug. */
				err = -EINVAL;
				goto out;
			}
		}

		t32 = le32_to_cpu(attr->size);
		t16 = le16_to_cpu(attr->name_off);
		err = ni_ins_attr_ext(ni, le, attr->type, Add2Ptr(attr, t16),
				      attr->name_len, t32, attr_svcn(attr), t16,
				      false, &eattr, NULL, NULL);
		if (err)
			return err;

		id = eattr->id;
		memcpy(eattr, attr, t32);
		eattr->id = id;

		/* Remove from primary record. */
		mi_remove_attr(NULL, &ni->mi, attr);

		/* attr now points to next attribute. */
		if (attr->type == ATTR_END)
			goto out;
	}
	while (asize + list_reserve > sbi->record_size - le32_to_cpu(rec->used))
		;

	attr = ni_ins_new_attr(ni, &ni->mi, NULL, type, name, name_len, asize,
			       name_off, svcn, ins_le);
	if (!attr) {
		err = -EINVAL;
		goto out;
	}

	if (IS_ERR(attr)) {
		err = PTR_ERR(attr);
		goto out;
	}

	if (ins_attr)
		*ins_attr = attr;
	if (ins_mi)
		*ins_mi = &ni->mi;

out:
	return err;
}

/* ni_expand_mft_list - Split ATTR_DATA of $MFT. */
static int ni_expand_mft_list(struct ntfs_inode *ni)
{
	int err = 0;
	struct runs_tree *run = &ni->file.run;
	u32 asize, run_size, done = 0;
	struct ATTRIB *attr;
	struct rb_node *node;
	CLST mft_min, mft_new, svcn, evcn, plen;
	struct mft_inode *mi, *mi_min, *mi_new;
	struct ntfs_sb_info *sbi = ni->mi.sbi;

	ni = ni->base;
	/* Find the nearest MFT. */
	mft_min = 0;
	mft_new = 0;
	mi_min = NULL;

	for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
		mi = rb_entry(node, struct mft_inode, node);

		attr = mi_enum_attr(ni, mi, NULL);

		if (!attr) {
			mft_min = mi->rno;
			mi_min = mi;
			break;
		}
	}

	if (ntfs_look_free_mft(sbi, &mft_new, true, ni, &mi_new)) {
		mft_new = 0;
		/* Really this is not critical. */
	} else if (mft_min > mft_new) {
		mft_min = mft_new;
		mi_min = mi_new;
	} else {
		ntfs_mark_rec_free(sbi, mft_new, true);
		mft_new = 0;
		ni_remove_mi(ni, mi_new);
	}

	attr = mi_find_attr(ni, &ni->mi, NULL, ATTR_DATA, NULL, 0, NULL);
	if (!attr) {
		err = -EINVAL;
		goto out;
	}

	asize = le32_to_cpu(attr->size);

	evcn = le64_to_cpu(attr->nres.evcn);
	svcn = bytes_to_cluster(sbi, (u64)(mft_min + 1) << sbi->record_bits);
	if (evcn + 1 >= svcn) {
		err = -EINVAL;
		goto out;
	}

	/*
	 * Split primary attribute [0 evcn] in two parts [0 svcn) + [svcn evcn].
	 *
	 * Update first part of ATTR_DATA in 'primary MFT.
	 */
	err = run_pack(run, 0, svcn, Add2Ptr(attr, SIZEOF_NONRESIDENT),
		       asize - SIZEOF_NONRESIDENT, &plen);
	if (err < 0)
		goto out;

	run_size = ALIGN(err, 8);
	err = 0;

	if (plen < svcn) {
		err = -EINVAL;
		goto out;
	}

	attr->nres.evcn = cpu_to_le64(svcn - 1);
	attr->size = cpu_to_le32(run_size + SIZEOF_NONRESIDENT);
	/* 'done' - How many bytes of primary MFT becomes free. */
	done = asize - run_size - SIZEOF_NONRESIDENT;
	le32_sub_cpu(&ni->mi.mrec->used, done);

	/* Estimate packed size (run_buf=NULL). */
	err = run_pack(run, svcn, evcn + 1 - svcn, NULL, sbi->record_size,
		       &plen);
	if (err < 0)
		goto out;

	run_size = ALIGN(err, 8);
	err = 0;

	if (plen < evcn + 1 - svcn) {
		err = -EINVAL;
		goto out;
	}

	/*
	 * This function may implicitly call expand attr_list.
	 * Insert second part of ATTR_DATA in 'mi_min'.
	 */
	attr = ni_ins_new_attr(ni, mi_min, NULL, ATTR_DATA, NULL, 0,
			       SIZEOF_NONRESIDENT + run_size,
			       SIZEOF_NONRESIDENT, svcn, NULL);
	if (!attr) {
		err = -EINVAL;
		goto out;
	}

	if (IS_ERR(attr)) {
		err = PTR_ERR(attr);
		goto out;
	}

	attr->non_res = 1;
	attr->name_off = SIZEOF_NONRESIDENT_LE;
	attr->flags = 0;

	/* This function can't fail - cause already checked above. */
	run_pack(run, svcn, evcn + 1 - svcn, Add2Ptr(attr, SIZEOF_NONRESIDENT),
		 run_size, &plen);

	attr->nres.svcn = cpu_to_le64(svcn);
	attr->nres.evcn = cpu_to_le64(evcn);
	attr->nres.run_off = cpu_to_le16(SIZEOF_NONRESIDENT);

out:
	if (mft_new) {
		ntfs_mark_rec_free(sbi, mft_new, true);
		ni_remove_mi(ni, mi_new);
	}

	return !err && !done ? -EOPNOTSUPP : err;
}

/*
 * ni_expand_list - Move all possible attributes out of primary record.
 */
int ni_expand_list(struct ntfs_inode *ni)
{
	int err = 0;
	u32 asize, done = 0;
	struct ATTRIB *attr, *ins_attr = NULL;
	struct ATTR_LIST_ENTRY *le;
	bool is_mft = ni->mi.rno == MFT_REC_MFT;
	struct MFT_REF ref;

	ni = ni->base;
	mi_get_ref(&ni->mi, &ref);
	le = NULL;

	while ((le = al_enumerate(ni, le))) {
		if (le->type == ATTR_STD)
			continue;

		if (memcmp(&ref, &le->ref, sizeof(struct MFT_REF)))
			continue;

		if (is_mft && le->type == ATTR_DATA)
			continue;

		/* Find attribute in primary record. */
		attr = rec_find_attr_le(ni, &ni->mi, le);
		if (!attr) {
			err = -EINVAL;
			goto out;
		}

		asize = le32_to_cpu(attr->size);

		/* Always insert into new record to avoid collisions (deep recursive). */
		err = ni_ins_attr_ext(ni, le, attr->type, attr_name(attr),
				      attr->name_len, asize, attr_svcn(attr),
				      le16_to_cpu(attr->name_off), true,
				      &ins_attr, NULL, NULL);

		if (err || !ins_attr)
			goto out;

		memcpy(ins_attr, attr, asize);
		ins_attr->id = le->id;
		/* Remove from primary record. */
		mi_remove_attr(NULL, &ni->mi, attr);

		done += asize;
		goto out;
	}

	if (!is_mft) {
		err = -EFBIG; /* Attr list is too big(?) */
		goto out;
	}

	/* Split MFT data as much as possible. */
	err = ni_expand_mft_list(ni);

out:
	return !err && !done ? -EOPNOTSUPP : err;
}

/*
 * ni_insert_nonresident - Insert new nonresident attribute.
 */
int ni_insert_nonresident(struct ntfs_inode *ni, enum ATTR_TYPE type,
			  const __le16 *name, u8 name_len,
			  const struct runs_tree *run, CLST svcn, CLST len,
			  __le16 flags, struct ATTRIB **new_attr,
			  struct mft_inode **mi, struct ATTR_LIST_ENTRY **le)
{
	int err;
	CLST plen;
	struct ATTRIB *attr;
	bool is_ext = (flags & (ATTR_FLAG_SPARSED | ATTR_FLAG_COMPRESSED)) &&
		      !svcn;
	u32 name_size = ALIGN(name_len * sizeof(short), 8);
	u32 name_off = is_ext ? SIZEOF_NONRESIDENT_EX : SIZEOF_NONRESIDENT;
	u32 run_off = name_off + name_size;
	u32 run_size, asize;
	struct ntfs_sb_info *sbi = ni->mi.sbi;

	ni = ni->base;
	/* Estimate packed size (run_buf=NULL). */
	err = run_pack(run, svcn, len, NULL, sbi->max_bytes_per_attr - run_off,
		       &plen);
	if (err < 0)
		goto out;

	run_size = ALIGN(err, 8);

	if (plen < len) {
		err = -EINVAL;
		goto out;
	}

	asize = run_off + run_size;

	if (asize > sbi->max_bytes_per_attr) {
		err = -EINVAL;
		goto out;
	}

	err = ni_insert_attr(ni, type, name, name_len, asize, name_off, svcn,
			     &attr, mi, le);

	if (err)
		goto out;

	attr->non_res = 1;
	attr->name_off = cpu_to_le16(name_off);
	attr->flags = flags;

	/* This function can't fail - cause already checked above. */
	run_pack(run, svcn, len, Add2Ptr(attr, run_off), run_size, &plen);

	attr->nres.svcn = cpu_to_le64(svcn);
	attr->nres.evcn = cpu_to_le64((u64)svcn + len - 1);

	if (new_attr)
		*new_attr = attr;

	*(__le64 *)&attr->nres.run_off = cpu_to_le64(run_off);

	attr->nres.alloc_size =
		svcn ? 0 : cpu_to_le64((u64)len << ni->mi.sbi->cluster_bits);
	attr->nres.data_size = attr->nres.alloc_size;
	attr->nres.valid_size = attr->nres.alloc_size;

	if (is_ext) {
		if (flags & ATTR_FLAG_COMPRESSED)
			attr->nres.c_unit = NTFS_LZNT_CUNIT;
		attr->nres.total_size = attr->nres.alloc_size;
	}

out:
	return err;
}

/*
 * ni_insert_resident - Inserts new resident attribute.
 */
int ni_insert_resident(struct ntfs_inode *ni, u32 data_size,
		       enum ATTR_TYPE type, const __le16 *name, u8 name_len,
		       struct ATTRIB **new_attr, struct mft_inode **mi,
		       struct ATTR_LIST_ENTRY **le)
{
	int err;
	u32 name_size = ALIGN(name_len * sizeof(short), 8);
	u32 asize = SIZEOF_RESIDENT + name_size + ALIGN(data_size, 8);
	struct ATTRIB *attr;

	ni = ni->base;
	err = ni_insert_attr(ni, type, name, name_len, asize, SIZEOF_RESIDENT,
			     0, &attr, mi, le);
	if (err)
		return err;

	attr->non_res = 0;
	attr->flags = 0;

	attr->res.data_size = cpu_to_le32(data_size);
	attr->res.data_off = cpu_to_le16(SIZEOF_RESIDENT + name_size);
	if (type == ATTR_NAME) {
		attr->res.flags = RESIDENT_FLAG_INDEXED;

		/* is_attr_indexed(attr)) == true */
		le16_add_cpu(&ni->mi.mrec->hard_links, 1);
		ni->mi.dirty = true;
	}
	attr->res.res = 0;

	if (new_attr)
		*new_attr = attr;

	return 0;
}

/*
 * ni_remove_attr_le - Remove attribute from record.
 */
void ni_remove_attr_le(struct ntfs_inode *ni, struct ATTRIB *attr,
		       struct mft_inode *mi, struct ATTR_LIST_ENTRY *le)
{
	ni = ni->base;
	mi_remove_attr(ni, mi, attr);

	if (le)
		al_remove_le(ni, le);
}

/*
 * ni_delete_all - Remove all attributes and frees allocates space.
 *
 * ntfs_evict_inode->ntfs_clear_inode->ni_delete_all (if no links).
 */
int ni_delete_all(struct ntfs_inode *ni)
{
	int err;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct ATTRIB *attr = NULL;
	struct rb_node *node;
	u16 roff;
	u32 asize;
	CLST svcn, evcn;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	bool nt3 = is_ntfs3(sbi);
	struct MFT_REF ref;

	ni = ni->base;
	while ((attr = ni_enum_attr_ex(ni, attr, &le, NULL))) {
		if (!nt3 || attr->name_len) {
			;
		} else if (attr->type == ATTR_REPARSE) {
			mi_get_ref(&ni->mi, &ref);
			ntfs_remove_reparse(sbi, 0, &ref);
		} else if (attr->type == ATTR_ID && !attr->non_res &&
			   le32_to_cpu(attr->res.data_size) >=
				   sizeof(struct GUID)) {
			ntfs_objid_remove(sbi, resident_data(attr));
		}

		if (!attr->non_res)
			continue;

		svcn = le64_to_cpu(attr->nres.svcn);
		evcn = le64_to_cpu(attr->nres.evcn);

		if (evcn + 1 <= svcn)
			continue;

		asize = le32_to_cpu(attr->size);
		roff = le16_to_cpu(attr->nres.run_off);

		if (roff > asize) {
			/* ni_enum_attr_ex checks this case. */
			continue;
		}

		/* run==1 means unpack and deallocate. */
		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
			      Add2Ptr(attr, roff), asize - roff);
	}

	if (ni->attr_list.size) {
		run_deallocate(ni->mi.sbi, &ni->attr_list.run, true);
		al_destroy(ni);
	}

	/* Free all subrecords. */
	for (node = rb_first(&ni->mi_tree); node;) {
		struct rb_node *next = rb_next(node);
		struct mft_inode *mi = rb_entry(node, struct mft_inode, node);

		clear_rec_inuse(mi->mrec);
		mi->dirty = true;
		mi_write(mi, 0);

		ntfs_mark_rec_free(sbi, mi->rno, false);
		ni_remove_mi(ni, mi);
		mi_put(mi);
		node = next;
	}

	/* Free base record. */
	clear_rec_inuse(ni->mi.mrec);
	ni->mi.dirty = true;
	err = mi_write(&ni->mi, 0);

	ntfs_mark_rec_free(sbi, ni->mi.rno, false);

	return err;
}

/* ni_fname_name
 *
 * Return: File name attribute by its value.
 */
struct ATTR_FILE_NAME *ni_fname_name(struct ntfs_inode *ni,
				     const struct le_str *uni,
				     const struct MFT_REF *home_dir,
				     struct mft_inode **mi,
				     struct ATTR_LIST_ENTRY **le)
{
	struct ATTRIB *attr = NULL;
	struct ATTR_FILE_NAME *fname;

	ni = ni->base;
	if (le)
		*le = NULL;

	/* Enumerate all names. */
next:
	attr = ni_find_attr(ni, attr, le, ATTR_NAME, NULL, 0, NULL, mi);
	if (!attr)
		return NULL;

	fname = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
	if (!fname)
		goto next;

	if (home_dir && memcmp(home_dir, &fname->home, sizeof(*home_dir)))
		goto next;

	if (!uni)
		return fname;

	if (uni->len != fname->name_len)
		goto next;

	if (ntfs_cmp_names(uni->name, uni->len, fname->name, uni->len, NULL,
			   false))
		goto next;
	return fname;
}

/*
 * ni_fname_type
 *
 * Return: File name attribute with given type.
 */
struct ATTR_FILE_NAME *ni_fname_type(struct ntfs_inode *ni, u8 name_type,
				     struct mft_inode **mi,
				     struct ATTR_LIST_ENTRY **le)
{
	struct ATTRIB *attr = NULL;
	struct ATTR_FILE_NAME *fname;

	*le = NULL;
	ni = ni->base;

	if (name_type == FILE_NAME_POSIX)
		return NULL;

	/* Enumerate all names. */
	for (;;) {
		attr = ni_find_attr(ni, attr, le, ATTR_NAME, NULL, 0, NULL, mi);
		if (!attr)
			return NULL;

		fname = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
		if (fname && name_type == fname->type)
			return fname;
	}
}

/*
 * ni_new_attr_flags
 *
 * Process compressed/sparsed in special way.
 * NOTE: You need to set ni->std_fa = new_fa
 * after this function to keep internal structures in consistency.
 */
int ni_new_attr_flags(struct ntfs_inode *ni, enum FILE_ATTRIBUTE new_fa)
{
	struct ATTRIB *attr;
	struct mft_inode *mi;
	__le16 new_aflags;
	u32 new_asize;

	ni = ni->base;
	attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
	if (!attr)
		return -EINVAL;

	new_aflags = attr->flags;

	if (new_fa & FILE_ATTRIBUTE_SPARSE_FILE)
		new_aflags |= ATTR_FLAG_SPARSED;
	else
		new_aflags &= ~ATTR_FLAG_SPARSED;

	if (new_fa & FILE_ATTRIBUTE_COMPRESSED)
		new_aflags |= ATTR_FLAG_COMPRESSED;
	else
		new_aflags &= ~ATTR_FLAG_COMPRESSED;

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

	if ((new_aflags & (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) ==
	    (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) {
		ntfs_inode_warn(&ni->vfs_inode,
				"file can't be sparsed and compressed");
		return -EOPNOTSUPP;
	}

	if (!attr->non_res)
		goto out;

	if (attr->nres.data_size) {
		ntfs_inode_warn(
			&ni->vfs_inode,
			"one can change sparsed/compressed only for empty files");
		return -EOPNOTSUPP;
	}

	/* Resize nonresident empty attribute in-place only. */
	new_asize = (new_aflags & (ATTR_FLAG_COMPRESSED | ATTR_FLAG_SPARSED)) ?
			    (SIZEOF_NONRESIDENT_EX + 8) :
			    (SIZEOF_NONRESIDENT + 8);

	if (!mi_resize_attr(mi, attr, new_asize - le32_to_cpu(attr->size)))
		return -EOPNOTSUPP;

	if (new_aflags & ATTR_FLAG_SPARSED) {
		attr->name_off = SIZEOF_NONRESIDENT_EX_LE;
		/* Windows uses 16 clusters per frame but supports one cluster per frame too. */
		attr->nres.c_unit = 0;
		ni->vfs_inode.i_mapping->a_ops = &ntfs_aops;
	} else if (new_aflags & ATTR_FLAG_COMPRESSED) {
		attr->name_off = SIZEOF_NONRESIDENT_EX_LE;
		/* The only allowed: 16 clusters per frame. */
		attr->nres.c_unit = NTFS_LZNT_CUNIT;
		ni->vfs_inode.i_mapping->a_ops = &ntfs_aops_cmpr;
	} else {
		attr->name_off = SIZEOF_NONRESIDENT_LE;
		/* Normal files. */
		attr->nres.c_unit = 0;
		ni->vfs_inode.i_mapping->a_ops = &ntfs_aops;
	}
	attr->nres.run_off = attr->name_off;
out:
	attr->flags = new_aflags;
	mi->dirty = true;

	return 0;
}

/*
 * ni_parse_reparse
 *
 * buffer - memory for reparse buffer header
 */
enum REPARSE_SIGN ni_parse_reparse(struct ntfs_inode *ni, struct ATTRIB *attr,
				   struct REPARSE_DATA_BUFFER *buffer)
{
	const struct REPARSE_DATA_BUFFER *rp = NULL;
	u8 bits;
	u16 len;
	typeof(rp->CompressReparseBuffer) *cmpr;

	ni = ni->base;
	/* Try to estimate reparse point. */
	if (!attr->non_res) {
		rp = resident_data_ex(attr, sizeof(struct REPARSE_DATA_BUFFER));
	} else if (le64_to_cpu(attr->nres.data_size) >=
		   sizeof(struct REPARSE_DATA_BUFFER)) {
		struct runs_tree run;

		run_init(&run);

		if (!attr_load_runs_vcn(ni, ATTR_REPARSE, NULL, 0, &run, 0) &&
		    !ntfs_read_run_nb(ni->mi.sbi, &run, 0, buffer,
				      sizeof(struct REPARSE_DATA_BUFFER),
				      NULL)) {
			rp = buffer;
		}

		run_close(&run);
	}

	if (!rp)
		return REPARSE_NONE;

	len = le16_to_cpu(rp->ReparseDataLength);
	switch (rp->ReparseTag) {
	case (IO_REPARSE_TAG_MICROSOFT | IO_REPARSE_TAG_SYMBOLIC_LINK):
		break; /* Symbolic link. */
	case IO_REPARSE_TAG_MOUNT_POINT:
		break; /* Mount points and junctions. */
	case IO_REPARSE_TAG_SYMLINK:
		break;
	case IO_REPARSE_TAG_COMPRESS:
		/*
		 * WOF - Windows Overlay Filter - Used to compress files with
		 * LZX/Xpress.
		 *
		 * Unlike native NTFS file compression, the Windows
		 * Overlay Filter supports only read operations. This means
		 * that it doesn't need to sector-align each compressed chunk,
		 * so the compressed data can be packed more tightly together.
		 * If you open the file for writing, the WOF just decompresses
		 * the entire file, turning it back into a plain file.
		 *
		 * Ntfs3 driver decompresses the entire file only on write or
		 * change size requests.
		 */

		cmpr = &rp->CompressReparseBuffer;
		if (len < sizeof(*cmpr) ||
		    cmpr->WofVersion != WOF_CURRENT_VERSION ||
		    cmpr->WofProvider != WOF_PROVIDER_SYSTEM ||
		    cmpr->ProviderVer != WOF_PROVIDER_CURRENT_VERSION) {
			return REPARSE_NONE;
		}

		switch (cmpr->CompressionFormat) {
		case WOF_COMPRESSION_XPRESS4K:
			bits = 0xc; // 4k
			break;
		case WOF_COMPRESSION_XPRESS8K:
			bits = 0xd; // 8k
			break;
		case WOF_COMPRESSION_XPRESS16K:
			bits = 0xe; // 16k
			break;
		case WOF_COMPRESSION_LZX32K:
			bits = 0xf; // 32k
			break;
		default:
			bits = 0x10; // 64k
			break;
		}
		ni_set_ext_compress_bits(ni, bits);
		return REPARSE_COMPRESSED;

	case IO_REPARSE_TAG_DEDUP:
		ni->ni_flags |= NI_FLAG_DEDUPLICATED;
		return REPARSE_DEDUPLICATED;

	default:
		if (rp->ReparseTag & IO_REPARSE_TAG_NAME_SURROGATE)
			break;

		return REPARSE_NONE;
	}

	if (buffer != rp)
		memcpy(buffer, rp, sizeof(struct REPARSE_DATA_BUFFER));

	/* Looks like normal symlink. */
	return REPARSE_LINK;
}

static struct folio *ntfs_lock_new_page(struct address_space *mapping,
					pgoff_t index, gfp_t gfp)
{
	struct folio *folio = __filemap_get_folio(
		mapping, index, FGP_LOCK | FGP_ACCESSED | FGP_CREAT, gfp);

	if (IS_ERR(folio))
		return folio;

	if (!folio_test_uptodate(folio)) {
		struct page *page = folio_file_page(folio, index);

		if (IS_ERR(page))
			return ERR_CAST(page);
		return page_folio(page);
	}

	/* Use a temporary page to avoid data corruption */
	folio_unlock(folio);
	folio_put(folio);
	folio = folio_alloc(gfp, 0);
	if (!folio)
		return ERR_PTR(-ENOMEM);
	__folio_set_locked(folio);
	return folio;
}

/*
 * ni_read_folio_cmpr
 *
 * When decompressing, we typically obtain more than one page per reference.
 * We inject the additional pages into the page cache.
 */
int ni_read_folio_cmpr(struct ntfs_inode *ni, struct folio *folio)
{
	int err;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct address_space *mapping = folio->mapping;
	pgoff_t index;
	u64 frame_vbo, vbo = folio_pos(folio);
	struct page **pages = NULL; /* Array of at most 16 pages. stack? */
	u8 frame_bits;
	CLST frame;
	u32 i, idx, frame_size, pages_per_frame;
	gfp_t gfp_mask;
	struct page *pg;
	struct folio *f;

	if (vbo >= i_size_read(&ni->vfs_inode)) {
		folio_zero_range(folio, 0, folio_size(folio));
		folio_mark_uptodate(folio);
		err = 0;
		goto out;
	}

	if (ni->ni_flags & NI_FLAG_COMPRESSED_MASK) {
		/* Xpress or LZX. */
		frame_bits = ni_ext_compress_bits(ni);
	} else {
		/* LZNT compression. */
		frame_bits = NTFS_LZNT_CUNIT + sbi->cluster_bits;
	}
	frame_size = 1u << frame_bits;
	frame = vbo >> frame_bits;
	frame_vbo = (u64)frame << frame_bits;
	idx = (vbo - frame_vbo) >> PAGE_SHIFT;

	pages_per_frame = frame_size >> PAGE_SHIFT;
	pages = kzalloc_objs(struct page *, pages_per_frame, GFP_NOFS);
	if (!pages) {
		err = -ENOMEM;
		goto out;
	}

	pages[idx] = &folio->page;
	index = frame_vbo >> PAGE_SHIFT;
	gfp_mask = mapping_gfp_mask(mapping);

	for (i = 0; i < pages_per_frame; i++, index++) {
		if (i == idx)
			continue;

		f = ntfs_lock_new_page(mapping, index, gfp_mask);
		if (IS_ERR(f)) {
			err = PTR_ERR(f);
			goto out1;
		}
		pages[i] = &f->page;
	}

	ni_lock(ni);
	err = ni_read_frame(ni, frame_vbo, pages, pages_per_frame, 0);
	ni_unlock(ni);

out1:
	for (i = 0; i < pages_per_frame; i++) {
		pg = pages[i];
		if (i == idx || !pg)
			continue;
		unlock_page(pg);
		put_page(pg);
	}

out:
	/* At this point, err contains 0 or -EIO depending on the "critical" page. */
	kfree(pages);
	folio_unlock(folio);

	return err;
}

#ifdef CONFIG_NTFS3_LZX_XPRESS
/*
 * ni_decompress_file - Decompress LZX/Xpress compressed file.
 *
 * Remove ATTR_DATA::WofCompressedData.
 * Remove ATTR_REPARSE.
 */
int ni_decompress_file(struct ntfs_inode *ni)
{
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct inode *inode = &ni->vfs_inode;
	loff_t i_size = i_size_read(inode);
	struct address_space *mapping = inode->i_mapping;
	gfp_t gfp_mask = mapping_gfp_mask(mapping);
	struct page **pages = NULL;
	struct ATTR_LIST_ENTRY *le;
	struct ATTRIB *attr;
	CLST vcn, cend, lcn, clen, end;
	pgoff_t index;
	u64 vbo;
	u8 frame_bits;
	u32 i, frame_size, pages_per_frame, bytes;
	struct mft_inode *mi;
	int err;

	ni = ni->base;
	/* Clusters for decompressed data. */
	cend = bytes_to_cluster(sbi, i_size);

	if (!i_size)
		goto remove_wof;

	/* Check in advance. */
	if (cend > wnd_zeroes(&sbi->used.bitmap)) {
		err = -ENOSPC;
		goto out;
	}

	frame_bits = ni_ext_compress_bits(ni);
	frame_size = 1u << frame_bits;
	pages_per_frame = frame_size >> PAGE_SHIFT;
	pages = kzalloc_objs(struct page *, pages_per_frame, GFP_NOFS);
	if (!pages) {
		err = -ENOMEM;
		goto out;
	}

	/*
	 * Step 1: Decompress data and copy to new allocated clusters.
	 */
	index = 0;
	for (vbo = 0; vbo < i_size; vbo += bytes) {
		bool new;

		bytes = vbo + frame_size > i_size ? (i_size - vbo) : frame_size;
		end = bytes_to_cluster(sbi, vbo + bytes);

		for (vcn = vbo >> sbi->cluster_bits; vcn < end; vcn += clen) {
			err = attr_data_get_block(ni, vcn, cend - vcn, &lcn,
						  &clen, &new, false, NULL,
						  false);
			if (err)
				goto out;
		}

		for (i = 0; i < pages_per_frame; i++, index++) {
			struct folio *f;

			f = ntfs_lock_new_page(mapping, index, gfp_mask);
			if (IS_ERR(f)) {
				while (i--) {
					unlock_page(pages[i]);
					put_page(pages[i]);
				}
				err = PTR_ERR(f);
				goto out;
			}
			pages[i] = &f->page;
		}

		err = ni_read_frame(ni, vbo, pages, pages_per_frame, 1);

		for (i = 0; i < pages_per_frame; i++) {
			unlock_page(pages[i]);
			put_page(pages[i]);
		}

		if (err)
			goto out;

		cond_resched();
	}

remove_wof:
	/*
	 * Step 2: Deallocate attributes ATTR_DATA::WofCompressedData
	 * and ATTR_REPARSE.
	 */
	attr = NULL;
	le = NULL;
	while ((attr = ni_enum_attr_ex(ni, attr, &le, NULL))) {
		CLST svcn, evcn;
		u32 asize, roff;

		if (attr->type == ATTR_REPARSE) {
			struct MFT_REF ref;

			mi_get_ref(&ni->mi, &ref);
			ntfs_remove_reparse(sbi, 0, &ref);
		}

		if (!attr->non_res)
			continue;

		if (attr->type != ATTR_REPARSE &&
		    (attr->type != ATTR_DATA ||
		     attr->name_len != ARRAY_SIZE(WOF_NAME) ||
		     memcmp(attr_name(attr), WOF_NAME, sizeof(WOF_NAME))))
			continue;

		svcn = le64_to_cpu(attr->nres.svcn);
		evcn = le64_to_cpu(attr->nres.evcn);

		if (evcn + 1 <= svcn)
			continue;

		asize = le32_to_cpu(attr->size);
		roff = le16_to_cpu(attr->nres.run_off);

		if (roff > asize) {
			err = -EINVAL;
			goto out;
		}

		/*run==1  Means unpack and deallocate. */
		run_unpack_ex(RUN_DEALLOCATE, sbi, ni->mi.rno, svcn, evcn, svcn,
			      Add2Ptr(attr, roff), asize - roff);
	}

	/*
	 * Step 3: Remove attribute ATTR_DATA::WofCompressedData.
	 */
	err = ni_remove_attr(ni, ATTR_DATA, WOF_NAME, ARRAY_SIZE(WOF_NAME),
			     false, NULL);
	if (err)
		goto out;

	/*
	 * Step 4: Remove ATTR_REPARSE.
	 */
	err = ni_remove_attr(ni, ATTR_REPARSE, NULL, 0, false, NULL);
	if (err)
		goto out;

	/*
	 * Step 5: Remove sparse flag from data attribute.
	 */
	attr = ni_find_attr(ni, NULL, NULL, ATTR_DATA, NULL, 0, NULL, &mi);
	if (!attr) {
		err = -EINVAL;
		goto out;
	}

	if (attr->non_res && is_attr_sparsed(attr)) {
		/* Sparsed attribute header is 8 bytes bigger than normal. */
		struct MFT_REC *rec = mi->mrec;
		u32 used = le32_to_cpu(rec->used);
		u32 asize = le32_to_cpu(attr->size);
		u16 roff = le16_to_cpu(attr->nres.run_off);
		char *rbuf = Add2Ptr(attr, roff);

		memmove(rbuf - 8, rbuf, used - PtrOffset(rec, rbuf));
		attr->size = cpu_to_le32(asize - 8);
		attr->flags &= ~ATTR_FLAG_SPARSED;
		attr->nres.run_off = cpu_to_le16(roff - 8);
		attr->nres.c_unit = 0;
		rec->used = cpu_to_le32(used - 8);
		mi->dirty = true;
		ni->std_fa &= ~(FILE_ATTRIBUTE_SPARSE_FILE |
				FILE_ATTRIBUTE_REPARSE_POINT);

		mark_inode_dirty(inode);
	}

	/* Clear cached flag. */
	ni->ni_flags &= ~NI_FLAG_COMPRESSED_MASK;
	if (ni->file.offs_folio) {
		folio_put(ni->file.offs_folio);
		ni->file.offs_folio = NULL;
	}
	mapping->a_ops = &ntfs_aops;

out:
	kfree(pages);
	if (err)
		_ntfs_bad_inode(inode);

	return err;
}

/*
 * decompress_lzx_xpress - External compression LZX/Xpress.
 */
static int decompress_lzx_xpress(struct ntfs_sb_info *sbi, const char *cmpr,
				 size_t cmpr_size, void *unc, size_t unc_size,
				 u32 frame_size)
{
	int err;
	void *ctx;

	if (cmpr_size == unc_size) {
		/* Frame not compressed. */
		memcpy(unc, cmpr, unc_size);
		return 0;
	}

	err = 0;
	if (frame_size == 0x8000) {
		mutex_lock(&sbi->compress.mtx_lzx);
		/* LZX: Frame compressed. */
		ctx = sbi->compress.lzx;
		if (!ctx) {
			/* Lazy initialize LZX decompress context. */
			ctx = lzx_allocate_decompressor();
			if (!ctx) {
				err = -ENOMEM;
				goto out1;
			}

			sbi->compress.lzx = ctx;
		}

		if (lzx_decompress(ctx, cmpr, cmpr_size, unc, unc_size)) {
			/* Treat all errors as "invalid argument". */
			err = -EINVAL;
		}
out1:
		mutex_unlock(&sbi->compress.mtx_lzx);
	} else {
		/* XPRESS: Frame compressed. */
		mutex_lock(&sbi->compress.mtx_xpress);
		ctx = sbi->compress.xpress;
		if (!ctx) {
			/* Lazy initialize Xpress decompress context. */
			ctx = xpress_allocate_decompressor();
			if (!ctx) {
				err = -ENOMEM;
				goto out2;
			}

			sbi->compress.xpress = ctx;
		}

		if (xpress_decompress(ctx, cmpr, cmpr_size, unc, unc_size)) {
			/* Treat all errors as "invalid argument". */
			err = -EINVAL;
		}
out2:
		mutex_unlock(&sbi->compress.mtx_xpress);
	}
	return err;
}
#endif

/*
 * ni_read_frame
 *
 * Pages - Array of locked pages.
 */
int ni_read_frame(struct ntfs_inode *ni, u64 frame_vbo, struct page **pages,
		  u32 pages_per_frame, int copy)
{
	int err;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	u8 cluster_bits = sbi->cluster_bits;
	char *frame_ondisk = NULL;
	char *frame_mem = NULL;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct runs_tree *run = &ni->file.run;
	u64 valid_size = ni->i_valid;
	u64 vbo_disk;
	size_t unc_size = 0;
	u32 frame_size, i, ondisk_size;
	struct page *pg;
	struct ATTRIB *attr;
	CLST frame, clst_data;

	ni = ni->base;
	/*
	 * To simplify decompress algorithm do vmap for source
	 * and target pages.
	 */
	frame_size = pages_per_frame << PAGE_SHIFT;
	frame_mem = vmap(pages, pages_per_frame, VM_MAP, PAGE_KERNEL);
	if (!frame_mem) {
		err = -ENOMEM;
		goto out;
	}

	attr = ni_find_attr(ni, NULL, &le, ATTR_DATA, NULL, 0, NULL, NULL);
	if (!attr) {
		err = -ENOENT;
		goto out1;
	}

	if (!attr->non_res) {
		u32 data_size = le32_to_cpu(attr->res.data_size);

		memset(frame_mem, 0, frame_size);
		if (frame_vbo < data_size) {
			ondisk_size = data_size - frame_vbo;
			memcpy(frame_mem, resident_data(attr) + frame_vbo,
			       min(ondisk_size, frame_size));
		}
		err = 0;
		goto out1;
	}

	if (frame_vbo >= valid_size) {
		memset(frame_mem, 0, frame_size);
		err = 0;
		goto out1;
	}

	if (ni->ni_flags & NI_FLAG_COMPRESSED_MASK) {
#ifndef CONFIG_NTFS3_LZX_XPRESS
		err = -EOPNOTSUPP;
		goto out1;
#else
		loff_t i_size = i_size_read(&ni->vfs_inode);
		u32 frame_bits = ni_ext_compress_bits(ni);
		u64 frame64 = frame_vbo >> frame_bits;
		u64 frames, vbo_data;

		if (frame_size != (1u << frame_bits)) {
			err = -EINVAL;
			goto out1;
		}
		switch (frame_size) {
		case 0x1000:
		case 0x2000:
		case 0x4000:
		case 0x8000:
			break;
		default:
			/* Unknown compression. */
			err = -EOPNOTSUPP;
			goto out1;
		}

		attr = ni_find_attr(ni, attr, &le, ATTR_DATA, WOF_NAME,
				    ARRAY_SIZE(WOF_NAME), NULL, NULL);
		if (!attr) {
			ntfs_inode_err(
				&ni->vfs_inode,
				"external compressed file should contains data attribute \"WofCompressedData\"");
			err = -EINVAL;
			goto out1;
		}

		if (!attr->non_res) {
			run = NULL;
		} else {
			run = run_alloc();
			if (!run) {
				err = -ENOMEM;
				goto out1;
			}
		}

		frames = (i_size - 1) >> frame_bits;

		err = attr_wof_frame_info(ni, attr, run, frame64, frames,
					  frame_bits, &ondisk_size, &vbo_data);
		if (err)
			goto out1;

		if (frame64 == frames) {
			unc_size = 1 + ((i_size - 1) & (frame_size - 1));
			ondisk_size = attr_size(attr) - vbo_data;
		} else {
			unc_size = frame_size;
		}

		if (ondisk_size > frame_size) {
			err = -EINVAL;
			goto out1;
		}

		if (!attr->non_res) {
			if (vbo_data + ondisk_size >
			    le32_to_cpu(attr->res.data_size)) {
				err = -EINVAL;
				goto out1;
			}

			err = decompress_lzx_xpress(
				sbi, Add2Ptr(resident_data(attr), vbo_data),
				ondisk_size, frame_mem, unc_size, frame_size);
			goto out1;
		}
		vbo_disk = vbo_data;
		/* Load all runs to read [vbo_disk-vbo_to). */
		err = attr_load_runs_range(ni, ATTR_DATA, WOF_NAME,
					   ARRAY_SIZE(WOF_NAME), run, vbo_disk,
					   vbo_data + ondisk_size);
		if (err)
			goto out1;
#endif
	} else if (is_attr_compressed(attr)) {
		/* LZNT compression. */
		if (sbi->cluster_size > NTFS_LZNT_MAX_CLUSTER) {
			err = -EOPNOTSUPP;
			goto out1;
		}

		if (attr->nres.c_unit != NTFS_LZNT_CUNIT) {
			err = -EOPNOTSUPP;
			goto out1;
		}

		down_write(&ni->file.run_lock);
		run_truncate_around(run, le64_to_cpu(attr->nres.svcn));
		frame = frame_vbo >> (cluster_bits + NTFS_LZNT_CUNIT);
		err = attr_is_frame_compressed(ni, attr, frame, &clst_data,
					       run);
		up_write(&ni->file.run_lock);
		if (err)
			goto out1;

		if (!clst_data) {
			memset(frame_mem, 0, frame_size);
			goto out1;
		}

		frame_size = sbi->cluster_size << NTFS_LZNT_CUNIT;
		ondisk_size = clst_data << cluster_bits;

		if (clst_data >= NTFS_LZNT_CLUSTERS) {
			/* Frame is not compressed. */
			down_read(&ni->file.run_lock);
			err = ntfs_read_run(sbi, run, frame_mem, frame_vbo,
					    ondisk_size);
			up_read(&ni->file.run_lock);
			goto out1;
		}
		vbo_disk = frame_vbo;
	} else {
		__builtin_unreachable();
		err = -EINVAL;
		goto out1;
	}

	/* Allocate memory to read compressed data to. */
	frame_ondisk = kvmalloc(ondisk_size, GFP_KERNEL);
	if (!frame_ondisk) {
		err = -ENOMEM;
		goto out1;
	}

	/* Read 'ondisk_size' bytes from disk. */
	down_read(&ni->file.run_lock);
	err = ntfs_read_run(sbi, run, frame_ondisk, vbo_disk, ondisk_size);
	up_read(&ni->file.run_lock);
	if (err)
		goto out2;

#ifdef CONFIG_NTFS3_LZX_XPRESS
	if (run != &ni->file.run) {
		/* LZX or XPRESS */
		err = decompress_lzx_xpress(sbi, frame_ondisk, ondisk_size,
					    frame_mem, unc_size, frame_size);
	} else
#endif
	{
		/* LZNT - Native NTFS compression. */
		unc_size = decompress_lznt(frame_ondisk, ondisk_size, frame_mem,
					   frame_size);
		if ((ssize_t)unc_size < 0)
			err = unc_size;
		else if (!unc_size || unc_size > frame_size)
			err = -EINVAL;
		else if (unc_size < frame_size) {
			/*
			 * Partial decompress: zero the [unc_size, frame_size)
			 * tail.  decompress_lznt() leaves it untouched, so
			 * without this the freshly vmapped pages would expose
			 * uninitialized kernel memory to userspace.
			 */
			memset(frame_mem + unc_size, 0, frame_size - unc_size);
		}
	}
	if (!err && valid_size < frame_vbo + frame_size) {
		size_t ok = valid_size - frame_vbo;

		memset(frame_mem + ok, 0, frame_size - ok);
	}

out2:
	kvfree(frame_ondisk);
out1:
#ifdef CONFIG_NTFS3_LZX_XPRESS
	if (run != &ni->file.run)
		run_free(run);
	if (!err && copy) {
		/* We are called from 'ni_decompress_file' */
		/* Copy decompressed LZX or XPRESS data into new place. */
		down_read(&ni->file.run_lock);
		err = ntfs_write_run(sbi, &ni->file.run, frame_mem, frame_vbo,
				     frame_size);
		up_read(&ni->file.run_lock);
	}
#endif
	vunmap(frame_mem);
out:
	for (i = 0; i < pages_per_frame; i++) {
		pg = pages[i];
		SetPageUptodate(pg);
	}

	return err;
}

/*
 * ni_write_frame
 *
 * Pages - Array of locked pages.
 */
int ni_write_frame(struct ntfs_inode *ni, struct page **pages,
		   u32 pages_per_frame)
{
	int err;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct folio *folio = page_folio(pages[0]);
	u8 frame_bits = NTFS_LZNT_CUNIT + sbi->cluster_bits;
	u32 frame_size = sbi->cluster_size << NTFS_LZNT_CUNIT;
	u64 frame_vbo = folio_pos(folio);
	CLST frame = frame_vbo >> frame_bits;
	char *frame_ondisk = NULL;
	struct ATTR_LIST_ENTRY *le = NULL;
	char *frame_mem;
	struct ATTRIB *attr;
	struct mft_inode *mi;
	size_t compr_size, ondisk_size;
	struct lznt *lznt;

	ni = ni->base;
	attr = ni_find_attr(ni, NULL, &le, ATTR_DATA, NULL, 0, NULL, &mi);
	if (!attr) {
		err = -ENOENT;
		goto out;
	}

	if (WARN_ON(!is_attr_compressed(attr))) {
		err = -EINVAL;
		goto out;
	}

	if (sbi->cluster_size > NTFS_LZNT_MAX_CLUSTER) {
		err = -EOPNOTSUPP;
		goto out;
	}

	if (!attr->non_res) {
		down_write(&ni->file.run_lock);
		err = attr_make_nonresident(ni, attr, le, mi,
					    le32_to_cpu(attr->res.data_size),
					    &ni->file.run, &attr, pages[0]);
		up_write(&ni->file.run_lock);
		if (err)
			goto out;
	}

	if (attr->nres.c_unit != NTFS_LZNT_CUNIT) {
		err = -EOPNOTSUPP;
		goto out;
	}

	/* Allocate memory to write compressed data to. */
	frame_ondisk = kvmalloc(frame_size, GFP_KERNEL);
	if (!frame_ondisk) {
		err = -ENOMEM;
		goto out;
	}

	/* Map in-memory frame for read-only. */
	frame_mem = vmap(pages, pages_per_frame, VM_MAP, PAGE_KERNEL_RO);
	if (!frame_mem) {
		err = -ENOMEM;
		goto out1;
	}

	mutex_lock(&sbi->compress.mtx_lznt);
	lznt = NULL;
	if (!sbi->compress.lznt) {
		/*
		 * LZNT implements two levels of compression:
		 * 0 - Standard compression
		 * 1 - Best compression, requires a lot of cpu
		 * use mount option?
		 */
		lznt = get_lznt_ctx(0);
		if (!lznt) {
			mutex_unlock(&sbi->compress.mtx_lznt);
			err = -ENOMEM;
			goto out2;
		}

		sbi->compress.lznt = lznt;
		lznt = NULL;
	}

	/* Compress: frame_mem -> frame_ondisk */
	compr_size = compress_lznt(frame_mem, frame_size, frame_ondisk,
				   frame_size, sbi->compress.lznt);
	mutex_unlock(&sbi->compress.mtx_lznt);
	kfree(lznt);

	if (compr_size + sbi->cluster_size > frame_size) {
		/* Frame is not compressed. */
		compr_size = frame_size;
		ondisk_size = frame_size;
	} else if (compr_size) {
		/* Frame is compressed. */
		ondisk_size = ntfs_up_cluster(sbi, compr_size);
		memset(frame_ondisk + compr_size, 0, ondisk_size - compr_size);
	} else {
		/* Frame is sparsed. */
		ondisk_size = 0;
	}

	down_write(&ni->file.run_lock);
	run_truncate_around(&ni->file.run, le64_to_cpu(attr->nres.svcn));
	err = attr_allocate_frame(ni, frame, compr_size, ni->i_valid);
	up_write(&ni->file.run_lock);
	if (err)
		goto out2;

	if (!ondisk_size)
		goto out2;

	down_read(&ni->file.run_lock);
	err = ntfs_write_run(sbi, &ni->file.run,
			     ondisk_size < frame_size ? frame_ondisk :
							frame_mem,
			     frame_vbo, ondisk_size);
	up_read(&ni->file.run_lock);

out2:
	vunmap(frame_mem);
out1:
	kvfree(frame_ondisk);
out:
	return err;
}

/*
 * ni_remove_name - Removes name 'de' from MFT and from directory.
 * 'de2' and 'undo_step' are used to restore MFT/dir, if error occurs.
 */
int ni_remove_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
		   struct NTFS_DE *de, struct NTFS_DE **de2, int *undo_step)
{
	int err;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct ATTR_FILE_NAME *de_name = (struct ATTR_FILE_NAME *)(de + 1);
	struct ATTR_FILE_NAME *fname;
	struct ATTR_LIST_ENTRY *le;
	struct mft_inode *mi;
	u16 de_key_size = le16_to_cpu(de->key_size);
	u8 name_type;

	ni = ni->base;
	*undo_step = 0;

	/* Find name in record. */
	mi_get_ref(&dir_ni->mi, &de_name->home);

	fname = ni_fname_name(ni, (struct le_str *)&de_name->name_len,
			      &de_name->home, &mi, &le);
	if (!fname)
		return -ENOENT;

	memcpy(&de_name->dup, &fname->dup, sizeof(struct NTFS_DUP_INFO));
	name_type = paired_name(fname->type);

	/* Mark ntfs as dirty. It will be cleared at umount. */
	ntfs_set_state(sbi, NTFS_DIRTY_DIRTY);

	/* Step 1: Remove name from directory. */
	err = indx_delete_entry(&dir_ni->dir, dir_ni, fname, de_key_size, sbi);
	if (err)
		return err;

	/* Step 2: Remove name from MFT. */
	ni_remove_attr_le(ni, attr_from_name(fname), mi, le);

	*undo_step = 2;

	/* Get paired name. */
	fname = ni_fname_type(ni, name_type, &mi, &le);
	if (fname) {
		u16 de2_key_size = fname_full_size(fname);

		*de2 = Add2Ptr(de, 1024);
		(*de2)->key_size = cpu_to_le16(de2_key_size);

		memcpy(*de2 + 1, fname, de2_key_size);

		/* Step 3: Remove paired name from directory. */
		err = indx_delete_entry(&dir_ni->dir, dir_ni, fname,
					de2_key_size, sbi);
		if (err)
			return err;

		/* Step 4: Remove paired name from MFT. */
		ni_remove_attr_le(ni, attr_from_name(fname), mi, le);

		*undo_step = 4;
	}
	return 0;
}

/*
 * ni_remove_name_undo - Paired function for ni_remove_name.
 *
 * Return: True if ok
 */
bool ni_remove_name_undo(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
			 struct NTFS_DE *de, struct NTFS_DE *de2, int undo_step)
{
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct ATTRIB *attr;
	u16 de_key_size;

	ni = ni->base;
	switch (undo_step) {
	case 4:
		de_key_size = le16_to_cpu(de2->key_size);
		if (ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0,
				       &attr, NULL, NULL))
			return false;
		memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de2 + 1, de_key_size);

		mi_get_ref(&ni->mi, &de2->ref);
		de2->size = cpu_to_le16(ALIGN(de_key_size, 8) +
					sizeof(struct NTFS_DE));
		de2->flags = 0;
		de2->res = 0;

		if (indx_insert_entry(&dir_ni->dir, dir_ni, de2, sbi, NULL, 1))
			return false;
		fallthrough;

	case 2:
		de_key_size = le16_to_cpu(de->key_size);

		if (ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0,
				       &attr, NULL, NULL))
			return false;

		memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de + 1, de_key_size);
		mi_get_ref(&ni->mi, &de->ref);

		if (indx_insert_entry(&dir_ni->dir, dir_ni, de, sbi, NULL, 1))
			return false;
	}

	return true;
}

/*
 * ni_add_name - Add new name into MFT and into directory.
 */
int ni_add_name(struct ntfs_inode *dir_ni, struct ntfs_inode *ni,
		struct NTFS_DE *de)
{
	int err;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct ATTRIB *attr;
	struct ATTR_LIST_ENTRY *le;
	struct mft_inode *mi;
	struct ATTR_FILE_NAME *fname;
	struct ATTR_FILE_NAME *de_name = (struct ATTR_FILE_NAME *)(de + 1);
	u16 de_key_size = le16_to_cpu(de->key_size);

	ni = ni->base;
	if (sbi->options->windows_names &&
	    !valid_windows_name(sbi, (struct le_str *)&de_name->name_len))
		return -EINVAL;

	/* If option "hide_dot_files" then set hidden attribute for dot files. */
	if (ni->mi.sbi->options->hide_dot_files) {
		if (de_name->name_len > 0 &&
		    le16_to_cpu(de_name->name[0]) == '.')
			ni->std_fa |= FILE_ATTRIBUTE_HIDDEN;
		else
			ni->std_fa &= ~FILE_ATTRIBUTE_HIDDEN;
	}

	mi_get_ref(&ni->mi, &de->ref);
	mi_get_ref(&dir_ni->mi, &de_name->home);

	/* Fill duplicate from any ATTR_NAME. */
	fname = ni_fname_name(ni, NULL, NULL, NULL, NULL);
	if (fname)
		memcpy(&de_name->dup, &fname->dup, sizeof(fname->dup));
	de_name->dup.fa = ni->std_fa;

	/* Insert new name into MFT. */
	err = ni_insert_resident(ni, de_key_size, ATTR_NAME, NULL, 0, &attr,
				 &mi, &le);
	if (err)
		return err;

	memcpy(Add2Ptr(attr, SIZEOF_RESIDENT), de_name, de_key_size);

	/* Insert new name into directory. */
	err = indx_insert_entry(&dir_ni->dir, dir_ni, de, sbi, NULL, 0);
	if (err)
		ni_remove_attr_le(ni, attr, mi, le);

	return err;
}

/*
 * ni_rename - Remove one name and insert new name.
 */
int ni_rename(struct ntfs_inode *dir_ni, struct ntfs_inode *new_dir_ni,
	      struct ntfs_inode *ni, struct NTFS_DE *de, struct NTFS_DE *new_de)
{
	int err;
	struct NTFS_DE *de2 = NULL;
	int undo = 0;
	const int way = 1; /* Hope compiler removes below 'else'. */

	/*
	 * There are two possible ways to rename:
	 * 1) Add new name and remove old name.
	 * 2) Remove old name and add new name.
	 *
	 * In most cases (not all!) adding new name into MFT and into directory can
	 * allocate additional cluster(s).
	 * Second way may result to bad inode if we can't add new name
	 * and then can't restore (add) old name.
	 */
	if (way == 1) {
		/*
		 * Way 1 - Add new + remove old.
		 */
		err = ni_add_name(new_dir_ni, ni, new_de);
		if (!err) {
			err = ni_remove_name(dir_ni, ni, de, &de2, &undo);
			if (err &&
			    ni_remove_name(new_dir_ni, ni, new_de, &de2, &undo))
				_ntfs_bad_inode(&ni->vfs_inode);
		}
	} else {
		/*
		 * Way 2 - Remove old + add new.
		 */
		err = ni_remove_name(dir_ni, ni, de, &de2, &undo);
		if (!err) {
			err = ni_add_name(new_dir_ni, ni, new_de);
			if (err &&
			    !ni_remove_name_undo(dir_ni, ni, de, de2, undo))
				_ntfs_bad_inode(&ni->vfs_inode);
		}
	}

	return err;
}

/*
 * ni_is_dirty - Return: True if 'ni' requires ni_write_inode.
 */
bool ni_is_dirty(struct inode *inode)
{
	struct ntfs_inode *ni = ntfs_i(inode);
	struct rb_node *node;

	if (ni->mi.dirty || ni->attr_list.dirty ||
	    (ni->ni_flags & NI_FLAG_UPDATE_PARENT))
		return true;

	for (node = rb_first(&ni->mi_tree); node; node = rb_next(node)) {
		if (rb_entry(node, struct mft_inode, node)->dirty)
			return true;
	}

	return false;
}

/*
 * ni_seek_data_or_hole
 *
 * Helper function for ntfs_llseek( SEEK_DATA/SEEK_HOLE )
 */
loff_t ni_seek_data_or_hole(struct ntfs_inode *ni, loff_t offset, bool data)
{
	int err;
	u8 cluster_bits = ni->mi.sbi->cluster_bits;
	CLST vcn, lcn, clen;
	loff_t vbo;

	/* Enumerate all fragments. */
	for (vcn = offset >> cluster_bits;; vcn += clen) {
		err = attr_data_get_block(ni, vcn, 1, &lcn, &clen, NULL, false,
					  NULL, false);
		if (err) {
			return err;
		}

		if (!clen) {
			/* Corrupted file. */
			return -EINVAL;
		}

		if (lcn == RESIDENT_LCN) {
			/* clen - resident size in bytes. clen == ni->vfs_inode.i_size */
			if (offset >= clen) {
				/* check eof. */
				return -ENXIO;
			}

			if (data) {
				return offset;
			}

			return clen;
		}

		if (lcn == EOF_LCN) {
			if (data) {
				return -ENXIO;
			}

			/* implicit hole at the end of file. */
			return ni->vfs_inode.i_size;
		}

		if (data) {
			/*
			 * Adjust the file offset to the next location in the file greater than
			 * or equal to offset containing data. If offset points to data, then
			 * the file offset is set to offset.
			 */
			if (lcn != SPARSE_LCN) {
				/* Normal cluster. */
				break;
			}

			if ((ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) &&
			    (vcn & (NTFS_LZNT_CLUSTERS - 1))) {
				/* Compressed cluster in compressed frame. */
				break;
			}
		} else {
			/*
			 * Adjust the file offset to the next hole in the file greater than or
			 * equal to offset. If offset points into the middle of a hole, then the
			 * file offset is set to offset. If there is no hole past offset, then the
			 * file offset is adjusted to the end of the file
			 * (i.e., there is an implicit hole at the end of any file).
			 */
			if (lcn == SPARSE_LCN &&
			    /* native compression hole begins at aligned vcn. */
			    (!(ni->std_fa & FILE_ATTRIBUTE_COMPRESSED) ||
			     !(vcn & (NTFS_LZNT_CLUSTERS - 1)))) {
				/* Hole in sparsed or compressed file frame. */
				break;
			}
		}
	}

	vbo = (u64)vcn << cluster_bits;
	return max(vbo, offset);
}

/*
 * ni_write_parents
 *
 * Helper function for ntfs_file_fsync.
 */
int ni_write_parents(struct ntfs_inode *ni, int sync)
{
	int err = 0;
	struct ATTRIB *attr = NULL;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct super_block *sb = sbi->sb;

	if (!is_ni_base(ni))
		return 0;

	while ((attr = ni_find_attr(ni, attr, &le, ATTR_NAME, NULL, 0, NULL,
				    NULL))) {
		struct inode *dir;
		struct ATTR_FILE_NAME *fname;

		fname = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
		if (!fname)
			continue;

		/* Check simple case when parent inode equals current inode. */
		if (ino_get(&fname->home) == ni->vfs_inode.i_ino) {
			if (MFT_REC_ROOT != ni->vfs_inode.i_ino) {
				ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
				err = -EINVAL;
			}
			continue;
		}

		dir = ntfs_iget5(sb, &fname->home, NULL);
		if (IS_ERR(dir)) {
			ntfs_inode_warn(
				&ni->vfs_inode,
				"failed to open parent directory r=%llx to write",
				(u64)ino_get(&fname->home));
			continue;
		}

		if (!is_bad_inode(dir)) {
			int err2 = write_inode_now(dir, sync);
			if (!err)
				err = err2;
		}
		iput(dir);
	}

	return err;
}

/*
 * ni_update_parent
 *
 * Update duplicate info of ATTR_FILE_NAME in MFT and in parent directories.
 */
static bool ni_update_parent(struct ntfs_inode *ni, struct NTFS_DUP_INFO *dup,
			     int sync)
{
	struct ATTRIB *attr;
	struct mft_inode *mi;
	struct ATTR_LIST_ENTRY *le = NULL;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	struct super_block *sb = sbi->sb;
	bool re_dirty = false;

	if (ni->mi.mrec->flags & RECORD_FLAG_DIR) {
		dup->fa |= FILE_ATTRIBUTE_DIRECTORY;
		attr = NULL;
		dup->alloc_size = 0;
		dup->data_size = 0;
	} else {
		dup->fa &= ~FILE_ATTRIBUTE_DIRECTORY;

		attr = ni_find_attr(ni, NULL, &le, ATTR_DATA, NULL, 0, NULL,
				    &mi);
		if (!attr) {
			dup->alloc_size = dup->data_size = 0;
		} else if (!attr->non_res) {
			u32 data_size = le32_to_cpu(attr->res.data_size);

			dup->alloc_size = cpu_to_le64(ALIGN(data_size, 8));
			dup->data_size = cpu_to_le64(data_size);
		} else {
			u64 new_valid = ni->i_valid;
			u64 data_size = le64_to_cpu(attr->nres.data_size);
			__le64 valid_le;

			dup->alloc_size = is_attr_ext(attr) ?
						  attr->nres.total_size :
						  attr->nres.alloc_size;
			dup->data_size = attr->nres.data_size;

			if (new_valid > data_size)
				new_valid = data_size;

			valid_le = cpu_to_le64(new_valid);
			if (valid_le != attr->nres.valid_size) {
				attr->nres.valid_size = valid_le;
				mi->dirty = true;
			}
		}
	}

	dup->extend_data = 0;

	if (dup->fa & FILE_ATTRIBUTE_REPARSE_POINT) {
		attr = ni_find_attr(ni, NULL, NULL, ATTR_REPARSE, NULL, 0, NULL,
				    NULL);

		if (attr) {
			const struct REPARSE_POINT *rp;

			rp = resident_data_ex(attr,
					      sizeof(struct REPARSE_POINT));
			/* If ATTR_REPARSE exists 'rp' can't be NULL. */
			if (rp)
				dup->extend_data = rp->ReparseTag;
		}
	} else if (ni->ni_flags & NI_FLAG_EA) {
		attr = ni_find_attr(ni, attr, &le, ATTR_EA_INFO, NULL, 0, NULL,
				    NULL);
		if (attr) {
			const struct EA_INFO *info;

			info = resident_data_ex(attr, sizeof(struct EA_INFO));
			/* If ATTR_EA_INFO exists 'info' can't be NULL. */
			if (info)
				dup->extend_data = info->size;
		}
	}

	attr = NULL;
	le = NULL;

	while ((attr = ni_find_attr(ni, attr, &le, ATTR_NAME, NULL, 0, NULL,
				    &mi))) {
		struct inode *dir;
		struct ATTR_FILE_NAME *fname;

		fname = resident_data_ex(attr, SIZEOF_ATTRIBUTE_FILENAME);
		if (!fname || !memcmp(&fname->dup, dup, sizeof(fname->dup)))
			continue;

		/* Check simple case when parent inode equals current inode. */
		if (ino_get(&fname->home) == ni->vfs_inode.i_ino) {
			ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
			continue;
		}

		/* ntfs_iget5 may sleep. */
		dir = ntfs_iget5(sb, &fname->home, NULL);
		if (IS_ERR(dir)) {
			ntfs_inode_warn(
				&ni->vfs_inode,
				"failed to open parent directory r=%llx to update",
				(u64)ino_get(&fname->home));
			continue;
		}

		if (!is_bad_inode(dir)) {
			struct ntfs_inode *dir_ni = ntfs_i(dir);

			if (!ni_trylock(dir_ni)) {
				re_dirty = true;
			} else {
				indx_update_dup(dir_ni, sbi, fname, dup, sync);
				ni_unlock(dir_ni);
				memcpy(&fname->dup, dup, sizeof(fname->dup));
				mi->dirty = true;
			}
		}
		iput(dir);
	}

	return re_dirty;
}

/*
 * ni_write_inode - Write MFT base record and all subrecords to disk.
 */
int ni_write_inode(struct inode *inode, int sync, const char *hint)
{
	int err = 0, err2;
	struct ntfs_inode *ni = ntfs_i(inode);
	struct super_block *sb = inode->i_sb;
	struct ntfs_sb_info *sbi = sb->s_fs_info;
	bool re_dirty = false;
	struct ATTR_STD_INFO *std;
	struct rb_node *node, *next;
	struct NTFS_DUP_INFO dup;

	if (is_bad_inode(inode) || sb_rdonly(sb))
		return 0;

	if (!is_ni_base(ni))
		return 0;

	/* Avoid any operation if inode is bad. */
	if (unlikely(is_bad_ni(ni)))
		return -EINVAL;

	if (unlikely(ntfs3_forced_shutdown(sb)))
		return -EIO;

	if (!ni_trylock(ni)) {
		/* 'ni' is under modification, skip for now. */
		mark_inode_dirty_sync(inode);
		return 0;
	}

	if (!ni->mi.mrec)
		goto out;

	if (is_rec_inuse(ni->mi.mrec) &&
	    !(sbi->flags & NTFS_FLAGS_LOG_REPLAYING) && inode->i_nlink) {
		bool modified = false;
		struct timespec64 ts;

		/* Update times in standard attribute. */
		std = ni_std(ni);
		if (!std) {
			err = -EINVAL;
			goto out;
		}

		/* Update the access times if they have changed. */
		ts = inode_get_mtime(inode);
		dup.m_time = kernel2nt(&ts);
		if (std->m_time != dup.m_time) {
			std->m_time = dup.m_time;
			modified = true;
		}

		ts = inode_get_ctime(inode);
		dup.c_time = kernel2nt(&ts);
		if (std->c_time != dup.c_time) {
			std->c_time = dup.c_time;
			modified = true;
		}

		ts = inode_get_atime(inode);
		dup.a_time = kernel2nt(&ts);
		if (std->a_time != dup.a_time) {
			std->a_time = dup.a_time;
			modified = true;
		}

		dup.fa = ni->std_fa;
		if (std->fa != dup.fa) {
			std->fa = dup.fa;
			modified = true;
		}

		/* std attribute is always in primary MFT record. */
		if (modified)
			ni->mi.dirty = true;

		if (!ntfs_is_meta_file(sbi, inode->i_ino) &&
		    (modified || (ni->ni_flags & NI_FLAG_UPDATE_PARENT))
		    /* Avoid __wait_on_freeing_inode(inode). */
		    && (sb->s_flags & SB_ACTIVE)) {
			dup.cr_time = std->cr_time;
			/* Not critical if this function fail. */
			re_dirty = ni_update_parent(ni, &dup, sync);

			if (re_dirty)
				ni->ni_flags |= NI_FLAG_UPDATE_PARENT;
			else
				ni->ni_flags &= ~NI_FLAG_UPDATE_PARENT;
		}

		/* Update attribute list. */
		if (ni->attr_list.size && ni->attr_list.dirty) {
			if (inode->i_ino != MFT_REC_MFT || sync) {
				err = ni_try_remove_attr_list(ni);
				if (err)
					goto out;
			}

			err = al_update(ni, sync);
			if (err)
				goto out;
		}
	}

	for (node = rb_first(&ni->mi_tree); node; node = next) {
		struct mft_inode *mi = rb_entry(node, struct mft_inode, node);
		bool is_empty;

		next = rb_next(node);

		if (!mi->dirty)
			continue;

		is_empty = !mi_enum_attr(ni, mi, NULL);

		if (is_empty)
			clear_rec_inuse(mi->mrec);

		err2 = mi_write(mi, sync);
		if (!err && err2)
			err = err2;

		if (is_empty) {
			ntfs_mark_rec_free(sbi, mi->rno, false);
			rb_erase(node, &ni->mi_tree);
			mi_put(mi);
		}
	}

	if (ni->mi.dirty) {
		err2 = mi_write(&ni->mi, sync);
		if (!err && err2)
			err = err2;
	}
out:
	ni_unlock(ni);

	if (err) {
		ntfs_inode_err(inode, "%s failed, %d.", hint, err);
		ntfs_set_state(sbi, NTFS_DIRTY_ERROR);
		return err;
	}

	if (re_dirty)
		mark_inode_dirty_sync(inode);

	return 0;
}

/*
 * Force to allocate all delay allocated clusters.
 */
int ni_allocate_da_blocks(struct ntfs_inode *ni)
{
	int err;

	ni_lock(ni);
	down_write(&ni->file.run_lock);

	err = ni_allocate_da_blocks_locked(ni);

	up_write(&ni->file.run_lock);
	ni_unlock(ni);

	return err;
}

/*
 * Force to allocate all delay allocated clusters.
 */
int ni_allocate_da_blocks_locked(struct ntfs_inode *ni)
{
	int err = 0;

	if (!ni->file.run_da.count)
		return 0;

	if (is_sparsed(ni)) {
		CLST vcn, lcn, clen, alen;
		bool new;

		/*
		 * Sparse file allocates clusters in 'attr_data_get_block_locked'
		 */
		while (run_get_entry(&ni->file.run_da, 0, &vcn, &lcn, &clen)) {
			/* TODO: zero=true? */
			err = attr_data_get_block_locked(ni, vcn, clen, &lcn,
							 &alen, &new, true,
							 NULL, true);
			if (err)
				break;
			if (!new) {
				err = -EINVAL;
				break;
			}
		}
	} else {
		/*
		 * Normal file allocates clusters in 'attr_set_size'
		 */
		err = attr_set_size_ex(ni, ATTR_DATA, ni->file.ads.name,
				       ni->file.ads.len, &ni->file.run,
				       ni->vfs_inode.i_size, &ni->i_valid,
				       false, NULL, true);
	}

	return err;
}

/*
 * Helper function to read ADS.
 * bytes = iov_iter_count(iter) is not 0. Checked by caller;
 */
ssize_t ni_query_ads(struct ntfs_inode *ni, loff_t *pos, struct iov_iter *iter)
{
	ssize_t ret = 0;
	struct ntfs_sb_info *sbi = ni->mi.sbi;
	size_t bytes = iov_iter_count(iter);
	loff_t end = *pos + bytes;
	char *buf = NULL;
	struct ATTR_LIST_ENTRY *le = NULL;
	u64 vbo = 0;
	struct ATTRIB *attr;
	size_t done, used;
	int err;

	/*
	 * Enumerate ADS.
	 */
	ni = ni->base;
	attr = NULL;
	while ((attr = ni_enum_attr_ex(ni, attr, &le, NULL))) {
		if (attr->type != ATTR_DATA || !attr->name_len)
			continue;

		if (!buf) {
			buf = kmalloc(PAGE_SIZE, GFP_NOFS);
			if (!buf)
				return -ENOMEM;
		}

		/* attr - named DATA attribute (ADS). */
		err = ntfs_utf16_to_nls(sbi, attr_name(attr), attr->name_len,
					buf, PAGE_SIZE);
		if (err < 0) {
			ret = err;
			break;
		}

		/* 
		 * err is the length of ADS name in bytes.
		 * Copy pseudo data interval [vbo, err + 1).
		 * into 'iter': [*pos, bytes)
		 */
		/* Add \n as streams name separator. */
		buf[err++] = '\n';

		if (vbo >= end) {
			iov_iter_zero(bytes, iter);
			break;
		}

		if (vbo + err > *pos) {
			size_t off = *pos - vbo;
			used = err - off;
			done = copy_to_iter(Add2Ptr(buf, off), min(used, bytes),
					    iter);
		} else {
			done = 0;
		}

		ret += done;
		*pos += done;
		if (done >= bytes)
			break;
		bytes -= done;
		vbo += err;
	}
	kfree(buf);
	return ret;
}
