// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * NTFS kernel mft record operations.
 * Part of this file is based on code from the NTFS-3G.
 *
 * Copyright (c) 2001-2012 Anton Altaparmakov and Tuxera Inc.
 * Copyright (c) 2002 Richard Russon
 * Copyright (c) 2025 LG Electronics Co., Ltd.
 */

#include <linux/writeback.h>
#include <linux/bio.h>
#include <linux/iomap.h>

#include "bitmap.h"
#include "lcnalloc.h"
#include "mft.h"
#include "ntfs.h"

/*
 * ntfs_mft_record_check - Check the consistency of an MFT record
 *
 * Make sure its general fields are safe, then examine all its
 * attributes and apply generic checks to them.
 *
 * Returns 0 if the checks are successful. If not, return -EIO.
 */
int ntfs_mft_record_check(const struct ntfs_volume *vol, struct mft_record *m,
		u64 mft_no)
{
	struct attr_record *a;
	struct super_block *sb = vol->sb;
	u16 attrs_offset;
	u32 bytes_in_use;

	if (!ntfs_is_file_record(m->magic)) {
		ntfs_error(sb, "Record %llu has no FILE magic (0x%x)\n",
				mft_no, le32_to_cpu(*(__le32 *)m));
		goto err_out;
	}

	if (le16_to_cpu(m->usa_ofs) & 0x1 ||
	    (vol->mft_record_size >> NTFS_BLOCK_SIZE_BITS) + 1 != le16_to_cpu(m->usa_count) ||
	    le16_to_cpu(m->usa_ofs) + le16_to_cpu(m->usa_count) * 2 > vol->mft_record_size) {
		ntfs_error(sb, "Record %llu has corrupt fix-up values fields\n",
				mft_no);
		goto err_out;
	}

	if (le32_to_cpu(m->bytes_allocated) != vol->mft_record_size) {
		ntfs_error(sb, "Record %llu has corrupt allocation size (%u <> %u)\n",
				mft_no, vol->mft_record_size,
				le32_to_cpu(m->bytes_allocated));
		goto err_out;
	}

	if (le32_to_cpu(m->bytes_in_use) > vol->mft_record_size) {
		ntfs_error(sb, "Record %llu has corrupt in-use size (%u > %u)\n",
				mft_no, le32_to_cpu(m->bytes_in_use),
				vol->mft_record_size);
		goto err_out;
	}

	if (le16_to_cpu(m->attrs_offset) & 7) {
		ntfs_error(sb, "Attributes badly aligned in record %llu\n",
				mft_no);
		goto err_out;
	}

	attrs_offset = le16_to_cpu(m->attrs_offset);
	bytes_in_use = le32_to_cpu(m->bytes_in_use);

	if (attrs_offset > bytes_in_use ||
	    bytes_in_use - attrs_offset < sizeof_field(struct attr_record, type)) {
		ntfs_error(sb, "Record %llu has corrupt attribute offset\n", mft_no);
		goto err_out;
	}

	a = (struct attr_record *)((char *)m + attrs_offset);
	if ((char *)a < (char *)m || (char *)a > (char *)m + vol->mft_record_size) {
		ntfs_error(sb, "Record %llu is corrupt\n", mft_no);
		goto err_out;
	}

	return 0;

err_out:
	return -EIO;
}

/*
 * map_mft_record_folio - map the folio in which a specific mft record resides
 * @ni:		ntfs inode whose mft record page to map
 *
 * This maps the folio in which the mft record of the ntfs inode @ni is
 * situated.
 *
 * This allocates a new buffer (@ni->mrec), copies the MFT record data from
 * the mapped folio into this buffer, and applies the MST (Multi Sector
 * Transfer) fixups on the copy.
 *
 * The folio is pinned (referenced) in @ni->folio to ensure the data remains
 * valid in the page cache, but the returned pointer is the allocated copy.
 *
 * Return: A pointer to the allocated and fixed-up mft record (@ni->mrec).
 * The return value needs to be checked with IS_ERR(). If it is true,
 * PTR_ERR() contains the negative error code.
 */
static inline struct mft_record *map_mft_record_folio(struct ntfs_inode *ni)
{
	loff_t i_size;
	struct ntfs_volume *vol = ni->vol;
	struct inode *mft_vi = vol->mft_ino;
	struct folio *folio;
	unsigned long index, end_index;
	unsigned int ofs;

	WARN_ON(ni->folio);
	/*
	 * The index into the page cache and the offset within the page cache
	 * page of the wanted mft record.
	 */
	index = NTFS_MFT_NR_TO_PIDX(vol, ni->mft_no);
	ofs = NTFS_MFT_NR_TO_POFS(vol, ni->mft_no);

	i_size = i_size_read(mft_vi);
	/* The maximum valid index into the page cache for $MFT's data. */
	end_index = i_size >> PAGE_SHIFT;

	/* If the wanted index is out of bounds the mft record doesn't exist. */
	if (unlikely(index >= end_index)) {
		if (index > end_index || (i_size & ~PAGE_MASK) < ofs +
				vol->mft_record_size) {
			folio = ERR_PTR(-ENOENT);
			ntfs_error(vol->sb,
				"Attempt to read mft record 0x%llx, which is beyond the end of the mft. This is probably a bug in the ntfs driver.",
				ni->mft_no);
			goto err_out;
		}
	}

	/* Read, map, and pin the folio. */
	folio = read_mapping_folio(mft_vi->i_mapping, index, NULL);
	if (!IS_ERR(folio)) {
		u8 *addr;

		ni->mrec = kmalloc(vol->mft_record_size, GFP_NOFS);
		if (!ni->mrec) {
			folio_put(folio);
			folio = ERR_PTR(-ENOMEM);
			goto err_out;
		}

		addr = kmap_local_folio(folio, 0);
		memcpy(ni->mrec, addr + ofs, vol->mft_record_size);
		post_read_mst_fixup((struct ntfs_record *)ni->mrec, vol->mft_record_size);

		/* Catch multi sector transfer fixup errors. */
		if (!ntfs_mft_record_check(vol, (struct mft_record *)ni->mrec, ni->mft_no)) {
			kunmap_local(addr);
			ni->folio = folio;
			ni->folio_ofs = ofs;
			return ni->mrec;
		}
		kunmap_local(addr);
		folio_put(folio);
		kfree(ni->mrec);
		ni->mrec = NULL;
		folio = ERR_PTR(-EIO);
		NVolSetErrors(vol);
	}
err_out:
	ni->folio = NULL;
	ni->folio_ofs = 0;
	return (struct mft_record *)folio;
}

/*
 * map_mft_record - map and pin an mft record
 * @ni:		ntfs inode whose MFT record to map
 *
 * This function ensures the MFT record for the given inode is mapped and
 * accessible.
 *
 * It increments the reference count of the ntfs inode. If the record is
 * already mapped (@ni->folio is set), it returns the cached record
 * immediately.
 *
 * Otherwise, it calls map_mft_record_folio() to read the folio from disk
 * (if necessary via read_mapping_folio), allocate a buffer, and copy the
 * record data.
 *
 * Return: A pointer to the mft record. You need to check the returned
 * pointer with IS_ERR().
 */
struct mft_record *map_mft_record(struct ntfs_inode *ni)
{
	struct mft_record *m;

	if (!ni)
		return ERR_PTR(-EINVAL);

	ntfs_debug("Entering for mft_no 0x%llx.", ni->mft_no);

	/* Make sure the ntfs inode doesn't go away. */
	atomic_inc(&ni->count);

	if (ni->folio)
		return (struct mft_record *)ni->mrec;

	m = map_mft_record_folio(ni);
	if (!IS_ERR(m))
		return m;

	atomic_dec(&ni->count);
	ntfs_error(ni->vol->sb, "Failed with error code %lu.", -PTR_ERR(m));
	return m;
}

/*
 * unmap_mft_record - release a reference to a mapped mft record
 * @ni:		ntfs inode whose MFT record to unmap
 *
 * This decrements the reference count of the ntfs inode.
 *
 * It releases the caller's hold on the inode. If the reference count indicates
 * that there are still other users (count > 1), the function returns
 * immediately, keeping the resources (folio and mrec buffer) pinned for
 * those users.
 *
 * NOTE: If caller has modified the mft record, it is imperative to set the mft
 * record dirty BEFORE calling unmap_mft_record().
 */
void unmap_mft_record(struct ntfs_inode *ni)
{
	struct folio *folio;

	if (!ni)
		return;

	ntfs_debug("Entering for mft_no 0x%llx.", ni->mft_no);

	folio = ni->folio;
	if (atomic_dec_return(&ni->count) > 1)
		return;
	WARN_ON(!folio);
}

/*
 * map_extent_mft_record - load an extent inode and attach it to its base
 * @base_ni:	base ntfs inode
 * @mref:	mft reference of the extent inode to load
 * @ntfs_ino:	on successful return, pointer to the struct ntfs_inode structure
 *
 * Load the extent mft record @mref and attach it to its base inode @base_ni.
 * Return the mapped extent mft record if IS_ERR(result) is false.  Otherwise
 * PTR_ERR(result) gives the negative error code.
 *
 * On successful return, @ntfs_ino contains a pointer to the ntfs_inode
 * structure of the mapped extent inode.
 */
struct mft_record *map_extent_mft_record(struct ntfs_inode *base_ni, u64 mref,
		struct ntfs_inode **ntfs_ino)
{
	struct mft_record *m;
	struct ntfs_inode *ni = NULL;
	struct ntfs_inode **extent_nis = NULL;
	int i;
	u64 mft_no = MREF(mref);
	u16 seq_no = MSEQNO(mref);
	bool destroy_ni = false;

	ntfs_debug("Mapping extent mft record 0x%llx (base mft record 0x%llx).",
			mft_no, base_ni->mft_no);
	/* Make sure the base ntfs inode doesn't go away. */
	atomic_inc(&base_ni->count);
	/*
	 * Check if this extent inode has already been added to the base inode,
	 * in which case just return it. If not found, add it to the base
	 * inode before returning it.
	 */
retry:
	mutex_lock(&base_ni->extent_lock);
	if (base_ni->nr_extents > 0) {
		extent_nis = base_ni->ext.extent_ntfs_inos;
		for (i = 0; i < base_ni->nr_extents; i++) {
			if (mft_no != extent_nis[i]->mft_no)
				continue;
			ni = extent_nis[i];
			/* Make sure the ntfs inode doesn't go away. */
			atomic_inc(&ni->count);
			break;
		}
	}
	if (likely(ni != NULL)) {
		mutex_unlock(&base_ni->extent_lock);
		atomic_dec(&base_ni->count);
		/* We found the record; just have to map and return it. */
		m = map_mft_record(ni);
		/* map_mft_record() has incremented this on success. */
		atomic_dec(&ni->count);
		if (!IS_ERR(m)) {
			/* Verify the sequence number. */
			if (likely(le16_to_cpu(m->sequence_number) == seq_no)) {
				ntfs_debug("Done 1.");
				*ntfs_ino = ni;
				return m;
			}
			unmap_mft_record(ni);
			ntfs_error(base_ni->vol->sb,
					"Found stale extent mft reference! Corrupt filesystem. Run chkdsk.");
			return ERR_PTR(-EIO);
		}
map_err_out:
		ntfs_error(base_ni->vol->sb,
				"Failed to map extent mft record, error code %ld.",
				-PTR_ERR(m));
		return m;
	}
	mutex_unlock(&base_ni->extent_lock);

	/* Record wasn't there. Get a new ntfs inode and initialize it. */
	ni = ntfs_new_extent_inode(base_ni->vol->sb, mft_no);
	if (unlikely(!ni)) {
		atomic_dec(&base_ni->count);
		return ERR_PTR(-ENOMEM);
	}
	ni->vol = base_ni->vol;
	ni->seq_no = seq_no;
	ni->nr_extents = -1;
	ni->ext.base_ntfs_ino = base_ni;
	/* Now map the record. */
	m = map_mft_record(ni);
	if (IS_ERR(m)) {
		atomic_dec(&base_ni->count);
		ntfs_clear_extent_inode(ni);
		goto map_err_out;
	}
	/* Verify the sequence number if it is present. */
	if (seq_no && (le16_to_cpu(m->sequence_number) != seq_no)) {
		ntfs_error(base_ni->vol->sb,
				"Found stale extent mft reference! Corrupt filesystem. Run chkdsk.");
		destroy_ni = true;
		m = ERR_PTR(-EIO);
		goto unm_nolock_err_out;
	}

	mutex_lock(&base_ni->extent_lock);
	for (i = 0; i < base_ni->nr_extents; i++) {
		if (mft_no == extent_nis[i]->mft_no) {
			mutex_unlock(&base_ni->extent_lock);
			ntfs_clear_extent_inode(ni);
			goto retry;
		}
	}
	/* Attach extent inode to base inode, reallocating memory if needed. */
	if (!(base_ni->nr_extents & 3)) {
		struct ntfs_inode **tmp;
		int new_size = (base_ni->nr_extents + 4) * sizeof(struct ntfs_inode *);

		tmp = kvzalloc(new_size, GFP_NOFS);
		if (unlikely(!tmp)) {
			ntfs_error(base_ni->vol->sb, "Failed to allocate internal buffer.");
			destroy_ni = true;
			m = ERR_PTR(-ENOMEM);
			goto unm_err_out;
		}
		if (base_ni->nr_extents) {
			WARN_ON(!base_ni->ext.extent_ntfs_inos);
			memcpy(tmp, base_ni->ext.extent_ntfs_inos, new_size -
					4 * sizeof(struct ntfs_inode *));
			kvfree(base_ni->ext.extent_ntfs_inos);
		}
		base_ni->ext.extent_ntfs_inos = tmp;
	}
	base_ni->ext.extent_ntfs_inos[base_ni->nr_extents++] = ni;
	mutex_unlock(&base_ni->extent_lock);
	atomic_dec(&base_ni->count);
	ntfs_debug("Done 2.");
	*ntfs_ino = ni;
	return m;
unm_err_out:
	mutex_unlock(&base_ni->extent_lock);
unm_nolock_err_out:
	unmap_mft_record(ni);
	atomic_dec(&base_ni->count);
	/*
	 * If the extent inode was not attached to the base inode we need to
	 * release it or we will leak memory.
	 */
	if (destroy_ni)
		ntfs_clear_extent_inode(ni);
	return m;
}

/*
 * __mark_mft_record_dirty - mark the base vfs inode dirty
 * @ni:		ntfs inode describing the mapped mft record
 *
 * Internal function.  Users should call mark_mft_record_dirty() instead.
 *
 * This function determines the base ntfs inode (in case @ni is an extent
 * inode) and marks the corresponding VFS inode dirty.
 *
 * NOTE:  We only set I_DIRTY_DATASYNC (and not I_DIRTY_PAGES)
 * on the base vfs inode, because even though file data may have been modified,
 * it is dirty in the inode meta data rather than the data page cache of the
 * inode, and thus there are no data pages that need writing out.  Therefore, a
 * full mark_inode_dirty() is overkill.  A mark_inode_dirty_sync(), on the
 * other hand, is not sufficient, because ->write_inode needs to be called even
 * in case of fdatasync. This needs to happen or the file data would not
 * necessarily hit the device synchronously, even though the vfs inode has the
 * O_SYNC flag set.  Also, I_DIRTY_DATASYNC simply "feels" better than just
 * I_DIRTY_SYNC, since the file data has not actually hit the block device yet,
 * which is not what I_DIRTY_SYNC on its own would suggest.
 */
void __mark_mft_record_dirty(struct ntfs_inode *ni)
{
	struct ntfs_inode *base_ni;

	ntfs_debug("Entering for inode 0x%llx.", ni->mft_no);
	WARN_ON(NInoAttr(ni));
	/* Determine the base vfs inode and mark it dirty, too. */
	if (likely(ni->nr_extents >= 0))
		base_ni = ni;
	else
		base_ni = ni->ext.base_ntfs_ino;
	__mark_inode_dirty(VFS_I(base_ni), I_DIRTY_DATASYNC);
}

/*
 * ntfs_bio_end_io - bio completion callback for MFT record writes
 *
 * Decrements the folio reference count that was incremented before
 * submit_bio(). This prevents a race condition where umount could
 * evict the inode and release the folio while I/O is still in flight,
 * potentially causing data corruption or use-after-free.
 */
static void ntfs_bio_end_io(struct bio *bio)
{
	if (bio->bi_private)
		folio_put((struct folio *)bio->bi_private);
	bio_put(bio);
}

/*
 * ntfs_sync_mft_mirror - synchronize an mft record to the mft mirror
 * @vol:	ntfs volume on which the mft record to synchronize resides
 * @mft_no:	mft record number of mft record to synchronize
 * @m:		mapped, mst protected (extent) mft record to synchronize
 *
 * Write the mapped, mst protected (extent) mft record @m with mft record
 * number @mft_no to the mft mirror ($MFTMirr) of the ntfs volume @vol.
 *
 * On success return 0.  On error return -errno and set the volume errors flag
 * in the ntfs volume @vol.
 *
 * NOTE:  We always perform synchronous i/o.
 */
int ntfs_sync_mft_mirror(struct ntfs_volume *vol, const u64 mft_no,
		struct mft_record *m)
{
	u8 *kmirr;
	struct folio *folio;
	unsigned int folio_ofs, lcn_folio_off = 0;
	int err = 0;
	struct bio *bio;

	ntfs_debug("Entering for inode 0x%llx.", mft_no);

	if (unlikely(!vol->mftmirr_ino)) {
		/* This could happen during umount... */
		err = -EIO;
		goto err_out;
	}
	/* Get the page containing the mirror copy of the mft record @m. */
	folio = read_mapping_folio(vol->mftmirr_ino->i_mapping,
			NTFS_MFT_NR_TO_PIDX(vol, mft_no), NULL);
	if (IS_ERR(folio)) {
		ntfs_error(vol->sb, "Failed to map mft mirror page.");
		err = PTR_ERR(folio);
		goto err_out;
	}

	folio_lock(folio);
	folio_clear_uptodate(folio);
	/* Offset of the mft mirror record inside the page. */
	folio_ofs = NTFS_MFT_NR_TO_POFS(vol, mft_no);
	/* The address in the page of the mirror copy of the mft record @m. */
	kmirr = kmap_local_folio(folio, 0) + folio_ofs;
	/* Copy the mst protected mft record to the mirror. */
	memcpy(kmirr, m, vol->mft_record_size);
	kunmap_local(kmirr);

	if (vol->cluster_size_bits > PAGE_SHIFT) {
		lcn_folio_off = folio->index << PAGE_SHIFT;
		lcn_folio_off &= vol->cluster_size_mask;
	}

	bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE, GFP_NOIO);
	bio->bi_iter.bi_sector =
		NTFS_B_TO_SECTOR(vol, NTFS_CLU_TO_B(vol, vol->mftmirr_lcn) +
				 lcn_folio_off + folio_ofs);

	if (bio_add_folio(bio, folio, vol->mft_record_size, folio_ofs))
		err = submit_bio_wait(bio);
	else
		err = -EIO;
	bio_put(bio);

	/*
	 * The in-memory mirror is now valid because we just memcpy()'d the
	 * mst-protected mft record into it.  Mark the folio uptodate even on
	 * write error so a subsequent read_mapping_folio() does not refetch
	 * the stale on-disk mirror and overwrite this copy.  The error is
	 * propagated to the caller via @err.
	 */
	folio_mark_uptodate(folio);

	folio_unlock(folio);
	folio_put(folio);
	if (likely(!err)) {
		ntfs_debug("Done.");
	} else {
		ntfs_error(vol->sb, "I/O error while writing mft mirror record 0x%llx!", mft_no);
err_out:
		ntfs_error(vol->sb,
			"Failed to synchronize $MFTMirr (error code %i).  Volume will be left marked dirty on umount.  Run chkdsk on the partition after umounting to correct this.",
			err);
		NVolSetErrors(vol);
	}
	return err;
}

/*
 * write_mft_record_nolock - write out a mapped (extent) mft record
 * @ni:		ntfs inode describing the mapped (extent) mft record
 * @m:		mapped (extent) mft record to write
 * @sync:	if true, wait for i/o completion
 *
 * Write the mapped (extent) mft record @m described by the (regular or extent)
 * ntfs inode @ni to backing store.  If the mft record @m has a counterpart in
 * the mft mirror, that is also updated.
 *
 * We only write the mft record if the ntfs inode @ni is dirty.
 *
 * On success, clean the mft record and return 0.
 * On error (specifically ENOMEM), we redirty the record so it can be retried.
 * For other errors, we mark the volume with errors.
 */
int write_mft_record_nolock(struct ntfs_inode *ni, struct mft_record *m, int sync)
{
	struct ntfs_volume *vol = ni->vol;
	struct folio *folio = ni->folio;
	int err = 0, i = 0;
	u8 *kaddr;
	struct mft_record *fixup_m;
	struct bio *bio;
	unsigned int offset = 0, folio_size;

	ntfs_debug("Entering for inode 0x%llx.", ni->mft_no);

	WARN_ON(NInoAttr(ni));
	WARN_ON(!folio_test_locked(folio));

	/*
	 * If the struct ntfs_inode is clean no need to do anything.  If it is dirty,
	 * mark it as clean now so that it can be redirtied later on if needed.
	 * There is no danger of races since the caller is holding the locks
	 * for the mft record @m and the page it is in.
	 */
	if (!NInoTestClearDirty(ni))
		goto done;

	kaddr = kmap_local_folio(folio, 0);
	fixup_m = (struct mft_record *)(kaddr + ni->folio_ofs);
	memcpy(fixup_m, m, vol->mft_record_size);

	/* Apply the mst protection fixups. */
	err = pre_write_mst_fixup((struct ntfs_record *)fixup_m, vol->mft_record_size);
	if (err) {
		ntfs_error(vol->sb, "Failed to apply mst fixups!");
		goto err_out;
	}

	folio_size = vol->mft_record_size / ni->mft_lcn_count;
	while (i < ni->mft_lcn_count) {
		unsigned int clu_off;

		clu_off = (unsigned int)((s64)ni->mft_no * vol->mft_record_size + offset) &
			vol->cluster_size_mask;

		bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE, GFP_NOIO);
		bio->bi_iter.bi_sector =
			NTFS_B_TO_SECTOR(vol, NTFS_CLU_TO_B(vol, ni->mft_lcn[i]) +
					 clu_off);

		if (!bio_add_folio(bio, folio, folio_size,
				   ni->folio_ofs + offset)) {
			err = -EIO;
			goto put_bio_out;
		}

		/* Synchronize the mft mirror now if not @sync. */
		if (!sync && ni->mft_no < vol->mftmirr_size) {
			int sub_err = ntfs_sync_mft_mirror(vol, ni->mft_no,
							   fixup_m);
			if (unlikely(sub_err) && !err)
				err = sub_err;
		}

		if (sync) {
			int sub_err = submit_bio_wait(bio);

			bio_put(bio);
			if (unlikely(sub_err) && !err)
				err = sub_err;
		} else {
			folio_get(folio);
			bio->bi_private = folio;
			bio->bi_end_io = ntfs_bio_end_io;
			submit_bio(bio);
		}
		offset += vol->cluster_size;
		i++;
	}

	/* If @sync, now synchronize the mft mirror. */
	if (sync && ni->mft_no < vol->mftmirr_size) {
		int sub_err = ntfs_sync_mft_mirror(vol, ni->mft_no, fixup_m);

		if (unlikely(sub_err) && !err)
			err = sub_err;
	}
	kunmap_local(kaddr);
	if (unlikely(err)) {
		/* I/O error during writing.  This is really bad! */
		ntfs_error(vol->sb,
			"I/O error while writing mft record 0x%llx!  Marking base inode as bad.  You should unmount the volume and run chkdsk.",
			ni->mft_no);
		goto err_out;
	}
done:
	ntfs_debug("Done.");
	return 0;
put_bio_out:
	bio_put(bio);
err_out:
	/*
	 * The caller should mark the base inode as bad so no more I/O
	 * happens. ->drop_inode() will still be invoked so all extent inodes
	 * and other allocated memory will be freed. ENOMEM is retried by
	 * redirtying the mft record below.
	 */
	if (err == -ENOMEM) {
		ntfs_error(vol->sb,
			"Not enough memory to write mft record. Redirtying so the write is retried later.");
		mark_mft_record_dirty(ni);
		err = 0;
	} else
		NVolSetErrors(vol);
	return err;
}

static int ntfs_test_inode_wb(struct inode *vi, u64 ino, void *data)
{
	struct ntfs_attr *na = data;

	if (!ntfs_test_inode(vi, na))
		return 0;

	/*
	 * Without this, ntfs_write_mst_block() could call iput_final()
	 * , and ntfs_evict_big_inode() could try to unlink this inode
	 * and the contex could be blocked infinitly in map_mft_record().
	 */
	if (NInoBeingDeleted(NTFS_I(vi))) {
		na->state = NI_BeingDeleted;
		return -1;
	}

	/*
	 * This condition can prevent ntfs_write_mst_block()
	 * from applying/undo fixups while ntfs_create() being
	 * called
	 */
	spin_lock(&vi->i_lock);
	if (inode_state_read_once(vi) & I_CREATING) {
		spin_unlock(&vi->i_lock);
		na->state = NI_BeingCreated;
		return -1;
	}
	spin_unlock(&vi->i_lock);

	return igrab(vi) ? 1 : -1;
}

/*
 * ntfs_may_write_mft_record - check if an mft record may be written out
 * @vol:	[IN]  ntfs volume on which the mft record to check resides
 * @mft_no:	[IN]  mft record number of the mft record to check
 * @m:		[IN]  mapped mft record to check
 * @locked_ni:	[OUT] caller has to unlock this ntfs inode if one is returned
 * @ref_vi:	[OUT] caller has to drop this vfs inode if one is returned
 *
 * Check if the mapped (base or extent) mft record @m with mft record number
 * @mft_no belonging to the ntfs volume @vol may be written out.  If necessary
 * and possible the ntfs inode of the mft record is locked and the base vfs
 * inode is pinned.  The locked ntfs inode is then returned in @locked_ni.  The
 * caller is responsible for unlocking the ntfs inode and unpinning the base
 * vfs inode.
 *
 * To avoid deadlock when the caller holds a folio lock, if the function
 * returns @ref_vi it defers dropping the vfs inode reference by returning
 * it in @ref_vi instead of calling iput() directly.  The caller must call
 * iput() on @ref_vi after releasing the folio lock.
 *
 * Return 'true' if the mft record may be written out and 'false' if not.
 *
 * The caller has locked the page and cleared the uptodate flag on it which
 * means that we can safely write out any dirty mft records that do not have
 * their inodes in icache as determined by find_inode_nowait().
 *
 * Here is a description of the tests we perform:
 *
 * If the inode is found in icache we know the mft record must be a base mft
 * record.  If it is dirty, we do not write it and return 'false' as the vfs
 * inode write paths will result in the access times being updated which would
 * cause the base mft record to be redirtied and written out again.
 *
 * If the inode is in icache and not dirty, we attempt to lock the mft record
 * and if we find the lock was already taken, it is not safe to write the mft
 * record and we return 'false'.
 *
 * If we manage to obtain the lock we have exclusive access to the mft record,
 * which also allows us safe writeout of the mft record.  We then set
 * @locked_ni to the locked ntfs inode and return 'true'.
 *
 * Note we cannot just lock the mft record and sleep while waiting for the lock
 * because this would deadlock due to lock reversal.
 *
 * If the inode is not in icache we need to perform further checks.
 *
 * If the mft record is not a FILE record or it is a base mft record, we can
 * safely write it and return 'true'.
 */
static bool ntfs_may_write_mft_record(struct ntfs_volume *vol, const u64 mft_no,
		const struct mft_record *m, struct ntfs_inode **locked_ni,
		struct inode **ref_vi)
{
	struct super_block *sb = vol->sb;
	struct inode *mft_vi = vol->mft_ino;
	struct inode *vi;
	struct ntfs_inode *ni;
	struct ntfs_attr na = {0};

	ntfs_debug("Entering for inode 0x%llx.", mft_no);
	/*
	 * Normally we do not return a locked inode so set @locked_ni to NULL.
	 */
	*locked_ni = NULL;
	*ref_vi = NULL;

	/*
	 * Check if the inode corresponding to this mft record is in the VFS
	 * inode cache and obtain a reference to it if it is.
	 */
	ntfs_debug("Looking for inode 0x%llx in icache.", mft_no);
	na.mft_no = mft_no;
	na.type = AT_UNUSED;
	/*
	 * Optimize inode 0, i.e. $MFT itself, since we have it in memory and
	 * we get here for it rather often.
	 */
	if (!mft_no) {
		/* Balance the below iput(). */
		vi = igrab(mft_vi);
		WARN_ON(vi != mft_vi);
	} else {
		/*
		 * Have to use find_inode_nowait() since ilookup5_nowait()
		 * waits for inode with I_FREEING, which causes ntfs to deadlock
		 * when inodes are unlinked concurrently
		 */
		vi = find_inode_nowait(sb, mft_no, ntfs_test_inode_wb, &na);
		if (na.state == NI_BeingDeleted || na.state == NI_BeingCreated)
			return false;
	}
	if (vi) {
		ntfs_debug("Base inode 0x%llx is in icache.", mft_no);
		/* The inode is in icache. */
		ni = NTFS_I(vi);
		/* Take a reference to the ntfs inode. */
		atomic_inc(&ni->count);
		/* If the inode is dirty, do not write this record. */
		if (NInoDirty(ni)) {
			ntfs_debug("Inode 0x%llx is dirty, do not write it.",
					mft_no);
			atomic_dec(&ni->count);
			*ref_vi = vi;
			return false;
		}
		ntfs_debug("Inode 0x%llx is not dirty.", mft_no);
		/* The inode is not dirty, try to take the mft record lock. */
		if (unlikely(!mutex_trylock(&ni->mrec_lock))) {
			ntfs_debug("Mft record 0x%llx is already locked, do not write it.", mft_no);
			atomic_dec(&ni->count);
			*ref_vi = vi;
			return false;
		}
		ntfs_debug("Managed to lock mft record 0x%llx, write it.",
				mft_no);
		/*
		 * The write has to occur while we hold the mft record lock so
		 * return the locked ntfs inode.
		 */
		*locked_ni = ni;
		return true;
	}
	ntfs_debug("Inode 0x%llx is not in icache.", mft_no);
	/* The inode is not in icache. */
	/* Write the record if it is not a mft record (type "FILE"). */
	if (!ntfs_is_mft_record(m->magic)) {
		ntfs_debug("Mft record 0x%llx is not a FILE record, write it.",
				mft_no);
		return true;
	}
	/* Write the mft record if it is a base inode. */
	if (!m->base_mft_record) {
		ntfs_debug("Mft record 0x%llx is a base record, write it.",
				mft_no);
		return true;
	}

	ntfs_debug("Mft record 0x%llx is an extent record, skip it.",
		   mft_no);
	return false;
}

static const char *es = "  Leaving inconsistent metadata.  Unmount and run chkdsk.";

#define RESERVED_MFT_RECORDS	64

/*
 * ntfs_mft_bitmap_find_and_alloc_free_rec_nolock - see name
 * @vol:	volume on which to search for a free mft record
 * @base_ni:	open base inode if allocating an extent mft record or NULL
 *
 * Search for a free mft record in the mft bitmap attribute on the ntfs volume
 * @vol.
 *
 * If @base_ni is NULL start the search at the default allocator position.
 *
 * If @base_ni is not NULL start the search at the mft record after the base
 * mft record @base_ni.
 *
 * Return the free mft record on success and -errno on error.  An error code of
 * -ENOSPC means that there are no free mft records in the currently
 * initialized mft bitmap.
 *
 * Locking: Caller must hold vol->mftbmp_lock for writing.
 */
static s64 ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(struct ntfs_volume *vol,
		struct ntfs_inode *base_ni)
{
	s64 pass_end, ll, data_pos, pass_start, ofs, bit;
	unsigned long flags;
	struct address_space *mftbmp_mapping;
	u8 *buf = NULL, *byte;
	struct folio *folio;
	unsigned int folio_ofs, size;
	u8 pass, b;

	ntfs_debug("Searching for free mft record in the currently initialized mft bitmap.");
	mftbmp_mapping = vol->mftbmp_ino->i_mapping;
	/*
	 * Set the end of the pass making sure we do not overflow the mft
	 * bitmap.
	 */
	read_lock_irqsave(&NTFS_I(vol->mft_ino)->size_lock, flags);
	pass_end = NTFS_I(vol->mft_ino)->allocated_size >>
			vol->mft_record_size_bits;
	read_unlock_irqrestore(&NTFS_I(vol->mft_ino)->size_lock, flags);
	read_lock_irqsave(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);
	ll = NTFS_I(vol->mftbmp_ino)->initialized_size << 3;
	read_unlock_irqrestore(&NTFS_I(vol->mftbmp_ino)->size_lock, flags);
	if (pass_end > ll)
		pass_end = ll;
	pass = 1;
	if (!base_ni)
		data_pos = vol->mft_data_pos;
	else
		data_pos = base_ni->mft_no + 1;
	if (data_pos < RESERVED_MFT_RECORDS)
		data_pos = RESERVED_MFT_RECORDS;
	if (data_pos >= pass_end) {
		data_pos = RESERVED_MFT_RECORDS;
		pass = 2;
		/* This happens on a freshly formatted volume. */
		if (data_pos >= pass_end)
			return -ENOSPC;
	}

	if (base_ni && base_ni->mft_no == FILE_MFT) {
		data_pos = 0;
		pass = 2;
	}

	pass_start = data_pos;
	ntfs_debug("Starting bitmap search: pass %u, pass_start 0x%llx, pass_end 0x%llx, data_pos 0x%llx.",
			pass, pass_start, pass_end, data_pos);
	/* Loop until a free mft record is found. */
	for (; pass <= 2;) {
		/* Cap size to pass_end. */
		ofs = data_pos >> 3;
		folio_ofs = ofs & ~PAGE_MASK;
		size = PAGE_SIZE - folio_ofs;
		ll = ((pass_end + 7) >> 3) - ofs;
		if (size > ll)
			size = ll;
		size <<= 3;
		/*
		 * If we are still within the active pass, search the next page
		 * for a zero bit.
		 */
		if (size) {
			folio = read_mapping_folio(mftbmp_mapping,
					ofs >> PAGE_SHIFT, NULL);
			if (IS_ERR(folio)) {
				ntfs_error(vol->sb, "Failed to read mft bitmap, aborting.");
				return PTR_ERR(folio);
			}
			folio_lock(folio);
			buf = (u8 *)kmap_local_folio(folio, 0) + folio_ofs;
			bit = data_pos & 7;
			data_pos &= ~7ull;
			ntfs_debug("Before inner for loop: size 0x%x, data_pos 0x%llx, bit 0x%llx",
					size, data_pos, bit);
			for (; bit < size && data_pos + bit < pass_end;
					bit &= ~7ull, bit += 8) {
				/*
				 * If we're extending $MFT and running out of the first
				 * mft record (base record) then give up searching since
				 * no guarantee that the found record will be accessible.
				 */
				if (base_ni && base_ni->mft_no == FILE_MFT && bit > 400) {
					folio_unlock(folio);
					kunmap_local(buf);
					folio_put(folio);
					return -ENOSPC;
				}

				byte = buf + (bit >> 3);
				if (*byte == 0xff)
					continue;
				b = ffz((unsigned long)*byte);
				if (b < 8 && b >= (bit & 7)) {
					ll = data_pos + (bit & ~7ull) + b;
					if (unlikely(ll >= (1ll << 32))) {
						folio_unlock(folio);
						kunmap_local(buf);
						folio_put(folio);
						return -ENOSPC;
					}
					*byte |= 1 << b;
					folio_mark_dirty(folio);
					folio_unlock(folio);
					kunmap_local(buf);
					folio_put(folio);
					ntfs_debug("Done.  (Found and allocated mft record 0x%llx.)",
							ll);
					return ll;
				}
			}
			ntfs_debug("After inner for loop: size 0x%x, data_pos 0x%llx, bit 0x%llx",
					size, data_pos, bit);
			data_pos += size;
			folio_unlock(folio);
			kunmap_local(buf);
			folio_put(folio);
			/*
			 * If the end of the pass has not been reached yet,
			 * continue searching the mft bitmap for a zero bit.
			 */
			if (data_pos < pass_end)
				continue;
		}
		/* Do the next pass. */
		if (++pass == 2) {
			/*
			 * Starting the second pass, in which we scan the first
			 * part of the zone which we omitted earlier.
			 */
			pass_end = pass_start;
			data_pos = pass_start = RESERVED_MFT_RECORDS;
			ntfs_debug("pass %i, pass_start 0x%llx, pass_end 0x%llx.",
					pass, pass_start, pass_end);
			if (data_pos >= pass_end)
				break;
		}
	}
	/* No free mft records in currently initialized mft bitmap. */
	ntfs_debug("Done.  (No free mft records left in currently initialized mft bitmap.)");
	return -ENOSPC;
}

static int ntfs_mft_attr_extend(struct ntfs_inode *ni)
{
	int ret = 0;
	struct ntfs_inode *base_ni;

	if (NInoAttr(ni))
		base_ni = ni->ext.base_ntfs_ino;
	else
		base_ni = ni;

	if (!NInoAttrList(base_ni)) {
		ret = ntfs_inode_add_attrlist(base_ni);
		if (ret) {
			pr_err("Can not add attrlist\n");
			goto out;
		} else {
			ret = -EAGAIN;
			goto out;
		}
	}

	ret = ntfs_attr_update_mapping_pairs(ni, 0);
	if (ret)
		pr_err("MP update failed\n");

out:
	return ret;
}

/*
 * ntfs_mft_bitmap_extend_allocation_nolock - extend mft bitmap by a cluster
 * @vol:	volume on which to extend the mft bitmap attribute
 *
 * Extend the mft bitmap attribute on the ntfs volume @vol by one cluster.
 *
 * Note: Only changes allocated_size, i.e. does not touch initialized_size or
 * data_size.
 *
 * Return 0 on success and -errno on error.
 *
 * Locking: - Caller must hold vol->mftbmp_lock for writing.
 *	    - This function takes NTFS_I(vol->mftbmp_ino)->runlist.lock for
 *	      writing and releases it before returning.
 *	    - This function takes vol->lcnbmp_lock for writing and releases it
 *	      before returning.
 */
static int ntfs_mft_bitmap_extend_allocation_nolock(struct ntfs_volume *vol)
{
	s64 lcn;
	s64 ll;
	unsigned long flags;
	struct folio *folio;
	struct ntfs_inode *mft_ni, *mftbmp_ni;
	struct runlist_element *rl, *rl2 = NULL;
	struct ntfs_attr_search_ctx *ctx = NULL;
	struct mft_record *mrec;
	struct attr_record *a = NULL;
	int ret, mp_size;
	u32 old_alen = 0;
	u8 *b, tb;
	struct {
		u8 added_cluster:1;
		u8 added_run:1;
		u8 mp_rebuilt:1;
		u8 mp_extended:1;
	} status = { 0, 0, 0, 0 };
	size_t new_rl_count;

	ntfs_debug("Extending mft bitmap allocation.");
	mft_ni = NTFS_I(vol->mft_ino);
	mftbmp_ni = NTFS_I(vol->mftbmp_ino);
	/*
	 * Determine the last lcn of the mft bitmap.  The allocated size of the
	 * mft bitmap cannot be zero so we are ok to do this.
	 */
	down_write(&mftbmp_ni->runlist.lock);
	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
	ll = mftbmp_ni->allocated_size;
	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	rl = ntfs_attr_find_vcn_nolock(mftbmp_ni,
			NTFS_B_TO_CLU(vol, ll - 1), NULL);
	if (IS_ERR(rl) || unlikely(!rl->length || rl->lcn < 0)) {
		up_write(&mftbmp_ni->runlist.lock);
		ntfs_error(vol->sb,
			"Failed to determine last allocated cluster of mft bitmap attribute.");
		if (!IS_ERR(rl))
			ret = -EIO;
		else
			ret = PTR_ERR(rl);
		return ret;
	}
	lcn = rl->lcn + rl->length;
	ntfs_debug("Last lcn of mft bitmap attribute is 0x%llx.",
			(long long)lcn);
	/*
	 * Attempt to get the cluster following the last allocated cluster by
	 * hand as it may be in the MFT zone so the allocator would not give it
	 * to us.
	 */
	ll = lcn >> 3;
	folio = read_mapping_folio(vol->lcnbmp_ino->i_mapping,
			ll >> PAGE_SHIFT, NULL);
	if (IS_ERR(folio)) {
		up_write(&mftbmp_ni->runlist.lock);
		ntfs_error(vol->sb, "Failed to read from lcn bitmap.");
		return PTR_ERR(folio);
	}

	down_write(&vol->lcnbmp_lock);
	folio_lock(folio);
	b = (u8 *)kmap_local_folio(folio, 0) + (ll & ~PAGE_MASK);
	tb = 1 << (lcn & 7ull);
	if (*b != 0xff && !(*b & tb)) {
		/* Next cluster is free, allocate it. */
		*b |= tb;
		folio_mark_dirty(folio);
		folio_unlock(folio);
		kunmap_local(b);
		folio_put(folio);
		up_write(&vol->lcnbmp_lock);
		/* Update the mft bitmap runlist. */
		rl->length++;
		rl[1].vcn++;
		status.added_cluster = 1;
		ntfs_debug("Appending one cluster to mft bitmap.");
	} else {
		folio_unlock(folio);
		kunmap_local(b);
		folio_put(folio);
		up_write(&vol->lcnbmp_lock);
		/* Allocate a cluster from the DATA_ZONE. */
		rl2 = ntfs_cluster_alloc(vol, rl[1].vcn, 1, lcn, DATA_ZONE,
				true, false, false);
		if (IS_ERR(rl2)) {
			up_write(&mftbmp_ni->runlist.lock);
			ntfs_error(vol->sb,
					"Failed to allocate a cluster for the mft bitmap.");
			return PTR_ERR(rl2);
		}
		rl = ntfs_runlists_merge(&mftbmp_ni->runlist, rl2, 0, &new_rl_count);
		if (IS_ERR(rl)) {
			up_write(&mftbmp_ni->runlist.lock);
			ntfs_error(vol->sb, "Failed to merge runlists for mft bitmap.");
			if (ntfs_cluster_free_from_rl(vol, rl2)) {
				ntfs_error(vol->sb, "Failed to deallocate allocated cluster.%s",
						es);
				NVolSetErrors(vol);
			}
			kvfree(rl2);
			return PTR_ERR(rl);
		}
		mftbmp_ni->runlist.rl = rl;
		mftbmp_ni->runlist.count = new_rl_count;
		status.added_run = 1;
		ntfs_debug("Adding one run to mft bitmap.");
		/* Find the last run in the new runlist. */
		for (; rl[1].length; rl++)
			;
	}
	/*
	 * Update the attribute record as well.  Note: @rl is the last
	 * (non-terminator) runlist element of mft bitmap.
	 */
	mrec = map_mft_record(mft_ni);
	if (IS_ERR(mrec)) {
		ntfs_error(vol->sb, "Failed to map mft record.");
		ret = PTR_ERR(mrec);
		goto undo_alloc;
	}
	ctx = ntfs_attr_get_search_ctx(mft_ni, mrec);
	if (unlikely(!ctx)) {
		ntfs_error(vol->sb, "Failed to get search context.");
		ret = -ENOMEM;
		goto undo_alloc;
	}
	ret = ntfs_attr_lookup(mftbmp_ni->type, mftbmp_ni->name,
			mftbmp_ni->name_len, CASE_SENSITIVE, rl[1].vcn, NULL,
			0, ctx);
	if (unlikely(ret)) {
		ntfs_error(vol->sb,
			"Failed to find last attribute extent of mft bitmap attribute.");
		if (ret == -ENOENT)
			ret = -EIO;
		goto undo_alloc;
	}
	a = ctx->attr;
	ll = le64_to_cpu(a->data.non_resident.lowest_vcn);
	/* Search back for the previous last allocated cluster of mft bitmap. */
	for (rl2 = rl; rl2 > mftbmp_ni->runlist.rl; rl2--) {
		if (ll >= rl2->vcn)
			break;
	}
	WARN_ON(ll < rl2->vcn);
	WARN_ON(ll >= rl2->vcn + rl2->length);
	/* Get the size for the new mapping pairs array for this extent. */
	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1, -1);
	if (unlikely(mp_size <= 0)) {
		ntfs_error(vol->sb,
			"Get size for mapping pairs failed for mft bitmap attribute extent.");
		ret = mp_size;
		if (!ret)
			ret = -EIO;
		goto undo_alloc;
	}
	/* Expand the attribute record if necessary. */
	old_alen = le32_to_cpu(a->length);
	ret = ntfs_attr_record_resize(ctx->mrec, a, mp_size +
			le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
	if (unlikely(ret)) {
		ret = ntfs_mft_attr_extend(mftbmp_ni);
		if (!ret)
			goto extended_ok;
		if (ret != -EAGAIN)
			status.mp_extended = 1;
		goto undo_alloc;
	}
	status.mp_rebuilt = 1;
	/* Generate the mapping pairs array directly into the attr record. */
	ret = ntfs_mapping_pairs_build(vol, (u8 *)a +
			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
			mp_size, rl2, ll, -1, NULL, NULL, NULL);
	if (unlikely(ret)) {
		ntfs_error(vol->sb,
			"Failed to build mapping pairs array for mft bitmap attribute.");
		goto undo_alloc;
	}
	/* Update the highest_vcn. */
	a->data.non_resident.highest_vcn = cpu_to_le64(rl[1].vcn - 1);
	/*
	 * We now have extended the mft bitmap allocated_size by one cluster.
	 * Reflect this in the struct ntfs_inode structure and the attribute record.
	 */
	if (a->data.non_resident.lowest_vcn) {
		/*
		 * We are not in the first attribute extent, switch to it, but
		 * first ensure the changes will make it to disk later.
		 */
		mark_mft_record_dirty(ctx->ntfs_ino);
extended_ok:
		ntfs_attr_reinit_search_ctx(ctx);
		ret = ntfs_attr_lookup(mftbmp_ni->type, mftbmp_ni->name,
				mftbmp_ni->name_len, CASE_SENSITIVE, 0, NULL,
				0, ctx);
		if (unlikely(ret)) {
			ntfs_error(vol->sb,
				"Failed to find first attribute extent of mft bitmap attribute.");
			goto restore_undo_alloc;
		}
		a = ctx->attr;
	}

	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
	mftbmp_ni->allocated_size += vol->cluster_size;
	a->data.non_resident.allocated_size =
			cpu_to_le64(mftbmp_ni->allocated_size);
	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	/* Ensure the changes make it to disk. */
	mark_mft_record_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(mft_ni);
	up_write(&mftbmp_ni->runlist.lock);
	ntfs_debug("Done.");
	return 0;

restore_undo_alloc:
	ntfs_attr_reinit_search_ctx(ctx);
	if (ntfs_attr_lookup(mftbmp_ni->type, mftbmp_ni->name,
			mftbmp_ni->name_len, CASE_SENSITIVE, rl[1].vcn, NULL,
			0, ctx)) {
		ntfs_error(vol->sb,
			"Failed to find last attribute extent of mft bitmap attribute.%s", es);
		write_lock_irqsave(&mftbmp_ni->size_lock, flags);
		mftbmp_ni->allocated_size += vol->cluster_size;
		write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
		ntfs_attr_put_search_ctx(ctx);
		unmap_mft_record(mft_ni);
		up_write(&mftbmp_ni->runlist.lock);
		/*
		 * The only thing that is now wrong is ->allocated_size of the
		 * base attribute extent which chkdsk should be able to fix.
		 */
		NVolSetErrors(vol);
		return ret;
	}
	a = ctx->attr;
	a->data.non_resident.highest_vcn = cpu_to_le64(rl[1].vcn - 2);
undo_alloc:
	if (status.added_cluster) {
		/* Truncate the last run in the runlist by one cluster. */
		rl->length--;
		rl[1].vcn--;
	} else if (status.added_run) {
		lcn = rl->lcn;
		/* Remove the last run from the runlist. */
		rl->lcn = rl[1].lcn;
		rl->length = 0;
		mftbmp_ni->runlist.count--;
	}
	/* Deallocate the cluster. */
	down_write(&vol->lcnbmp_lock);
	if (ntfs_bitmap_clear_bit(vol->lcnbmp_ino, lcn)) {
		ntfs_error(vol->sb, "Failed to free allocated cluster.%s", es);
		NVolSetErrors(vol);
	} else
		ntfs_inc_free_clusters(vol, 1);
	up_write(&vol->lcnbmp_lock);
	if (status.mp_rebuilt) {
		if (ntfs_mapping_pairs_build(vol, (u8 *)a + le16_to_cpu(
				a->data.non_resident.mapping_pairs_offset),
				old_alen - le16_to_cpu(
				a->data.non_resident.mapping_pairs_offset),
				rl2, ll, -1, NULL, NULL, NULL)) {
			ntfs_error(vol->sb, "Failed to restore mapping pairs array.%s", es);
			NVolSetErrors(vol);
		}
		if (ntfs_attr_record_resize(ctx->mrec, a, old_alen)) {
			ntfs_error(vol->sb, "Failed to restore attribute record.%s", es);
			NVolSetErrors(vol);
		}
		mark_mft_record_dirty(ctx->ntfs_ino);
	} else if (status.mp_extended && ntfs_attr_update_mapping_pairs(mftbmp_ni, 0)) {
		ntfs_error(vol->sb, "Failed to restore mapping pairs.%s", es);
		NVolSetErrors(vol);
	}
	if (ctx)
		ntfs_attr_put_search_ctx(ctx);
	if (!IS_ERR(mrec))
		unmap_mft_record(mft_ni);
	up_write(&mftbmp_ni->runlist.lock);
	return ret;
}

/*
 * ntfs_mft_bitmap_extend_initialized_nolock - extend mftbmp initialized data
 * @vol:	volume on which to extend the mft bitmap attribute
 *
 * Extend the initialized portion of the mft bitmap attribute on the ntfs
 * volume @vol by 8 bytes.
 *
 * Note:  Only changes initialized_size and data_size, i.e. requires that
 * allocated_size is big enough to fit the new initialized_size.
 *
 * Return 0 on success and -error on error.
 *
 * Locking: Caller must hold vol->mftbmp_lock for writing.
 */
static int ntfs_mft_bitmap_extend_initialized_nolock(struct ntfs_volume *vol)
{
	s64 old_data_size, old_initialized_size;
	unsigned long flags;
	struct inode *mftbmp_vi;
	struct ntfs_inode *mft_ni, *mftbmp_ni;
	struct ntfs_attr_search_ctx *ctx;
	struct mft_record *mrec;
	struct attr_record *a;
	int ret;

	ntfs_debug("Extending mft bitmap initialized (and data) size.");
	mft_ni = NTFS_I(vol->mft_ino);
	mftbmp_vi = vol->mftbmp_ino;
	mftbmp_ni = NTFS_I(mftbmp_vi);
	/* Get the attribute record. */
	mrec = map_mft_record(mft_ni);
	if (IS_ERR(mrec)) {
		ntfs_error(vol->sb, "Failed to map mft record.");
		return PTR_ERR(mrec);
	}
	ctx = ntfs_attr_get_search_ctx(mft_ni, mrec);
	if (unlikely(!ctx)) {
		ntfs_error(vol->sb, "Failed to get search context.");
		ret = -ENOMEM;
		goto unm_err_out;
	}
	ret = ntfs_attr_lookup(mftbmp_ni->type, mftbmp_ni->name,
			mftbmp_ni->name_len, CASE_SENSITIVE, 0, NULL, 0, ctx);
	if (unlikely(ret)) {
		ntfs_error(vol->sb,
			"Failed to find first attribute extent of mft bitmap attribute.");
		if (ret == -ENOENT)
			ret = -EIO;
		goto put_err_out;
	}
	a = ctx->attr;
	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
	old_data_size = i_size_read(mftbmp_vi);
	old_initialized_size = mftbmp_ni->initialized_size;
	/*
	 * We can simply update the initialized_size before filling the space
	 * with zeroes because the caller is holding the mft bitmap lock for
	 * writing which ensures that no one else is trying to access the data.
	 */
	mftbmp_ni->initialized_size += 8;
	a->data.non_resident.initialized_size =
			cpu_to_le64(mftbmp_ni->initialized_size);
	if (mftbmp_ni->initialized_size > old_data_size) {
		i_size_write(mftbmp_vi, mftbmp_ni->initialized_size);
		a->data.non_resident.data_size =
				cpu_to_le64(mftbmp_ni->initialized_size);
	}
	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	/* Ensure the changes make it to disk. */
	mark_mft_record_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(mft_ni);
	/* Initialize the mft bitmap attribute value with zeroes. */
	ret = ntfs_attr_set(mftbmp_ni, old_initialized_size, 8, 0);
	if (likely(!ret)) {
		ntfs_debug("Done.  (Wrote eight initialized bytes to mft bitmap.");
		ntfs_inc_free_mft_records(vol, 8 * 8);
		return 0;
	}
	ntfs_error(vol->sb, "Failed to write to mft bitmap.");
	/* Try to recover from the error. */
	mrec = map_mft_record(mft_ni);
	if (IS_ERR(mrec)) {
		ntfs_error(vol->sb, "Failed to map mft record.%s", es);
		NVolSetErrors(vol);
		return ret;
	}
	ctx = ntfs_attr_get_search_ctx(mft_ni, mrec);
	if (unlikely(!ctx)) {
		ntfs_error(vol->sb, "Failed to get search context.%s", es);
		NVolSetErrors(vol);
		goto unm_err_out;
	}
	if (ntfs_attr_lookup(mftbmp_ni->type, mftbmp_ni->name,
			mftbmp_ni->name_len, CASE_SENSITIVE, 0, NULL, 0, ctx)) {
		ntfs_error(vol->sb,
			"Failed to find first attribute extent of mft bitmap attribute.%s", es);
		NVolSetErrors(vol);
put_err_out:
		ntfs_attr_put_search_ctx(ctx);
unm_err_out:
		unmap_mft_record(mft_ni);
		goto err_out;
	}
	a = ctx->attr;
	write_lock_irqsave(&mftbmp_ni->size_lock, flags);
	mftbmp_ni->initialized_size = old_initialized_size;
	a->data.non_resident.initialized_size =
			cpu_to_le64(old_initialized_size);
	if (i_size_read(mftbmp_vi) != old_data_size) {
		i_size_write(mftbmp_vi, old_data_size);
		a->data.non_resident.data_size = cpu_to_le64(old_data_size);
	}
	write_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	mark_mft_record_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(mft_ni);
#ifdef DEBUG
	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
	ntfs_debug("Restored status of mftbmp: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
			mftbmp_ni->allocated_size, i_size_read(mftbmp_vi),
			mftbmp_ni->initialized_size);
	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
#endif /* DEBUG */
err_out:
	return ret;
}

/*
 * ntfs_mft_data_extend_allocation_nolock - extend mft data attribute
 * @vol:	volume on which to extend the mft data attribute
 *
 * Extend the mft data attribute on the ntfs volume @vol by 16 mft records
 * worth of clusters or if not enough space for this by one mft record worth
 * of clusters.
 *
 * Note:  Only changes allocated_size, i.e. does not touch initialized_size or
 * data_size.
 *
 * Return 0 on success and -errno on error.
 *
 * Locking: - Caller must hold vol->mftbmp_lock for writing.
 *	    - This function takes NTFS_I(vol->mft_ino)->runlist.lock for
 *	      writing and releases it before returning.
 *	    - This function calls functions which take vol->lcnbmp_lock for
 *	      writing and release it before returning.
 */
static int ntfs_mft_data_extend_allocation_nolock(struct ntfs_volume *vol)
{
	s64 lcn;
	s64 old_last_vcn;
	s64 min_nr, nr, ll;
	unsigned long flags;
	struct ntfs_inode *mft_ni;
	struct runlist_element *rl, *rl2;
	struct ntfs_attr_search_ctx *ctx = NULL;
	struct mft_record *mrec;
	struct attr_record *a = NULL;
	int ret, mp_size;
	u32 old_alen = 0;
	bool mp_rebuilt = false, mp_extended = false;
	size_t new_rl_count;

	ntfs_debug("Extending mft data allocation.");
	mft_ni = NTFS_I(vol->mft_ino);
	/*
	 * Determine the preferred allocation location, i.e. the last lcn of
	 * the mft data attribute.  The allocated size of the mft data
	 * attribute cannot be zero so we are ok to do this.
	 */
	down_write(&mft_ni->runlist.lock);
	read_lock_irqsave(&mft_ni->size_lock, flags);
	ll = mft_ni->allocated_size;
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
	rl = ntfs_attr_find_vcn_nolock(mft_ni,
			NTFS_B_TO_CLU(vol, ll - 1), NULL);
	if (IS_ERR(rl) || unlikely(!rl->length || rl->lcn < 0)) {
		up_write(&mft_ni->runlist.lock);
		ntfs_error(vol->sb,
			"Failed to determine last allocated cluster of mft data attribute.");
		if (!IS_ERR(rl))
			ret = -EIO;
		else
			ret = PTR_ERR(rl);
		return ret;
	}
	lcn = rl->lcn + rl->length;
	ntfs_debug("Last lcn of mft data attribute is 0x%llx.", lcn);
	/* Minimum allocation is one mft record worth of clusters. */
	min_nr = NTFS_B_TO_CLU(vol, vol->mft_record_size);
	if (!min_nr)
		min_nr = 1;
	/* Want to allocate 16 mft records worth of clusters. */
	nr = vol->mft_record_size << 4 >> vol->cluster_size_bits;
	if (!nr)
		nr = min_nr;
	/* Ensure we do not go above 2^32-1 mft records. */
	read_lock_irqsave(&mft_ni->size_lock, flags);
	ll = mft_ni->allocated_size;
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
	if (unlikely((ll + NTFS_CLU_TO_B(vol, nr)) >>
			vol->mft_record_size_bits >= (1ll << 32))) {
		nr = min_nr;
		if (unlikely((ll + NTFS_CLU_TO_B(vol, nr)) >>
				vol->mft_record_size_bits >= (1ll << 32))) {
			ntfs_warning(vol->sb,
				"Cannot allocate mft record because the maximum number of inodes (2^32) has already been reached.");
			up_write(&mft_ni->runlist.lock);
			return -ENOSPC;
		}
	}
	ntfs_debug("Trying mft data allocation with %s cluster count %lli.",
			nr > min_nr ? "default" : "minimal", (long long)nr);
	old_last_vcn = rl[1].vcn;
	/*
	 * We can release the mft_ni runlist lock, Because this function is
	 * the only one that expends $MFT data attribute and is called with
	 * mft_ni->mrec_lock.
	 * This is required for the lock order, vol->lcnbmp_lock =>
	 * mft_ni->runlist.lock.
	 */
	up_write(&mft_ni->runlist.lock);

	do {
		rl2 = ntfs_cluster_alloc(vol, old_last_vcn, nr, lcn, MFT_ZONE,
				true, false, false);
		if (!IS_ERR(rl2))
			break;
		if (PTR_ERR(rl2) != -ENOSPC || nr == min_nr) {
			ntfs_error(vol->sb,
				"Failed to allocate the minimal number of clusters (%lli) for the mft data attribute.",
				nr);
			return PTR_ERR(rl2);
		}
		/*
		 * There is not enough space to do the allocation, but there
		 * might be enough space to do a minimal allocation so try that
		 * before failing.
		 */
		nr = min_nr;
		ntfs_debug("Retrying mft data allocation with minimal cluster count %lli.", nr);
	} while (1);

	down_write(&mft_ni->runlist.lock);
	rl = ntfs_runlists_merge(&mft_ni->runlist, rl2, 0, &new_rl_count);
	if (IS_ERR(rl)) {
		up_write(&mft_ni->runlist.lock);
		ntfs_error(vol->sb, "Failed to merge runlists for mft data attribute.");
		if (ntfs_cluster_free_from_rl(vol, rl2)) {
			ntfs_error(vol->sb,
				"Failed to deallocate clusters from the mft data attribute.%s", es);
			NVolSetErrors(vol);
		}
		kvfree(rl2);
		return PTR_ERR(rl);
	}
	mft_ni->runlist.rl = rl;
	mft_ni->runlist.count = new_rl_count;
	ntfs_debug("Allocated %lli clusters.", (long long)nr);
	/* Find the last run in the new runlist. */
	for (; rl[1].length; rl++)
		;
	up_write(&mft_ni->runlist.lock);

	/* Update the attribute record as well. */
	mrec = map_mft_record(mft_ni);
	if (IS_ERR(mrec)) {
		ntfs_error(vol->sb, "Failed to map mft record.");
		ret = PTR_ERR(mrec);
		down_write(&mft_ni->runlist.lock);
		goto undo_alloc;
	}
	ctx = ntfs_attr_get_search_ctx(mft_ni, mrec);
	if (unlikely(!ctx)) {
		ntfs_error(vol->sb, "Failed to get search context.");
		ret = -ENOMEM;
		goto undo_alloc;
	}
	ret = ntfs_attr_lookup(mft_ni->type, mft_ni->name, mft_ni->name_len,
			CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx);
	if (unlikely(ret)) {
		ntfs_error(vol->sb, "Failed to find last attribute extent of mft data attribute.");
		if (ret == -ENOENT)
			ret = -EIO;
		goto undo_alloc;
	}
	a = ctx->attr;
	ll = le64_to_cpu(a->data.non_resident.lowest_vcn);

	down_write(&mft_ni->runlist.lock);
	/* Search back for the previous last allocated cluster of mft bitmap. */
	for (rl2 = rl; rl2 > mft_ni->runlist.rl; rl2--) {
		if (ll >= rl2->vcn)
			break;
	}
	WARN_ON(ll < rl2->vcn);
	WARN_ON(ll >= rl2->vcn + rl2->length);
	/* Get the size for the new mapping pairs array for this extent. */
	mp_size = ntfs_get_size_for_mapping_pairs(vol, rl2, ll, -1, -1);
	if (unlikely(mp_size <= 0)) {
		ntfs_error(vol->sb,
			"Get size for mapping pairs failed for mft data attribute extent.");
		ret = mp_size;
		if (!ret)
			ret = -EIO;
		up_write(&mft_ni->runlist.lock);
		goto undo_alloc;
	}
	up_write(&mft_ni->runlist.lock);

	/* Expand the attribute record if necessary. */
	old_alen = le32_to_cpu(a->length);
	ret = ntfs_attr_record_resize(ctx->mrec, a, mp_size +
			le16_to_cpu(a->data.non_resident.mapping_pairs_offset));
	if (unlikely(ret)) {
		ret = ntfs_mft_attr_extend(mft_ni);
		if (!ret)
			goto extended_ok;
		if (ret != -EAGAIN)
			mp_extended = true;
		goto undo_alloc;
	}
	mp_rebuilt = true;
	/* Generate the mapping pairs array directly into the attr record. */
	ret = ntfs_mapping_pairs_build(vol, (u8 *)a +
			le16_to_cpu(a->data.non_resident.mapping_pairs_offset),
			mp_size, rl2, ll, -1, NULL, NULL, NULL);
	if (unlikely(ret)) {
		ntfs_error(vol->sb, "Failed to build mapping pairs array of mft data attribute.");
		goto undo_alloc;
	}
	/* Update the highest_vcn. */
	a->data.non_resident.highest_vcn = cpu_to_le64(rl[1].vcn - 1);
	/*
	 * We now have extended the mft data allocated_size by nr clusters.
	 * Reflect this in the struct ntfs_inode structure and the attribute record.
	 * @rl is the last (non-terminator) runlist element of mft data
	 * attribute.
	 */
	if (a->data.non_resident.lowest_vcn) {
		/*
		 * We are not in the first attribute extent, switch to it, but
		 * first ensure the changes will make it to disk later.
		 */
		mark_mft_record_dirty(ctx->ntfs_ino);
extended_ok:
		ntfs_attr_reinit_search_ctx(ctx);
		ret = ntfs_attr_lookup(mft_ni->type, mft_ni->name,
				mft_ni->name_len, CASE_SENSITIVE, 0, NULL, 0,
				ctx);
		if (unlikely(ret)) {
			ntfs_error(vol->sb,
				"Failed to find first attribute extent of mft data attribute.");
			goto restore_undo_alloc;
		}
		a = ctx->attr;
	}

	write_lock_irqsave(&mft_ni->size_lock, flags);
	mft_ni->allocated_size += NTFS_CLU_TO_B(vol, nr);
	a->data.non_resident.allocated_size =
			cpu_to_le64(mft_ni->allocated_size);
	write_unlock_irqrestore(&mft_ni->size_lock, flags);
	/* Ensure the changes make it to disk. */
	mark_mft_record_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(mft_ni);
	ntfs_debug("Done.");
	return 0;
restore_undo_alloc:
	ntfs_attr_reinit_search_ctx(ctx);
	if (ntfs_attr_lookup(mft_ni->type, mft_ni->name, mft_ni->name_len,
			CASE_SENSITIVE, rl[1].vcn, NULL, 0, ctx)) {
		ntfs_error(vol->sb,
			"Failed to find last attribute extent of mft data attribute.%s", es);
		write_lock_irqsave(&mft_ni->size_lock, flags);
		mft_ni->allocated_size += NTFS_CLU_TO_B(vol, nr);
		write_unlock_irqrestore(&mft_ni->size_lock, flags);
		ntfs_attr_put_search_ctx(ctx);
		unmap_mft_record(mft_ni);
		up_write(&mft_ni->runlist.lock);
		/*
		 * The only thing that is now wrong is ->allocated_size of the
		 * base attribute extent which chkdsk should be able to fix.
		 */
		NVolSetErrors(vol);
		return ret;
	}
	ctx->attr->data.non_resident.highest_vcn =
			cpu_to_le64(old_last_vcn - 1);
undo_alloc:
	if (ntfs_cluster_free(mft_ni, old_last_vcn, -1, ctx) < 0) {
		ntfs_error(vol->sb, "Failed to free clusters from mft data attribute.%s", es);
		NVolSetErrors(vol);
	}

	if (ntfs_rl_truncate_nolock(vol, &mft_ni->runlist, old_last_vcn)) {
		ntfs_error(vol->sb, "Failed to truncate mft data attribute runlist.%s", es);
		NVolSetErrors(vol);
	}
	if (mp_extended && ntfs_attr_update_mapping_pairs(mft_ni, 0)) {
		ntfs_error(vol->sb, "Failed to restore mapping pairs.%s",
			   es);
		NVolSetErrors(vol);
	}
	if (ctx) {
		a = ctx->attr;
		if (mp_rebuilt && !IS_ERR(ctx->mrec)) {
			if (ntfs_mapping_pairs_build(vol, (u8 *)a + le16_to_cpu(
				a->data.non_resident.mapping_pairs_offset),
				old_alen - le16_to_cpu(
					a->data.non_resident.mapping_pairs_offset),
				rl2, ll, -1, NULL, NULL, NULL)) {
				ntfs_error(vol->sb, "Failed to restore mapping pairs array.%s", es);
				NVolSetErrors(vol);
			}
			if (ntfs_attr_record_resize(ctx->mrec, a, old_alen)) {
				ntfs_error(vol->sb, "Failed to restore attribute record.%s", es);
				NVolSetErrors(vol);
			}
			mark_mft_record_dirty(ctx->ntfs_ino);
		} else if (IS_ERR(ctx->mrec)) {
			ntfs_error(vol->sb, "Failed to restore attribute search context.%s", es);
			NVolSetErrors(vol);
		}
		ntfs_attr_put_search_ctx(ctx);
	}
	if (!IS_ERR(mrec))
		unmap_mft_record(mft_ni);
	return ret;
}

/*
 * ntfs_mft_record_layout - layout an mft record into a memory buffer
 * @vol:	volume to which the mft record will belong
 * @mft_no:	mft reference specifying the mft record number
 * @m:		destination buffer of size >= @vol->mft_record_size bytes
 *
 * Layout an empty, unused mft record with the mft record number @mft_no into
 * the buffer @m.  The volume @vol is needed because the mft record structure
 * was modified in NTFS 3.1 so we need to know which volume version this mft
 * record will be used on.
 *
 * Return 0 on success and -errno on error.
 */
static int ntfs_mft_record_layout(const struct ntfs_volume *vol, const s64 mft_no,
		struct mft_record *m)
{
	struct attr_record *a;

	ntfs_debug("Entering for mft record 0x%llx.", (long long)mft_no);
	if (mft_no >= (1ll << 32)) {
		ntfs_error(vol->sb, "Mft record number 0x%llx exceeds maximum of 2^32.",
				(long long)mft_no);
		return -ERANGE;
	}
	/* Start by clearing the whole mft record to gives us a clean slate. */
	memset(m, 0, vol->mft_record_size);
	/* Aligned to 2-byte boundary. */
	if (vol->major_ver < 3 || (vol->major_ver == 3 && !vol->minor_ver))
		m->usa_ofs = cpu_to_le16((sizeof(struct mft_record_old) + 1) & ~1);
	else {
		m->usa_ofs = cpu_to_le16((sizeof(struct mft_record) + 1) & ~1);
		/*
		 * Set the NTFS 3.1+ specific fields while we know that the
		 * volume version is 3.1+.
		 */
		m->reserved = 0;
		m->mft_record_number = cpu_to_le32((u32)mft_no);
	}
	m->magic = magic_FILE;
	if (vol->mft_record_size >= NTFS_BLOCK_SIZE)
		m->usa_count = cpu_to_le16(vol->mft_record_size /
				NTFS_BLOCK_SIZE + 1);
	else {
		m->usa_count = cpu_to_le16(1);
		ntfs_warning(vol->sb,
			"Sector size is bigger than mft record size.  Setting usa_count to 1.  If chkdsk reports this as corruption");
	}
	/* Set the update sequence number to 1. */
	*(__le16 *)((u8 *)m + le16_to_cpu(m->usa_ofs)) = cpu_to_le16(1);
	m->lsn = 0;
	m->sequence_number = cpu_to_le16(1);
	m->link_count = 0;
	/*
	 * Place the attributes straight after the update sequence array,
	 * aligned to 8-byte boundary.
	 */
	m->attrs_offset = cpu_to_le16((le16_to_cpu(m->usa_ofs) +
			(le16_to_cpu(m->usa_count) << 1) + 7) & ~7);
	m->flags = 0;
	/*
	 * Using attrs_offset plus eight bytes (for the termination attribute).
	 * attrs_offset is already aligned to 8-byte boundary, so no need to
	 * align again.
	 */
	m->bytes_in_use = cpu_to_le32(le16_to_cpu(m->attrs_offset) + 8);
	m->bytes_allocated = cpu_to_le32(vol->mft_record_size);
	m->base_mft_record = 0;
	m->next_attr_instance = 0;
	/* Add the termination attribute. */
	a = (struct attr_record *)((u8 *)m + le16_to_cpu(m->attrs_offset));
	a->type = AT_END;
	a->length = 0;
	ntfs_debug("Done.");
	return 0;
}

/*
 * ntfs_mft_record_format - format an mft record on an ntfs volume
 * @vol:	volume on which to format the mft record
 * @mft_no:	mft record number to format
 *
 * Format the mft record @mft_no in $MFT/$DATA, i.e. lay out an empty, unused
 * mft record into the appropriate place of the mft data attribute.  This is
 * used when extending the mft data attribute.
 *
 * Return 0 on success and -errno on error.
 */
static int ntfs_mft_record_format(const struct ntfs_volume *vol, const s64 mft_no)
{
	loff_t i_size;
	struct inode *mft_vi = vol->mft_ino;
	struct folio *folio;
	struct mft_record *m;
	pgoff_t index, end_index;
	unsigned int ofs;
	int err;

	ntfs_debug("Entering for mft record 0x%llx.", (long long)mft_no);
	/*
	 * The index into the page cache and the offset within the page cache
	 * page of the wanted mft record.
	 */
	index = NTFS_MFT_NR_TO_PIDX(vol, mft_no);
	ofs = NTFS_MFT_NR_TO_POFS(vol, mft_no);
	/* The maximum valid index into the page cache for $MFT's data. */
	i_size = i_size_read(mft_vi);
	end_index = i_size >> PAGE_SHIFT;
	if (unlikely(index >= end_index)) {
		if (unlikely(index > end_index ||
			     ofs + vol->mft_record_size > (i_size & ~PAGE_MASK))) {
			ntfs_error(vol->sb, "Tried to format non-existing mft record 0x%llx.",
					(long long)mft_no);
			return -ENOENT;
		}
	}

	/* Read, map, and pin the folio containing the mft record. */
	folio = read_mapping_folio(mft_vi->i_mapping, index, NULL);
	if (IS_ERR(folio)) {
		ntfs_error(vol->sb, "Failed to map page containing mft record to format 0x%llx.",
				(long long)mft_no);
		return PTR_ERR(folio);
	}
	folio_lock(folio);
	folio_clear_uptodate(folio);
	m = (struct mft_record *)((u8 *)kmap_local_folio(folio, 0) + ofs);
	err = ntfs_mft_record_layout(vol, mft_no, m);
	if (unlikely(err)) {
		ntfs_error(vol->sb, "Failed to layout mft record 0x%llx.",
				(long long)mft_no);
		folio_mark_uptodate(folio);
		folio_unlock(folio);
		kunmap_local(m);
		folio_put(folio);
		return err;
	}
	pre_write_mst_fixup((struct ntfs_record *)m, vol->mft_record_size);
	folio_mark_uptodate(folio);
	/*
	 * Make sure the mft record is written out to disk.  We could use
	 * ilookup5() to check if an inode is in icache and so on but this is
	 * unnecessary as ntfs_writepage() will write the dirty record anyway.
	 */
	ntfs_mft_mark_dirty(folio);
	folio_unlock(folio);
	kunmap_local(m);
	folio_put(folio);
	ntfs_debug("Done.");
	return 0;
}

/*
 * ntfs_mft_record_alloc - allocate an mft record on an ntfs volume
 * @vol:	[IN]  volume on which to allocate the mft record
 * @mode:	[IN]  mode if want a file or directory, i.e. base inode or 0
 * @ni:		[OUT] on success, set to the allocated ntfs inode
 * @base_ni:	[IN]  open base inode if allocating an extent mft record or NULL
 * @ni_mrec:	[OUT] on successful return this is the mapped mft record
 *
 * Allocate an mft record in $MFT/$DATA of an open ntfs volume @vol.
 *
 * If @base_ni is NULL make the mft record a base mft record, i.e. a file or
 * direvctory inode, and allocate it at the default allocator position.  In
 * this case @mode is the file mode as given to us by the caller.  We in
 * particular use @mode to distinguish whether a file or a directory is being
 * created (S_IFDIR(mode) and S_IFREG(mode), respectively).
 *
 * If @base_ni is not NULL make the allocated mft record an extent record,
 * allocate it starting at the mft record after the base mft record and attach
 * the allocated and opened ntfs inode to the base inode @base_ni.  In this
 * case @mode must be 0 as it is meaningless for extent inodes.
 *
 * You need to check the return value with IS_ERR().  If false, the function
 * was successful and the return value is the now opened ntfs inode of the
 * allocated mft record.  *@mrec is then set to the allocated, mapped, pinned,
 * and locked mft record.  If IS_ERR() is true, the function failed and the
 * error code is obtained from PTR_ERR(return value).  *@mrec is undefined in
 * this case.
 *
 * Allocation strategy:
 *
 * To find a free mft record, we scan the mft bitmap for a zero bit.  To
 * optimize this we start scanning at the place specified by @base_ni or if
 * @base_ni is NULL we start where we last stopped and we perform wrap around
 * when we reach the end.  Note, we do not try to allocate mft records below
 * number 64 because numbers 0 to 15 are the defined system files anyway and 16
 * to 64 are special in that they are used for storing extension mft records
 * for the $DATA attribute of $MFT.  This is required to avoid the possibility
 * of creating a runlist with a circular dependency which once written to disk
 * can never be read in again.  Windows will only use records 16 to 24 for
 * normal files if the volume is completely out of space.  We never use them
 * which means that when the volume is really out of space we cannot create any
 * more files while Windows can still create up to 8 small files.  We can start
 * doing this at some later time, it does not matter much for now.
 *
 * When scanning the mft bitmap, we only search up to the last allocated mft
 * record.  If there are no free records left in the range 64 to number of
 * allocated mft records, then we extend the $MFT/$DATA attribute in order to
 * create free mft records.  We extend the allocated size of $MFT/$DATA by 16
 * records at a time or one cluster, if cluster size is above 16kiB.  If there
 * is not sufficient space to do this, we try to extend by a single mft record
 * or one cluster, if cluster size is above the mft record size.
 *
 * No matter how many mft records we allocate, we initialize only the first
 * allocated mft record, incrementing mft data size and initialized size
 * accordingly, open an struct ntfs_inode for it and return it to the caller, unless
 * there are less than 64 mft records, in which case we allocate and initialize
 * mft records until we reach record 64 which we consider as the first free mft
 * record for use by normal files.
 *
 * If during any stage we overflow the initialized data in the mft bitmap, we
 * extend the initialized size (and data size) by 8 bytes, allocating another
 * cluster if required.  The bitmap data size has to be at least equal to the
 * number of mft records in the mft, but it can be bigger, in which case the
 * superfluous bits are padded with zeroes.
 *
 * Thus, when we return successfully (IS_ERR() is false), we will have:
 *	- initialized / extended the mft bitmap if necessary,
 *	- initialized / extended the mft data if necessary,
 *	- set the bit corresponding to the mft record being allocated in the
 *	  mft bitmap,
 *	- opened an struct ntfs_inode for the allocated mft record, and we will have
 *	- returned the struct ntfs_inode as well as the allocated mapped, pinned, and
 *	  locked mft record.
 *
 * On error, the volume will be left in a consistent state and no record will
 * be allocated.  If rolling back a partial operation fails, we may leave some
 * inconsistent metadata in which case we set NVolErrors() so the volume is
 * left dirty when unmounted.
 *
 * Note, this function cannot make use of most of the normal functions, like
 * for example for attribute resizing, etc, because when the run list overflows
 * the base mft record and an attribute list is used, it is very important that
 * the extension mft records used to store the $DATA attribute of $MFT can be
 * reached without having to read the information contained inside them, as
 * this would make it impossible to find them in the first place after the
 * volume is unmounted.  $MFT/$BITMAP probably does not need to follow this
 * rule because the bitmap is not essential for finding the mft records, but on
 * the other hand, handling the bitmap in this special way would make life
 * easier because otherwise there might be circular invocations of functions
 * when reading the bitmap.
 */
int ntfs_mft_record_alloc(struct ntfs_volume *vol, const int mode,
			  struct ntfs_inode **ni, struct ntfs_inode *base_ni,
			  struct mft_record **ni_mrec)
{
	s64 ll, bit, old_data_initialized, old_data_size;
	unsigned long flags;
	struct folio *folio;
	struct ntfs_inode *mft_ni, *mftbmp_ni;
	struct ntfs_attr_search_ctx *ctx;
	struct mft_record *m = NULL;
	struct attr_record *a;
	pgoff_t index;
	unsigned int ofs;
	int err;
	__le16 seq_no, usn;
	bool record_formatted = false;
	unsigned int memalloc_flags;

	if (base_ni && *ni)
		return -EINVAL;

	/* @mode and @base_ni are mutually exclusive. */
	if (mode && base_ni)
		return -EINVAL;

	if (base_ni)
		ntfs_debug("Entering (allocating an extent mft record for base mft record 0x%llx).",
				(long long)base_ni->mft_no);
	else
		ntfs_debug("Entering (allocating a base mft record).");

	memalloc_flags = memalloc_nofs_save();

	mft_ni = NTFS_I(vol->mft_ino);
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		mutex_lock(&mft_ni->mrec_lock);
	mftbmp_ni = NTFS_I(vol->mftbmp_ino);
search_free_rec:
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		down_write(&vol->mftbmp_lock);
	bit = ntfs_mft_bitmap_find_and_alloc_free_rec_nolock(vol, base_ni);
	if (bit >= 0) {
		ntfs_debug("Found and allocated free record (#1), bit 0x%llx.",
				(long long)bit);
		goto have_alloc_rec;
	}
	if (bit != -ENOSPC) {
		if (!base_ni || base_ni->mft_no != FILE_MFT) {
			up_write(&vol->mftbmp_lock);
			mutex_unlock(&mft_ni->mrec_lock);
		}
		memalloc_nofs_restore(memalloc_flags);
		return bit;
	}

	if (base_ni && base_ni->mft_no == FILE_MFT) {
		memalloc_nofs_restore(memalloc_flags);
		return bit;
	}

	/*
	 * No free mft records left.  If the mft bitmap already covers more
	 * than the currently used mft records, the next records are all free,
	 * so we can simply allocate the first unused mft record.
	 * Note: We also have to make sure that the mft bitmap at least covers
	 * the first 24 mft records as they are special and whilst they may not
	 * be in use, we do not allocate from them.
	 */
	read_lock_irqsave(&mft_ni->size_lock, flags);
	ll = mft_ni->initialized_size >> vol->mft_record_size_bits;
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
	old_data_initialized = mftbmp_ni->initialized_size;
	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	if (old_data_initialized << 3 > ll &&
	    old_data_initialized > RESERVED_MFT_RECORDS / 8) {
		bit = ll;
		if (bit < RESERVED_MFT_RECORDS)
			bit = RESERVED_MFT_RECORDS;
		if (unlikely(bit >= (1ll << 32)))
			goto max_err_out;
		ntfs_debug("Found free record (#2), bit 0x%llx.",
				(long long)bit);
		goto found_free_rec;
	}
	/*
	 * The mft bitmap needs to be expanded until it covers the first unused
	 * mft record that we can allocate.
	 * Note: The smallest mft record we allocate is mft record 24.
	 */
	bit = old_data_initialized << 3;
	if (unlikely(bit >= (1ll << 32)))
		goto max_err_out;
	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
	old_data_size = mftbmp_ni->allocated_size;
	ntfs_debug("Status of mftbmp before extension: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
			old_data_size, i_size_read(vol->mftbmp_ino),
			old_data_initialized);
	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
	if (old_data_initialized + 8 > old_data_size) {
		/* Need to extend bitmap by one more cluster. */
		ntfs_debug("mftbmp: initialized_size + 8 > allocated_size.");
		err = ntfs_mft_bitmap_extend_allocation_nolock(vol);
		if (err == -EAGAIN)
			err = ntfs_mft_bitmap_extend_allocation_nolock(vol);

		if (unlikely(err)) {
			if (!base_ni || base_ni->mft_no != FILE_MFT)
				up_write(&vol->mftbmp_lock);
			goto err_out;
		}
#ifdef DEBUG
		read_lock_irqsave(&mftbmp_ni->size_lock, flags);
		ntfs_debug("Status of mftbmp after allocation extension: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
				mftbmp_ni->allocated_size,
				i_size_read(vol->mftbmp_ino),
				mftbmp_ni->initialized_size);
		read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
#endif /* DEBUG */
	}
	/*
	 * We now have sufficient allocated space, extend the initialized_size
	 * as well as the data_size if necessary and fill the new space with
	 * zeroes.
	 */
	err = ntfs_mft_bitmap_extend_initialized_nolock(vol);
	if (unlikely(err)) {
		if (!base_ni || base_ni->mft_no != FILE_MFT)
			up_write(&vol->mftbmp_lock);
		goto err_out;
	}
#ifdef DEBUG
	read_lock_irqsave(&mftbmp_ni->size_lock, flags);
	ntfs_debug("Status of mftbmp after initialized extension: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
			mftbmp_ni->allocated_size,
			i_size_read(vol->mftbmp_ino),
			mftbmp_ni->initialized_size);
	read_unlock_irqrestore(&mftbmp_ni->size_lock, flags);
#endif /* DEBUG */
	ntfs_debug("Found free record (#3), bit 0x%llx.", (long long)bit);
found_free_rec:
	/* @bit is the found free mft record, allocate it in the mft bitmap. */
	ntfs_debug("At found_free_rec.");
	err = ntfs_bitmap_set_bit(vol->mftbmp_ino, bit);
	if (unlikely(err)) {
		ntfs_error(vol->sb, "Failed to allocate bit in mft bitmap.");
		if (!base_ni || base_ni->mft_no != FILE_MFT)
			up_write(&vol->mftbmp_lock);
		goto err_out;
	}
	ntfs_debug("Set bit 0x%llx in mft bitmap.", (long long)bit);
have_alloc_rec:
	/*
	 * The mft bitmap is now uptodate.  Deal with mft data attribute now.
	 * Note, we keep hold of the mft bitmap lock for writing until all
	 * modifications to the mft data attribute are complete, too, as they
	 * will impact decisions for mft bitmap and mft record allocation done
	 * by a parallel allocation and if the lock is not maintained a
	 * parallel allocation could allocate the same mft record as this one.
	 */
	ll = (bit + 1) << vol->mft_record_size_bits;
	read_lock_irqsave(&mft_ni->size_lock, flags);
	old_data_initialized = mft_ni->initialized_size;
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
	if (ll <= old_data_initialized) {
		ntfs_debug("Allocated mft record already initialized.");
		goto mft_rec_already_initialized;
	}
	ntfs_debug("Initializing allocated mft record.");
	/*
	 * The mft record is outside the initialized data.  Extend the mft data
	 * attribute until it covers the allocated record.  The loop is only
	 * actually traversed more than once when a freshly formatted volume is
	 * first written to so it optimizes away nicely in the common case.
	 */
	if (!base_ni || base_ni->mft_no != FILE_MFT) {
		read_lock_irqsave(&mft_ni->size_lock, flags);
		ntfs_debug("Status of mft data before extension: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
				mft_ni->allocated_size, i_size_read(vol->mft_ino),
				mft_ni->initialized_size);
		while (ll > mft_ni->allocated_size) {
			read_unlock_irqrestore(&mft_ni->size_lock, flags);
			err = ntfs_mft_data_extend_allocation_nolock(vol);
			if (err == -EAGAIN)
				err = ntfs_mft_data_extend_allocation_nolock(vol);

			if (unlikely(err)) {
				ntfs_error(vol->sb, "Failed to extend mft data allocation.");
				goto undo_mftbmp_alloc_nolock;
			}
			read_lock_irqsave(&mft_ni->size_lock, flags);
			ntfs_debug("Status of mft data after allocation extension: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
					mft_ni->allocated_size, i_size_read(vol->mft_ino),
					mft_ni->initialized_size);
		}
		read_unlock_irqrestore(&mft_ni->size_lock, flags);
	} else if (ll > mft_ni->allocated_size) {
		err = -ENOSPC;
		goto undo_mftbmp_alloc_nolock;
	}
	/*
	 * Extend mft data initialized size (and data size of course) to reach
	 * the allocated mft record, formatting the mft records allong the way.
	 * Note: We only modify the struct ntfs_inode structure as that is all that is
	 * needed by ntfs_mft_record_format().  We will update the attribute
	 * record itself in one fell swoop later on.
	 */
	write_lock_irqsave(&mft_ni->size_lock, flags);
	old_data_initialized = mft_ni->initialized_size;
	old_data_size = vol->mft_ino->i_size;
	while (ll > mft_ni->initialized_size) {
		s64 new_initialized_size, mft_no;

		new_initialized_size = mft_ni->initialized_size +
				vol->mft_record_size;
		mft_no = mft_ni->initialized_size >> vol->mft_record_size_bits;
		if (new_initialized_size > i_size_read(vol->mft_ino))
			i_size_write(vol->mft_ino, new_initialized_size);
		write_unlock_irqrestore(&mft_ni->size_lock, flags);
		ntfs_debug("Initializing mft record 0x%llx.",
				(long long)mft_no);
		err = ntfs_mft_record_format(vol, mft_no);
		if (unlikely(err)) {
			ntfs_error(vol->sb, "Failed to format mft record.");
			goto undo_data_init;
		}
		write_lock_irqsave(&mft_ni->size_lock, flags);
		mft_ni->initialized_size = new_initialized_size;
	}
	write_unlock_irqrestore(&mft_ni->size_lock, flags);
	record_formatted = true;
	/* Update the mft data attribute record to reflect the new sizes. */
	m = map_mft_record(mft_ni);
	if (IS_ERR(m)) {
		ntfs_error(vol->sb, "Failed to map mft record.");
		err = PTR_ERR(m);
		goto undo_data_init;
	}
	ctx = ntfs_attr_get_search_ctx(mft_ni, m);
	if (unlikely(!ctx)) {
		ntfs_error(vol->sb, "Failed to get search context.");
		err = -ENOMEM;
		unmap_mft_record(mft_ni);
		goto undo_data_init;
	}
	err = ntfs_attr_lookup(mft_ni->type, mft_ni->name, mft_ni->name_len,
			CASE_SENSITIVE, 0, NULL, 0, ctx);
	if (unlikely(err)) {
		ntfs_error(vol->sb, "Failed to find first attribute extent of mft data attribute.");
		ntfs_attr_put_search_ctx(ctx);
		unmap_mft_record(mft_ni);
		goto undo_data_init;
	}
	a = ctx->attr;
	read_lock_irqsave(&mft_ni->size_lock, flags);
	a->data.non_resident.initialized_size =
			cpu_to_le64(mft_ni->initialized_size);
	a->data.non_resident.data_size =
			cpu_to_le64(i_size_read(vol->mft_ino));
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
	/* Ensure the changes make it to disk. */
	mark_mft_record_dirty(ctx->ntfs_ino);
	ntfs_attr_put_search_ctx(ctx);
	unmap_mft_record(mft_ni);
	read_lock_irqsave(&mft_ni->size_lock, flags);
	ntfs_debug("Status of mft data after mft record initialization: allocated_size 0x%llx, data_size 0x%llx, initialized_size 0x%llx.",
			mft_ni->allocated_size,	i_size_read(vol->mft_ino),
			mft_ni->initialized_size);
	WARN_ON(i_size_read(vol->mft_ino) > mft_ni->allocated_size);
	WARN_ON(mft_ni->initialized_size > i_size_read(vol->mft_ino));
	read_unlock_irqrestore(&mft_ni->size_lock, flags);
mft_rec_already_initialized:
	/*
	 * We can finally drop the mft bitmap lock as the mft data attribute
	 * has been fully updated.  The only disparity left is that the
	 * allocated mft record still needs to be marked as in use to match the
	 * set bit in the mft bitmap but this is actually not a problem since
	 * this mft record is not referenced from anywhere yet and the fact
	 * that it is allocated in the mft bitmap means that no-one will try to
	 * allocate it either.
	 */
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		up_write(&vol->mftbmp_lock);
	/*
	 * We now have allocated and initialized the mft record.  Calculate the
	 * index of and the offset within the page cache page the record is in.
	 */
	index = NTFS_MFT_NR_TO_PIDX(vol, bit);
	ofs = NTFS_MFT_NR_TO_POFS(vol, bit);
	/* Read, map, and pin the folio containing the mft record. */
	folio = read_mapping_folio(vol->mft_ino->i_mapping, index, NULL);
	if (IS_ERR(folio)) {
		ntfs_error(vol->sb, "Failed to map page containing allocated mft record 0x%llx.",
				bit);
		err = PTR_ERR(folio);
		goto undo_mftbmp_alloc;
	}
	folio_lock(folio);
	folio_clear_uptodate(folio);
	m = (struct mft_record *)((u8 *)kmap_local_folio(folio, 0) + ofs);
	/* If we just formatted the mft record no need to do it again. */
	if (!record_formatted) {
		/* Sanity check that the mft record is really not in use. */
		if (ntfs_is_file_record(m->magic) &&
				(m->flags & MFT_RECORD_IN_USE)) {
			ntfs_warning(vol->sb,
				"Mft record 0x%llx was marked free in mft bitmap but is marked used itself. Unmount and run chkdsk.",
				bit);
			folio_mark_uptodate(folio);
			folio_unlock(folio);
			kunmap_local(m);
			folio_put(folio);
			NVolSetErrors(vol);
			goto search_free_rec;
		}
		/*
		 * We need to (re-)format the mft record, preserving the
		 * sequence number if it is not zero as well as the update
		 * sequence number if it is not zero or -1 (0xffff).  This
		 * means we do not need to care whether or not something went
		 * wrong with the previous mft record.
		 */
		seq_no = m->sequence_number;
		usn = *(__le16 *)((u8 *)m + le16_to_cpu(m->usa_ofs));
		err = ntfs_mft_record_layout(vol, bit, m);
		if (unlikely(err)) {
			ntfs_error(vol->sb, "Failed to layout allocated mft record 0x%llx.",
					bit);
			folio_mark_uptodate(folio);
			folio_unlock(folio);
			kunmap_local(m);
			folio_put(folio);
			goto undo_mftbmp_alloc;
		}
		if (seq_no)
			m->sequence_number = seq_no;
		if (usn && le16_to_cpu(usn) != 0xffff)
			*(__le16 *)((u8 *)m + le16_to_cpu(m->usa_ofs)) = usn;
		pre_write_mst_fixup((struct ntfs_record *)m, vol->mft_record_size);
	}
	/* Set the mft record itself in use. */
	m->flags |= MFT_RECORD_IN_USE;
	if (S_ISDIR(mode))
		m->flags |= MFT_RECORD_IS_DIRECTORY;
	folio_mark_uptodate(folio);
	if (base_ni) {
		struct mft_record *m_tmp;

		/*
		 * Setup the base mft record in the extent mft record.  This
		 * completes initialization of the allocated extent mft record
		 * and we can simply use it with map_extent_mft_record().
		 */
		m->base_mft_record = MK_LE_MREF(base_ni->mft_no,
				base_ni->seq_no);
		/*
		 * Allocate an extent inode structure for the new mft record,
		 * attach it to the base inode @base_ni and map, pin, and lock
		 * its, i.e. the allocated, mft record.
		 */
		m_tmp = map_extent_mft_record(base_ni,
					      MK_MREF(bit, le16_to_cpu(m->sequence_number)),
					      ni);
		if (IS_ERR(m_tmp)) {
			ntfs_error(vol->sb, "Failed to map allocated extent mft record 0x%llx.",
					bit);
			err = PTR_ERR(m_tmp);
			/* Set the mft record itself not in use. */
			m->flags &= cpu_to_le16(
					~le16_to_cpu(MFT_RECORD_IN_USE));
			/* Make sure the mft record is written out to disk. */
			ntfs_mft_mark_dirty(folio);
			folio_unlock(folio);
			kunmap_local(m);
			folio_put(folio);
			goto undo_mftbmp_alloc;
		}

		/*
		 * Make sure the allocated mft record is written out to disk.
		 * No need to set the inode dirty because the caller is going
		 * to do that anyway after finishing with the new extent mft
		 * record (e.g. at a minimum a new attribute will be added to
		 * the mft record.
		 */
		ntfs_mft_mark_dirty(folio);
		folio_unlock(folio);
		/*
		 * Need to unmap the page since map_extent_mft_record() mapped
		 * it as well so we have it mapped twice at the moment.
		 */
		kunmap_local(m);
		folio_put(folio);
	} else {
		/*
		 * Manually map, pin, and lock the mft record as we already
		 * have its page mapped and it is very easy to do.
		 */
		(*ni)->seq_no = le16_to_cpu(m->sequence_number);
		/*
		 * Make sure the allocated mft record is written out to disk.
		 * NOTE: We do not set the ntfs inode dirty because this would
		 * fail in ntfs_write_inode() because the inode does not have a
		 * standard information attribute yet.  Also, there is no need
		 * to set the inode dirty because the caller is going to do
		 * that anyway after finishing with the new mft record (e.g. at
		 * a minimum some new attributes will be added to the mft
		 * record.
		 */

		(*ni)->mrec = kmalloc(vol->mft_record_size, GFP_NOFS);
		if (!(*ni)->mrec) {
			folio_unlock(folio);
			kunmap_local(m);
			folio_put(folio);
			err = -ENOMEM;
			goto undo_mftbmp_alloc;
		}

		memcpy((*ni)->mrec, m, vol->mft_record_size);
		post_read_mst_fixup((struct ntfs_record *)(*ni)->mrec, vol->mft_record_size);
		ntfs_mft_mark_dirty(folio);
		folio_unlock(folio);
		(*ni)->folio = folio;
		(*ni)->folio_ofs = ofs;
		atomic_inc(&(*ni)->count);
		/* Update the default mft allocation position. */
		vol->mft_data_pos = bit + 1;
	}
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		mutex_unlock(&mft_ni->mrec_lock);
	memalloc_nofs_restore(memalloc_flags);

	/*
	 * Return the opened, allocated inode of the allocated mft record as
	 * well as the mapped, pinned, and locked mft record.
	 */
	ntfs_debug("Returning opened, allocated %sinode 0x%llx.",
			base_ni ? "extent " : "", bit);
	(*ni)->mft_no = bit;
	if (ni_mrec)
		*ni_mrec = (*ni)->mrec;
	ntfs_dec_free_mft_records(vol, 1);
	return 0;
undo_data_init:
	write_lock_irqsave(&mft_ni->size_lock, flags);
	mft_ni->initialized_size = old_data_initialized;
	i_size_write(vol->mft_ino, old_data_size);
	write_unlock_irqrestore(&mft_ni->size_lock, flags);
	goto undo_mftbmp_alloc_nolock;
undo_mftbmp_alloc:
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		down_write(&vol->mftbmp_lock);
undo_mftbmp_alloc_nolock:
	if (ntfs_bitmap_clear_bit(vol->mftbmp_ino, bit)) {
		ntfs_error(vol->sb, "Failed to clear bit in mft bitmap.%s", es);
		NVolSetErrors(vol);
	}
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		up_write(&vol->mftbmp_lock);
err_out:
	if (!base_ni || base_ni->mft_no != FILE_MFT)
		mutex_unlock(&mft_ni->mrec_lock);
	memalloc_nofs_restore(memalloc_flags);
	return err;
max_err_out:
	ntfs_warning(vol->sb,
		"Cannot allocate mft record because the maximum number of inodes (2^32) has already been reached.");
	if (!base_ni || base_ni->mft_no != FILE_MFT) {
		up_write(&vol->mftbmp_lock);
		mutex_unlock(&mft_ni->mrec_lock);
	}
	memalloc_nofs_restore(memalloc_flags);
	return -ENOSPC;
}

/*
 * ntfs_mft_record_free - free an mft record on an ntfs volume
 * @vol:	volume on which to free the mft record
 * @ni:		open ntfs inode of the mft record to free
 *
 * Free the mft record of the open inode @ni on the mounted ntfs volume @vol.
 * Note that this function calls ntfs_inode_close() internally and hence you
 * cannot use the pointer @ni any more after this function returns success.
 *
 * On success return 0 and on error return -1 with errno set to the error code.
 */
int ntfs_mft_record_free(struct ntfs_volume *vol, struct ntfs_inode *ni)
{
	u64 mft_no;
	int err;
	u16 seq_no;
	__le16 old_seq_no;
	struct mft_record *ni_mrec;
	unsigned int memalloc_flags;
	struct ntfs_inode *base_ni;

	if (!vol || !ni)
		return -EINVAL;

	ntfs_debug("Entering for inode 0x%llx.\n", (long long)ni->mft_no);

	ni_mrec = map_mft_record(ni);
	if (IS_ERR(ni_mrec))
		return -EIO;

	/* Cache the mft reference for later. */
	mft_no = ni->mft_no;

	/* Mark the mft record as not in use. */
	ni_mrec->flags &= ~MFT_RECORD_IN_USE;

	/* Increment the sequence number, skipping zero, if it is not zero. */
	old_seq_no = ni_mrec->sequence_number;
	seq_no = le16_to_cpu(old_seq_no);
	if (seq_no == 0xffff)
		seq_no = 1;
	else if (seq_no)
		seq_no++;
	ni_mrec->sequence_number = cpu_to_le16(seq_no);

	down_read(&NTFS_I(vol->mft_ino)->runlist.lock);
	err = ntfs_get_block_mft_record(NTFS_I(vol->mft_ino), ni);
	up_read(&NTFS_I(vol->mft_ino)->runlist.lock);
	if (err) {
		unmap_mft_record(ni);
		return err;
	}

	/*
	 * Set the ntfs inode dirty and write it out.  We do not need to worry
	 * about the base inode here since whatever caused the extent mft
	 * record to be freed is guaranteed to do it already.
	 */
	NInoSetDirty(ni);
	err = write_mft_record(ni, ni_mrec, 0);
	if (err)
		goto sync_rollback;

	if (likely(ni->nr_extents >= 0))
		base_ni = ni;
	else
		base_ni = ni->ext.base_ntfs_ino;

	/* Clear the bit in the $MFT/$BITMAP corresponding to this record. */
	memalloc_flags = memalloc_nofs_save();
	if (base_ni->mft_no != FILE_MFT)
		down_write(&vol->mftbmp_lock);
	err = ntfs_bitmap_clear_bit(vol->mftbmp_ino, mft_no);
	if (base_ni->mft_no != FILE_MFT)
		up_write(&vol->mftbmp_lock);
	memalloc_nofs_restore(memalloc_flags);
	if (err)
		goto bitmap_rollback;

	unmap_mft_record(ni);
	ntfs_inc_free_mft_records(vol, 1);
	return 0;

	/* Rollback what we did... */
bitmap_rollback:
	memalloc_flags = memalloc_nofs_save();
	if (base_ni->mft_no != FILE_MFT)
		down_write(&vol->mftbmp_lock);
	if (ntfs_bitmap_set_bit(vol->mftbmp_ino, mft_no))
		ntfs_error(vol->sb, "ntfs_bitmap_set_bit failed in bitmap_rollback\n");
	if (base_ni->mft_no != FILE_MFT)
		up_write(&vol->mftbmp_lock);
	memalloc_nofs_restore(memalloc_flags);
sync_rollback:
	ntfs_error(vol->sb,
		"Eeek! Rollback failed in %s. Leaving inconsistent metadata!\n", __func__);
	ni_mrec->flags |= MFT_RECORD_IN_USE;
	ni_mrec->sequence_number = old_seq_no;
	NInoSetDirty(ni);
	write_mft_record(ni, ni_mrec, 0);
	unmap_mft_record(ni);
	return err;
}

static s64 lcn_from_index(struct ntfs_volume *vol, struct ntfs_inode *ni,
		unsigned long index)
{
	s64 vcn;
	s64 lcn;

	vcn = ntfs_pidx_to_cluster(vol, index);

	down_read(&ni->runlist.lock);
	lcn = ntfs_attr_vcn_to_lcn_nolock(ni, vcn, false);
	up_read(&ni->runlist.lock);

	return lcn;
}

/*
 * ntfs_write_mft_block - Write back a folio containing MFT records
 * @folio:	The folio to write back (contains one or more MFT records)
 * @wbc:	Writeback control structure
 *
 * This function is called as part of the address_space_operations
 * .writepages implementation for the $MFT inode (or $MFTMirr).
 * It handles writing one folio (normally 4KiB page) worth of MFT records
 * to the underlying block device.
 *
 * Return: 0 on success, or -errno on error.
 */
static int ntfs_write_mft_block(struct folio *folio, struct writeback_control *wbc)
{
	struct address_space *mapping = folio->mapping;
	struct inode *vi = mapping->host;
	struct ntfs_inode *ni = NTFS_I(vi);
	struct ntfs_volume *vol = ni->vol;
	u8 *kaddr;
	struct ntfs_inode **locked_nis __free(kfree) = kmalloc_array(PAGE_SIZE / NTFS_BLOCK_SIZE,
							sizeof(struct ntfs_inode *), GFP_NOFS);
	int nr_locked_nis = 0, err = 0, mft_ofs, prev_mft_ofs;
	struct inode **ref_inos __free(kfree) = kmalloc_array(PAGE_SIZE / NTFS_BLOCK_SIZE,
							      sizeof(struct inode *), GFP_NOFS);
	int nr_ref_inos = 0;
	struct bio *bio = NULL;
	u64 mft_no;
	struct ntfs_inode *tni;
	s64 lcn;
	s64 vcn = ntfs_pidx_to_cluster(vol, folio->index);
	s64 end_vcn = ntfs_bytes_to_cluster(vol, ni->allocated_size);
	unsigned int folio_sz;
	loff_t i_size = i_size_read(vi);

	ntfs_debug("Entering for inode 0x%llx, attribute type 0x%x, folio index 0x%lx.",
			ni->mft_no, ni->type, folio->index);

	if (!locked_nis || !ref_inos) {
		folio_redirty_for_writepage(wbc, folio);
		folio_unlock(folio);
		return -ENOMEM;
	}

	/* We have to zero every time due to mmap-at-end-of-file. */
	if (folio->index >= (i_size >> folio_shift(folio)))
		/* The page straddles i_size. */
		folio_zero_segment(folio,
				   offset_in_folio(folio, i_size),
				   folio_size(folio));

	lcn = lcn_from_index(vol, ni, folio->index);
	if (lcn <= LCN_HOLE) {
		folio_start_writeback(folio);
		folio_unlock(folio);
		folio_end_writeback(folio);
		return -EIO;
	}

	/* Map folio so we can access its contents. */
	kaddr = kmap_local_folio(folio, 0);
	/* Clear the page uptodate flag whilst the mst fixups are applied. */
	folio_clear_uptodate(folio);

	for (mft_ofs = 0; mft_ofs < PAGE_SIZE && vcn < end_vcn;
	     mft_ofs += vol->mft_record_size) {
		/* Get the mft record number. */
		mft_no = (((s64)folio->index << PAGE_SHIFT) + mft_ofs) >>
			vol->mft_record_size_bits;
		vcn = ntfs_mft_no_to_cluster(vol, mft_no);
		/* Check whether to write this mft record. */
		tni = NULL;
		if (ntfs_may_write_mft_record(vol, mft_no,
					(struct mft_record *)(kaddr + mft_ofs),
					&tni, &ref_inos[nr_ref_inos])) {
			unsigned int mft_record_off = 0;
			s64 vcn_off = vcn;
			s64 rl_len = 0;

			/*
			 * The record should be written.  If a locked ntfs
			 * inode was returned, add it to the array of locked
			 * ntfs inodes.
			 */
			if (tni)
				locked_nis[nr_locked_nis++] = tni;
			else if (ref_inos[nr_ref_inos])
				nr_ref_inos++;

			if (bio && (mft_ofs != prev_mft_ofs + vol->mft_record_size)) {
flush_bio:
				bio->bi_end_io = ntfs_bio_end_io;
				submit_bio(bio);
				bio = NULL;
			}

			if (vol->cluster_size < folio_size(folio)) {
				struct runlist_element *rl;

				down_write(&ni->runlist.lock);
				rl = ntfs_attr_vcn_to_rl(ni, vcn_off, &lcn);
				if (!IS_ERR(rl))
					rl_len = rl->length - (vcn_off - rl->vcn);
				up_write(&ni->runlist.lock);
				if (IS_ERR(rl) || lcn < 0) {
					err = -EIO;
					goto unm_done;
				}

				if (bio &&
				   (bio_end_sector(bio) >> (vol->cluster_size_bits - 9)) !=
				    lcn) {
					bio->bi_end_io = ntfs_bio_end_io;
					submit_bio(bio);
					bio = NULL;
				}
			}

			if (!bio) {
				unsigned int off;

				off = ((mft_no << vol->mft_record_size_bits) +
				       mft_record_off) & vol->cluster_size_mask;

				bio = bio_alloc(vol->sb->s_bdev, 1, REQ_OP_WRITE,
						GFP_NOIO);
				bio->bi_iter.bi_sector =
					ntfs_bytes_to_sector(vol,
							ntfs_cluster_to_bytes(vol, lcn) + off);
			}

			if (vol->cluster_size == NTFS_BLOCK_SIZE &&
			    (mft_record_off ||
			     rl_len == 1 ||
			     mft_ofs + NTFS_BLOCK_SIZE >= PAGE_SIZE))
				folio_sz = NTFS_BLOCK_SIZE;
			else
				folio_sz = vol->mft_record_size;
			if (!bio_add_folio(bio, folio, folio_sz,
					   mft_ofs + mft_record_off)) {
				err = -EIO;
				bio_put(bio);
				goto unm_done;
			}
			mft_record_off += folio_sz;

			if (mft_record_off != vol->mft_record_size) {
				vcn_off++;
				goto flush_bio;
			}
			prev_mft_ofs = mft_ofs;

			if (mft_no < vol->mftmirr_size) {
				int sub_err = ntfs_sync_mft_mirror(vol, mft_no,
						(struct mft_record *)(kaddr + mft_ofs));

				if (unlikely(sub_err) && !err)
					err = sub_err;
			}
		} else if (ref_inos[nr_ref_inos])
			nr_ref_inos++;
	}

	if (bio) {
		bio->bi_end_io = ntfs_bio_end_io;
		submit_bio(bio);
	}
unm_done:
	folio_mark_uptodate(folio);
	kunmap_local(kaddr);

	folio_start_writeback(folio);
	folio_unlock(folio);
	folio_end_writeback(folio);

	/* Unlock any locked inodes. */
	while (nr_locked_nis-- > 0) {
		struct ntfs_inode *base_tni;

		tni = locked_nis[nr_locked_nis];
		mutex_unlock(&tni->mrec_lock);

		/* Get the base inode. */
		mutex_lock(&tni->extent_lock);
		if (tni->nr_extents >= 0)
			base_tni = tni;
		else
			base_tni = tni->ext.base_ntfs_ino;
		mutex_unlock(&tni->extent_lock);
		ntfs_debug("Unlocking %s inode 0x%llx.",
				tni == base_tni ? "base" : "extent",
				tni->mft_no);
		atomic_dec(&tni->count);
		iput(VFS_I(base_tni));
	}

	/* Dropping deferred references */
	while (nr_ref_inos-- > 0) {
		if (ref_inos[nr_ref_inos])
			iput(ref_inos[nr_ref_inos]);
	}

	if (unlikely(err && err != -ENOMEM))
		NVolSetErrors(vol);
	if (likely(!err))
		ntfs_debug("Done.");
	return err;
}

/*
 * ntfs_mft_writepages - Write back dirty folios for the $MFT inode
 * @mapping:	address space of the $MFT inode
 * @wbc:	writeback control
 *
 * Writeback iterator for MFT records. Iterates over dirty folios and
 * delegates actual writing to ntfs_write_mft_block() for each folio.
 * Called from the address_space_operations .writepages vector of the
 * $MFT inode.
 *
 * Returns 0 on success, or the first error encountered.
 */
int ntfs_mft_writepages(struct address_space *mapping,
		struct writeback_control *wbc)
{
	struct folio *folio = NULL;
	int error;

	if (NVolShutdown(NTFS_I(mapping->host)->vol))
		return -EIO;

	while ((folio = writeback_iter(mapping, wbc, folio, &error)))
		error = ntfs_write_mft_block(folio, wbc);
	return error;
}

void ntfs_mft_mark_dirty(struct folio *folio)
{
	iomap_dirty_folio(folio->mapping, folio);
}
