/*
 * fs/mpage.c
 *
 * Copyright (C) 2002, Linus Torvalds.
 *
 * Contains functions related to preparing and submitting BIOs which contain
 * multiple pagecache pages.
 *
 * 15May2002	Andrew Morton
 *		Initial version
 * 27Jun2002	axboe@suse.de
 *		use bio_add_page() to build bio's just the right size
 */

/*
 *  Copyright (C) 2012-2013 Samsung Electronics Co., Ltd.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU General Public License
 *  as published by the Free Software Foundation; either version 2
 *  of the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, see <http://www.gnu.org/licenses/>.
 */

/************************************************************************/
/*                                                                      */
/*  PROJECT : exFAT & FAT12/16/32 File System                           */
/*  FILE    : core.c                                                    */
/*  PURPOSE : sdFAT glue layer for supporting VFS                       */
/*                                                                      */
/*----------------------------------------------------------------------*/
/*  NOTES                                                               */
/*                                                                      */
/*                                                                      */
/************************************************************************/

#include <linux/version.h>
#include <linux/module.h>
#include <linux/time.h>
#include <linux/buffer_head.h>
#include <linux/exportfs.h>
#include <linux/mount.h>
#include <linux/vfs.h>
#include <linux/parser.h>
#include <linux/uio.h>
#include <linux/writeback.h>
#include <linux/log2.h>
#include <linux/hash.h>
#include <linux/backing-dev.h>
#include <linux/sched.h>
#include <linux/fs_struct.h>
#include <linux/namei.h>
#include <linux/bio.h>
#include <linux/blkdev.h>
#include <linux/swap.h> /* for mark_page_accessed() */
#include <asm/current.h>
#include <asm/unaligned.h>
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 10, 0)
#include <linux/aio.h>
#endif

#include "sdfat.h"

#ifdef CONFIG_SDFAT_ALIGNED_MPAGE_WRITE

#define MIN_ALIGNED_SIZE	(PAGE_SIZE)
#define MIN_ALIGNED_SIZE_MASK	(MIN_ALIGNED_SIZE - 1)

/*************************************************************************
 * INNER FUNCTIONS FOR FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
 *************************************************************************/
static void __mpage_write_end_io(struct bio *bio, int err);

/*************************************************************************
 * FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
 *************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 14, 0)
       /* EMPTY */
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0) */
static inline void bio_set_dev(struct bio *bio, struct block_device *bdev)
{
	bio->bi_bdev = bdev;
}
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 10, 0)
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
	clean_bdev_aliases(bdev, block, 1);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,10,0) */
static inline void __sdfat_clean_bdev_aliases(struct block_device *bdev, sector_t block)
{
	unmap_underlying_metadata(bdev, block);
}

static inline int wbc_to_write_flags(struct writeback_control *wbc)
{
	if (wbc->sync_mode == WB_SYNC_ALL)
		return WRITE_SYNC;

	return 0;
}
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 8, 0)
static inline void __sdfat_submit_bio_write2(int flags, struct bio *bio)
{
	bio_set_op_attrs(bio, REQ_OP_WRITE, flags);
	submit_bio(bio);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,8,0) */
static inline void __sdfat_submit_bio_write2(int flags, struct bio *bio)
{
	submit_bio(WRITE | flags, bio);
}
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 1, 0)
static inline int bio_get_nr_vecs(struct block_device *bdev)
{
	return BIO_MAX_PAGES;
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,1,0) */
	/* EMPTY */
#endif

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 14, 0)
static inline sector_t __sdfat_bio_sector(struct bio *bio)
{
	return bio->bi_iter.bi_sector;
}

static inline void __sdfat_set_bio_sector(struct bio *bio, sector_t sector)
{
	bio->bi_iter.bi_sector = sector;
}

static inline unsigned int __sdfat_bio_size(struct bio *bio)
{
	return bio->bi_iter.bi_size;
}

static inline void __sdfat_set_bio_size(struct bio *bio, unsigned int size)
{
	bio->bi_iter.bi_size = size;
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 14, 0) */
static inline sector_t __sdfat_bio_sector(struct bio *bio)
{
	return bio->bi_sector;
}

static inline void __sdfat_set_bio_sector(struct bio *bio, sector_t sector)
{
	bio->bi_sector = sector;
}

static inline unsigned int __sdfat_bio_size(struct bio *bio)
{
	return bio->bi_size;
}

static inline void __sdfat_set_bio_size(struct bio *bio, unsigned int size)
{
	bio->bi_size = size;
}
#endif

/*************************************************************************
 * MORE FUNCTIONS WHICH HAS KERNEL VERSION DEPENDENCY
 *************************************************************************/
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 13, 0)
static void  mpage_write_end_io(struct bio *bio)
{
	__mpage_write_end_io(bio, blk_status_to_errno(bio->bi_status));
}
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(4, 3, 0)
static void  mpage_write_end_io(struct bio *bio)
{
	__mpage_write_end_io(bio, bio->bi_error);
}
#else /* LINUX_VERSION_CODE < KERNEL_VERSION(4,3,0) */
static void mpage_write_end_io(struct bio *bio, int err)
{
	if (test_bit(BIO_UPTODATE, &bio->bi_flags))
		err = 0;
	__mpage_write_end_io(bio, err);
}
#endif

/* __check_dfr_on() and __dfr_writepage_end_io() functions
 * are copied from sdfat.c
 * Each function should be same perfectly
 */
static inline int __check_dfr_on(struct inode *inode, loff_t start, loff_t end, const char *fname)
{
#ifdef	CONFIG_SDFAT_DFR
	struct defrag_info *ino_dfr = &(SDFAT_I(inode)->dfr_info);

	if ((atomic_read(&ino_dfr->stat) == DFR_INO_STAT_REQ) &&
			fsapi_dfr_check_dfr_on(inode, start, end, 0, fname))
		return 1;
#endif
	return 0;
}

static inline int __dfr_writepage_end_io(struct page *page)
{
#ifdef	CONFIG_SDFAT_DFR
	struct defrag_info *ino_dfr = &(SDFAT_I(page->mapping->host)->dfr_info);

	if (atomic_read(&ino_dfr->stat) == DFR_INO_STAT_REQ)
		fsapi_dfr_writepage_endio(page);
#endif
	return 0;
}


static inline unsigned int __calc_size_to_align(struct super_block *sb)
{
	struct block_device *bdev = sb->s_bdev;
	struct gendisk *disk;
	struct request_queue *queue;
	struct queue_limits *limit;
	unsigned int max_sectors;
	unsigned int aligned = 0;

	disk = bdev->bd_disk;
	if (!disk)
		goto out;

	queue = disk->queue;
	if (!queue)
		goto out;

	limit = &queue->limits;
	max_sectors = limit->max_sectors;
	aligned = 1 << ilog2(max_sectors);

	if (aligned && (max_sectors & (aligned - 1)))
		aligned = 0;

	if (aligned && aligned < (MIN_ALIGNED_SIZE >> SECTOR_SIZE_BITS))
		aligned = 0;
out:
	return aligned;
}

struct mpage_data {
	struct bio *bio;
	sector_t last_block_in_bio;
	get_block_t *get_block;
	unsigned int use_writepage;
	unsigned int size_to_align;
};

/*
 * After completing I/O on a page, call this routine to update the page
 * flags appropriately
 */
static void __page_write_endio(struct page *page, int err)
{
	if (err) {
		struct address_space *mapping;

		SetPageError(page);
		mapping = page_mapping(page);
		if (mapping)
			mapping_set_error(mapping, err);
	}
	__dfr_writepage_end_io(page);
	end_page_writeback(page);
}

/*
 * I/O completion handler for multipage BIOs.
 *
 * The mpage code never puts partial pages into a BIO (except for end-of-file).
 * If a page does not map to a contiguous run of blocks then it simply falls
 * back to block_read_full_page().
 *
 * Why is this?  If a page's completion depends on a number of different BIOs
 * which can complete in any order (or at the same time) then determining the
 * status of that page is hard.  See end_buffer_async_read() for the details.
 * There is no point in duplicating all that complexity.
 */
static void __mpage_write_end_io(struct bio *bio, int err)
{
	struct bio_vec *bv;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 2, 0)
	struct bvec_iter_all iter_all;

	ASSERT(bio_data_dir(bio) == WRITE); /* only write */

	/* Use bio_for_each_segemnt_all() to support multi-page bvec */
	bio_for_each_segment_all(bv, bio, iter_all)
		__page_write_endio(bv->bv_page, err);
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 1, 0)
	struct bvec_iter_all iter_all;
	int i;

	ASSERT(bio_data_dir(bio) == WRITE); /* only write */

	/* Use bio_for_each_segemnt_all() to support multi-page bvec */
	bio_for_each_segment_all(bv, bio, i, iter_all)
		__page_write_endio(bv->bv_page, err);
#else
	ASSERT(bio_data_dir(bio) == WRITE); /* only write */
	bv = bio->bi_io_vec + bio->bi_vcnt - 1;

	do {
		struct page *page = bv->bv_page;

		if (--bv >= bio->bi_io_vec)
			prefetchw(&bv->bv_page->flags);

		__page_write_endio(page, err);
	} while (bv >= bio->bi_io_vec);
#endif
	bio_put(bio);
}

static struct bio *mpage_bio_submit_write(int flags, struct bio *bio)
{
	bio->bi_end_io = mpage_write_end_io;
	__sdfat_submit_bio_write2(flags, bio);
	return NULL;
}

static struct bio *
mpage_alloc(struct block_device *bdev,
		sector_t first_sector, int nr_vecs,
		gfp_t gfp_flags)
{
	struct bio *bio;

	bio = bio_alloc(gfp_flags, nr_vecs);

	if (bio == NULL && (current->flags & PF_MEMALLOC)) {
		while (!bio && (nr_vecs /= 2))
			bio = bio_alloc(gfp_flags, nr_vecs);
	}

	if (bio) {
		bio_set_dev(bio, bdev);
		__sdfat_set_bio_sector(bio, first_sector);
	}
	return bio;
}


#if IS_BUILTIN(CONFIG_SDFAT_FS)
#define __write_boundary_block	write_boundary_block
#define sdfat_buffer_heads_over_limit	buffer_heads_over_limit
#else

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 9, 0)
/*
 * Called when we've recently written block `bblock', and it is known that
 * `bblock' was for a buffer_boundary() buffer.  This means that the block at
 * `bblock + 1' is probably a dirty indirect block.  Hunt it down and, if it's
 * dirty, schedule it for IO.  So that indirects merge nicely with their data.
 */
static void __write_boundary_block(struct block_device *bdev,
				sector_t bblock, unsigned int blocksize)
{
	struct buffer_head *bh = __find_get_block(bdev, bblock + 1, blocksize);

	if (bh) {
		if (buffer_dirty(bh))
			ll_rw_block(REQ_OP_WRITE, 0, 1, &bh);
		put_bh(bh);
	}
}
#else
#warning "Need an alternative of write_boundary_block function"
#define __write_boundary_block	write_boundary_block
#endif

#warning "sdfat could not check buffer_heads_over_limit on module. Assumed zero"
#define sdfat_buffer_heads_over_limit	(0)
#endif

static void clean_buffers(struct page *page, unsigned int first_unmapped)
{
	unsigned int buffer_counter = 0;
	struct buffer_head *bh, *head;

	if (!page_has_buffers(page))
		return;
	head = page_buffers(page);
	bh = head;

	do {
		if (buffer_counter++ == first_unmapped)
			break;
		clear_buffer_dirty(bh);
		bh = bh->b_this_page;
	} while (bh != head);

	/*
	 * we cannot drop the bh if the page is not uptodate or a concurrent
	 * readpage would fail to serialize with the bh and it would read from
	 * disk before we reach the platter.
	 */
	if (sdfat_buffer_heads_over_limit && PageUptodate(page))
		try_to_free_buffers(page);
}

static int sdfat_mpage_writepage(struct page *page,
		struct writeback_control *wbc, void *data)
{
	struct mpage_data *mpd = data;
	struct bio *bio = mpd->bio;
	struct address_space *mapping = page->mapping;
	struct inode *inode = page->mapping->host;
	const unsigned int blkbits = inode->i_blkbits;
	const unsigned int blocks_per_page = PAGE_SIZE >> blkbits;
	sector_t last_block;
	sector_t block_in_file;
	sector_t blocks[MAX_BUF_PER_PAGE];
	unsigned int page_block;
	unsigned int first_unmapped = blocks_per_page;
	struct block_device *bdev = NULL;
	int boundary = 0;
	sector_t boundary_block = 0;
	struct block_device *boundary_bdev = NULL;
	int length;
	struct buffer_head map_bh;
	loff_t i_size = i_size_read(inode);
	unsigned long end_index = i_size >> PAGE_SHIFT;
	int ret = 0;
	int op_flags = wbc_to_write_flags(wbc);

	if (page_has_buffers(page)) {
		struct buffer_head *head = page_buffers(page);
		struct buffer_head *bh = head;

		/* If they're all mapped and dirty, do it */
		page_block = 0;
		do {
			BUG_ON(buffer_locked(bh));
			if (!buffer_mapped(bh)) {
				/*
				 * unmapped dirty buffers are created by
				 * __set_page_dirty_buffers -> mmapped data
				 */
				if (buffer_dirty(bh))
					goto confused;
				if (first_unmapped == blocks_per_page)
					first_unmapped = page_block;
				continue;
			}

			if (first_unmapped != blocks_per_page)
				goto confused;	/* hole -> non-hole */

			if (!buffer_dirty(bh) || !buffer_uptodate(bh))
				goto confused;

			/* bh should be mapped if delay is set */
			if (buffer_delay(bh)) {
				sector_t blk_in_file =
					(sector_t)(page->index << (PAGE_SHIFT - blkbits)) + page_block;

				BUG_ON(bh->b_size != (1 << blkbits));
				if (page->index > end_index) {
					MMSG("%s(inode:%p) "
						"over end with delayed buffer"
						"(page_idx:%u, end_idx:%u)\n",
						__func__, inode,
						(u32)page->index,
						(u32)end_index);
					goto confused;
				}

				ret = mpd->get_block(inode, blk_in_file, bh, 1);
				if (ret) {
					MMSG("%s(inode:%p) "
						"failed to getblk(ret:%d)\n",
						__func__, inode, ret);
					goto confused;
				}

				BUG_ON(buffer_delay(bh));

				if (buffer_new(bh)) {
					clear_buffer_new(bh);
					__sdfat_clean_bdev_aliases(bh->b_bdev, bh->b_blocknr);
				}
			}

			if (page_block) {
				if (bh->b_blocknr != blocks[page_block-1] + 1) {
					MMSG("%s(inode:%p) pblk(%d) "
						"no_seq(prev:%lld, new:%lld)\n",
						__func__, inode, page_block,
						(u64)blocks[page_block-1],
						(u64)bh->b_blocknr);
					goto confused;
				}
			}
			blocks[page_block++] = bh->b_blocknr;
			boundary = buffer_boundary(bh);
			if (boundary) {
				boundary_block = bh->b_blocknr;
				boundary_bdev = bh->b_bdev;
			}
			bdev = bh->b_bdev;
		} while ((bh = bh->b_this_page) != head);

		if (first_unmapped)
			goto page_is_mapped;

		/*
		 * Page has buffers, but they are all unmapped. The page was
		 * created by pagein or read over a hole which was handled by
		 * block_read_full_page().  If this address_space is also
		 * using mpage_readpages then this can rarely happen.
		 */
		goto confused;
	}

	/*
	 * The page has no buffers: map it to disk
	 */
	BUG_ON(!PageUptodate(page));
	block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits);
	last_block = (i_size - 1) >> blkbits;
	map_bh.b_page = page;
	for (page_block = 0; page_block < blocks_per_page; ) {

		map_bh.b_state = 0;
		map_bh.b_size = 1 << blkbits;
		if (mpd->get_block(inode, block_in_file, &map_bh, 1))
			goto confused;

		if (buffer_new(&map_bh))
			__sdfat_clean_bdev_aliases(map_bh.b_bdev, map_bh.b_blocknr);
		if (buffer_boundary(&map_bh)) {
			boundary_block = map_bh.b_blocknr;
			boundary_bdev = map_bh.b_bdev;
		}

		if (page_block) {
			if (map_bh.b_blocknr != blocks[page_block-1] + 1)
				goto confused;
		}
		blocks[page_block++] = map_bh.b_blocknr;
		boundary = buffer_boundary(&map_bh);
		bdev = map_bh.b_bdev;
		if (block_in_file == last_block)
			break;
		block_in_file++;
	}
	BUG_ON(page_block == 0);

	first_unmapped = page_block;

page_is_mapped:
	if (page->index >= end_index) {
		/*
		 * The page straddles i_size.  It must be zeroed out on each
		 * and every writepage invocation because it may be mmapped.
		 * "A file is mapped in multiples of the page size.  For a file
		 * that is not a multiple of the page size, the remaining memory
		 * is zeroed when mapped, and writes to that region are not
		 * written out to the file."
		 */
		unsigned int offset = i_size & (PAGE_SIZE - 1);

		if (page->index > end_index || !offset) {
			MMSG("%s(inode:%p) over end "
				"(page_idx:%u, end_idx:%u off:%u)\n",
				__func__, inode, (u32)page->index,
				(u32)end_index, (u32)offset);
			goto confused;
		}
		zero_user_segment(page, offset, PAGE_SIZE);
	}

	/*
	 * This page will go to BIO.  Do we need to send this BIO off first?
	 *
	 * REMARK : added ELSE_IF for ALIGNMENT_MPAGE_WRITE of SDFAT
	 */
	if (bio) {
		if (mpd->last_block_in_bio != blocks[0] - 1) {
			bio = mpage_bio_submit_write(op_flags, bio);
		} else if (mpd->size_to_align) {
			unsigned int mask = mpd->size_to_align - 1;
			sector_t max_end_block =
				(__sdfat_bio_sector(bio) & ~(mask)) + mask;

			if ((__sdfat_bio_size(bio) & MIN_ALIGNED_SIZE_MASK) &&
				(mpd->last_block_in_bio == max_end_block)) {
				int op_nomerge = op_flags | REQ_NOMERGE;

				MMSG("%s(inode:%p) alignment mpage_bio_submit"
				     "(start:%u, len:%u size:%u aligned:%u)\n",
					__func__, inode,
					(unsigned int)__sdfat_bio_sector(bio),
					(unsigned int)(mpd->last_block_in_bio -
						__sdfat_bio_sector(bio) + 1),
					(unsigned int)__sdfat_bio_size(bio),
					(unsigned int)mpd->size_to_align);
				bio = mpage_bio_submit_write(op_nomerge, bio);
			}
		}
	}

alloc_new:
	if (!bio) {
		bio = mpage_alloc(bdev, blocks[0] << (blkbits - 9),
				bio_get_nr_vecs(bdev), GFP_NOFS|__GFP_HIGH);
		if (!bio)
			goto confused;
	}

	/*
	 * Must try to add the page before marking the buffer clean or
	 * the confused fail path above (OOM) will be very confused when
	 * it finds all bh marked clean (i.e. it will not write anything)
	 */
	length = first_unmapped << blkbits;
	if (bio_add_page(bio, page, length, 0) < length) {
		bio = mpage_bio_submit_write(op_flags, bio);
		goto alloc_new;
	}

	/*
	 * OK, we have our BIO, so we can now mark the buffers clean.  Make
	 * sure to only clean buffers which we know we'll be writing.
	 */
	clean_buffers(page, first_unmapped);

	BUG_ON(PageWriteback(page));
	set_page_writeback(page);

	/*
	 * FIXME FOR DEFRAGMENTATION : CODE REVIEW IS REQUIRED
	 *
	 * Turn off MAPPED flag in victim's bh if defrag on.
	 * Another write_begin can starts after get_block for defrag victims
	 * called.
	 * In this case, write_begin calls get_block and get original block
	 * number and previous defrag will be canceled.
	 */
	if (unlikely(__check_dfr_on(inode, (loff_t)(page->index << PAGE_SHIFT),
			(loff_t)((page->index + 1) << PAGE_SHIFT), __func__))) {
		struct buffer_head *head = page_buffers(page);
		struct buffer_head *bh = head;

		do {
			clear_buffer_mapped(bh);
			bh = bh->b_this_page;
		} while (bh != head);
	}

	unlock_page(page);
	if (boundary || (first_unmapped != blocks_per_page)) {
		bio = mpage_bio_submit_write(op_flags, bio);
		if (boundary_block) {
			__write_boundary_block(boundary_bdev,
					boundary_block, 1 << blkbits);
		}
	} else {
		mpd->last_block_in_bio = blocks[blocks_per_page - 1];
	}

	goto out;

confused:
	if (bio)
		bio = mpage_bio_submit_write(op_flags, bio);

	if (mpd->use_writepage) {
		ret = mapping->a_ops->writepage(page, wbc);
	} else {
		ret = -EAGAIN;
		goto out;
	}
	/*
	 * The caller has a ref on the inode, so *mapping is stable
	 */
	mapping_set_error(mapping, ret);
out:
	mpd->bio = bio;
	return ret;
}

int sdfat_mpage_writepages(struct address_space *mapping,
			struct writeback_control *wbc, get_block_t *get_block)
{
	struct blk_plug plug;
	int ret;
	struct mpage_data mpd = {
		.bio = NULL,
		.last_block_in_bio = 0,
		.get_block = get_block,
		.use_writepage = 1,
		.size_to_align = __calc_size_to_align(mapping->host->i_sb),
	};

	BUG_ON(!get_block);
	blk_start_plug(&plug);
	ret = write_cache_pages(mapping, wbc, sdfat_mpage_writepage, &mpd);
	if (mpd.bio) {
		int op_flags = wbc_to_write_flags(wbc);

		mpage_bio_submit_write(op_flags, mpd.bio);
	}
	blk_finish_plug(&plug);
	return ret;
}

#endif /* CONFIG_SDFAT_ALIGNED_MPAGE_WRITE */

