// SPDX-License-Identifier: GPL-2.0-or-later
/*
 * NTFS kernel address space operations and page cache handling.
 *
 * Copyright (c) 2001-2014 Anton Altaparmakov and Tuxera Inc.
 * Copyright (c) 2002 Richard Russon
 * Copyright (c) 2025 LG Electronics Co., Ltd.
 */

#include <linux/writeback.h>

#include "attrib.h"
#include "mft.h"
#include "ntfs.h"
#include "debug.h"
#include "iomap.h"

static void ntfs_iomap_read_end_io(struct bio *bio)
{
	int error = blk_status_to_errno(bio->bi_status);
	struct folio_iter iter;

	bio_for_each_folio_all(iter, bio) {
		struct folio *folio = iter.folio;
		struct ntfs_inode *ni = NTFS_I(folio->mapping->host);
		s64 init_size;
		loff_t pos = folio_pos(folio);

		init_size = ni->initialized_size;
		if (pos + iter.offset < init_size &&
		    pos + iter.offset + iter.length > init_size)
			folio_zero_segment(folio, offset_in_folio(folio, init_size),
					   iter.offset + iter.length);

		iomap_finish_folio_read(folio, iter.offset, iter.length, error);
	}
	bio_put(bio);
}

static void ntfs_iomap_bio_submit_read(const struct iomap_iter *iter,
		struct iomap_read_folio_ctx *ctx)
{
	iomap_bio_submit_read_endio(iter, ctx, ntfs_iomap_read_end_io);
}

static const struct iomap_read_ops ntfs_iomap_bio_read_ops = {
	.read_folio_range	= iomap_bio_read_folio_range,
	.submit_read		= ntfs_iomap_bio_submit_read,
};

/*
 * ntfs_read_folio - Read data for a folio from the device
 * @file:	open file to which the folio @folio belongs or NULL
 * @folio:	page cache folio to fill with data
 *
 * This function handles reading data into the page cache. It first checks
 * for specific ntfs attribute type like encryption and compression.
 *
 * - If the attribute is encrypted, access is denied (-EACCES) because
 *   decryption is not supported in this path.
 * - If the attribute is non-resident and compressed, the read operation is
 *   delegated to ntfs_read_compressed_block().
 * - For normal resident or non-resident attribute, it utilizes the generic
 *   iomap infrastructure via iomap_bio_read_folio() to perform the I/O.
 *
 * Return: 0 on success, or -errno on error.
 */
static int ntfs_read_folio(struct file *file, struct folio *folio)
{
	struct ntfs_inode *ni = NTFS_I(folio->mapping->host);
	struct iomap_read_folio_ctx ctx = {
		.cur_folio = folio,
		.ops = &ntfs_iomap_bio_read_ops,
	};

	/*
	 * Only $DATA attributes can be encrypted and only unnamed $DATA
	 * attributes can be compressed.  Index root can have the flags set but
	 * this means to create compressed/encrypted files, not that the
	 * attribute is compressed/encrypted.  Note we need to check for
	 * AT_INDEX_ALLOCATION since this is the type of both directory and
	 * index inodes.
	 */
	if (ni->type != AT_INDEX_ALLOCATION) {
		/*
		 * EFS-encrypted files are not supported.
		 * (decryption/encryption is not implemented yet)
		 */
		if (NInoEncrypted(ni)) {
			folio_unlock(folio);
			return -EOPNOTSUPP;
		}
		if (NInoWofCompressed(ni)) {
#ifdef CONFIG_NTFS_FS_WOF_COMPRESSION
			return ntfs_read_wof_compressed_block(folio);
#else
			folio_unlock(folio);
			return -EOPNOTSUPP;
#endif
		}
		/* Compressed data streams are handled in compress.c. */
		if (NInoNonResident(ni) && NInoCompressed(ni))
			return ntfs_read_compressed_block(folio);
	}

	iomap_read_folio(&ntfs_read_iomap_ops, &ctx, NULL);
	return 0;
}

/*
 * ntfs_bmap - map logical file block to physical device block
 * @mapping:	address space mapping to which the block to be mapped belongs
 * @block:	logical block to map to its physical device block
 *
 * For regular, non-resident files (i.e. not compressed and not encrypted), map
 * the logical @block belonging to the file described by the address space
 * mapping @mapping to its physical device block.
 *
 * The size of the block is equal to the @s_blocksize field of the super block
 * of the mounted file system which is guaranteed to be smaller than or equal
 * to the cluster size thus the block is guaranteed to fit entirely inside the
 * cluster which means we do not need to care how many contiguous bytes are
 * available after the beginning of the block.
 *
 * Return the physical device block if the mapping succeeded or 0 if the block
 * is sparse or there was an error.
 *
 * Note: This is a problem if someone tries to run bmap() on $Boot system file
 * as that really is in block zero but there is nothing we can do.  bmap() is
 * just broken in that respect (just like it cannot distinguish sparse from
 * not available or error).
 */
static sector_t ntfs_bmap(struct address_space *mapping, sector_t block)
{
	s64 ofs, size;
	loff_t i_size;
	s64 lcn;
	unsigned long blocksize, flags;
	struct ntfs_inode *ni = NTFS_I(mapping->host);
	struct ntfs_volume *vol = ni->vol;
	unsigned int delta;
	unsigned char blocksize_bits;

	ntfs_debug("Entering for mft_no 0x%llx, logical block 0x%llx.",
			ni->mft_no, (unsigned long long)block);
	if (ni->type != AT_DATA || !NInoNonResident(ni) || NInoEncrypted(ni) ||
	    NInoWofCompressed(ni) || NInoMstProtected(ni)) {
		ntfs_error(vol->sb, "BMAP does not make sense for %s attributes, returning 0.",
				(ni->type != AT_DATA) ? "non-data" :
				(!NInoNonResident(ni) ? "resident" :
				(NInoWofCompressed(ni) ? "WOF-compressed" :
				"encrypted")));
		return 0;
	}
	/* None of these can happen. */
	blocksize = vol->sb->s_blocksize;
	blocksize_bits = vol->sb->s_blocksize_bits;
	ofs = (s64)block << blocksize_bits;
	read_lock_irqsave(&ni->size_lock, flags);
	size = ni->initialized_size;
	i_size = i_size_read(VFS_I(ni));
	read_unlock_irqrestore(&ni->size_lock, flags);
	/*
	 * If the offset is outside the initialized size or the block straddles
	 * the initialized size then pretend it is a hole unless the
	 * initialized size equals the file size.
	 */
	if (unlikely(ofs >= size || (ofs + blocksize > size && size < i_size)))
		goto hole;
	down_read(&ni->runlist.lock);
	lcn = ntfs_attr_vcn_to_lcn_nolock(ni, ntfs_bytes_to_cluster(vol, ofs),
			false);
	up_read(&ni->runlist.lock);
	if (unlikely(lcn < LCN_HOLE)) {
		/*
		 * Step down to an integer to avoid gcc doing a long long
		 * comparision in the switch when we know @lcn is between
		 * LCN_HOLE and LCN_EIO (i.e. -1 to -5).
		 *
		 * Otherwise older gcc (at least on some architectures) will
		 * try to use __cmpdi2() which is of course not available in
		 * the kernel.
		 */
		switch ((int)lcn) {
		case LCN_ENOENT:
			/*
			 * If the offset is out of bounds then pretend it is a
			 * hole.
			 */
			goto hole;
		case LCN_ENOMEM:
			ntfs_error(vol->sb,
				"Not enough memory to complete mapping for inode 0x%llx. Returning 0.",
				ni->mft_no);
			break;
		default:
			ntfs_error(vol->sb,
				"Failed to complete mapping for inode 0x%llx.  Run chkdsk. Returning 0.",
				ni->mft_no);
			break;
		}
		return 0;
	}
	if (lcn < 0) {
		/* It is a hole. */
hole:
		ntfs_debug("Done (returning hole).");
		return 0;
	}
	/*
	 * The block is really allocated and fullfils all our criteria.
	 * Convert the cluster to units of block size and return the result.
	 */
	delta = ofs & vol->cluster_size_mask;
	if (unlikely(sizeof(block) < sizeof(lcn))) {
		block = lcn = (ntfs_cluster_to_bytes(vol, lcn) + delta) >>
				blocksize_bits;
		/* If the block number was truncated return 0. */
		if (unlikely(block != lcn)) {
			ntfs_error(vol->sb,
				"Physical block 0x%llx is too large to be returned, returning 0.",
				(long long)lcn);
			return 0;
		}
	} else
		block = (ntfs_cluster_to_bytes(vol, lcn) + delta) >>
				blocksize_bits;
	ntfs_debug("Done (returning block 0x%llx).", (unsigned long long)lcn);
	return block;
}

static void ntfs_readahead(struct readahead_control *rac)
{
	struct address_space *mapping = rac->mapping;
	struct inode *inode = mapping->host;
	struct ntfs_inode *ni = NTFS_I(inode);
	struct iomap_read_folio_ctx ctx = {
		.ops = &ntfs_iomap_bio_read_ops,
		.rac = rac,
	};

	/*
	 * Resident files are not cached in the page cache,
	 * and readahead is not implemented for compressed files.
	 */
	if (!NInoNonResident(ni) || NInoCompressed(ni) ||
	    NInoWofCompressed(ni))
		return;
	iomap_readahead(&ntfs_read_iomap_ops, &ctx, NULL);
}

static int ntfs_writepages(struct address_space *mapping,
		struct writeback_control *wbc)
{
	struct inode *inode = mapping->host;
	struct ntfs_inode *ni = NTFS_I(inode);
	struct iomap_writepage_ctx wpc = {
		.inode		= mapping->host,
		.wbc		= wbc,
		.ops		= &ntfs_writeback_ops,
	};
	bool need_iput = false;
	int ret;

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

	if (!NInoNonResident(ni))
		return 0;

	/*
	 * EFS-encrypted files are not supported.
	 * (decryption/encryption is not implemented yet)
	 */
	if (NInoEncrypted(ni)) {
		ntfs_debug("Encrypted I/O not supported");
		return -EOPNOTSUPP;
	}

	/*
	 * Prevent eviction in writeback to avoid deadlock in
	 * ntfs_drop_big_inode().
	 */
	if ((ni->type == AT_DATA || ni->type == AT_INDEX_ALLOCATION) &&
	    igrab(inode))
		need_iput = true;

	ret = iomap_writepages(&wpc);

	if (need_iput)
		iput(inode);

	return ret;
}

static int ntfs_swap_activate(struct swap_info_struct *sis,
		struct file *swap_file, sector_t *span)
{
	if (NInoWofCompressed(NTFS_I(file_inode(swap_file))))
		return -EOPNOTSUPP;

	return iomap_swapfile_activate(sis, swap_file, span,
			&ntfs_read_iomap_ops);
}

const struct address_space_operations ntfs_aops = {
	.read_folio		= ntfs_read_folio,
	.readahead		= ntfs_readahead,
	.writepages		= ntfs_writepages,
	.dirty_folio		= iomap_dirty_folio,
	.bmap			= ntfs_bmap,
	.migrate_folio		= filemap_migrate_folio,
	.is_partially_uptodate	= iomap_is_partially_uptodate,
	.error_remove_folio	= generic_error_remove_folio,
	.release_folio		= iomap_release_folio,
	.invalidate_folio	= iomap_invalidate_folio,
	.swap_activate          = ntfs_swap_activate,
};

const struct address_space_operations ntfs_mft_aops = {
	.read_folio		= ntfs_read_folio,
	.readahead		= ntfs_readahead,
	.writepages		= ntfs_mft_writepages,
	.dirty_folio		= iomap_dirty_folio,
	.bmap			= ntfs_bmap,
	.migrate_folio		= filemap_migrate_folio,
	.is_partially_uptodate	= iomap_is_partially_uptodate,
	.error_remove_folio	= generic_error_remove_folio,
	.release_folio		= iomap_release_folio,
	.invalidate_folio	= iomap_invalidate_folio,
};
