/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
 * Copyright (C) 2004-2005 Red Hat, Inc.  All rights reserved.
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
 * of the GNU General Public License v.2.
 */

#include <linux/sched.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/pagemap.h>
#include <linux/pagevec.h>
#include <linux/mpage.h>
#include <linux/fs.h>
#include <linux/gfs2_ondisk.h>
#include <asm/semaphore.h>

#include "gfs2.h"
#include "lm_interface.h"
#include "incore.h"
#include "bmap.h"
#include "glock.h"
#include "inode.h"
#include "log.h"
#include "meta_io.h"
#include "ops_address.h"
#include "page.h"
#include "quota.h"
#include "trans.h"
#include "rgrp.h"
#include "ops_file.h"
#include "util.h"

/**
 * gfs2_get_block - Fills in a buffer head with details about a block
 * @inode: The inode
 * @lblock: The block number to look up
 * @bh_result: The buffer head to return the result in
 * @create: Non-zero if we may add block to the file
 *
 * Returns: errno
 */

int gfs2_get_block(struct inode *inode, sector_t lblock,
	           struct buffer_head *bh_result, int create)
{
	int new = create;
	uint64_t dblock;
	int error;
	int boundary;

	error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
	if (error)
		return error;

	if (!dblock)
		return 0;

	map_bh(bh_result, inode->i_sb, dblock);
	if (new)
		set_buffer_new(bh_result);
	if (boundary)
		set_buffer_boundary(bh_result);

	return 0;
}

/**
 * get_block_noalloc - Fills in a buffer head with details about a block
 * @inode: The inode
 * @lblock: The block number to look up
 * @bh_result: The buffer head to return the result in
 * @create: Non-zero if we may add block to the file
 *
 * Returns: errno
 */

static int get_block_noalloc(struct inode *inode, sector_t lblock,
			     struct buffer_head *bh_result, int create)
{
	struct gfs2_inode *ip = inode->u.generic_ip;
	int new = 0;
	uint64_t dblock;
	int error;
	int boundary;

	error = gfs2_block_map(inode, lblock, &new, &dblock, &boundary);
	if (error)
		return error;

	if (dblock)
		map_bh(bh_result, inode->i_sb, dblock);
	else if (gfs2_assert_withdraw(ip->i_sbd, !create))
		error = -EIO;
	if (boundary)
		set_buffer_boundary(bh_result);

	return error;
}

/**
 * gfs2_writepage - Write complete page
 * @page: Page to write
 *
 * Returns: errno
 *
 * Some of this is copied from block_write_full_page() although we still
 * call it to do most of the work.
 */

static int gfs2_writepage(struct page *page, struct writeback_control *wbc)
{
	struct inode *inode = page->mapping->host;
	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;
	loff_t i_size = i_size_read(inode);
	pgoff_t end_index = i_size >> PAGE_CACHE_SHIFT;
	unsigned offset;
	int error;
	int done_trans = 0;

	if (gfs2_assert_withdraw(sdp, gfs2_glock_is_held_excl(ip->i_gl))) {
		unlock_page(page);
		return -EIO;
	}
	if (current->journal_info)
		goto out_ignore;

	/* Is the page fully outside i_size? (truncate in progress) */
        offset = i_size & (PAGE_CACHE_SIZE-1);
	if (page->index > end_index || (page->index == end_index && !offset)) {
		page->mapping->a_ops->invalidatepage(page, 0);
		unlock_page(page);
		return 0; /* don't care */
	}

	if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip)) {
		error = gfs2_trans_begin(sdp, RES_DINODE + 1, 0);
		if (error)
			goto out_ignore;
		gfs2_page_add_databufs(ip, page, 0, sdp->sd_vfs->s_blocksize-1);
		done_trans = 1;
	}
	error = block_write_full_page(page, get_block_noalloc, wbc);
	if (done_trans)
		gfs2_trans_end(sdp);
	gfs2_meta_cache_flush(ip);
	return error;

out_ignore:
	redirty_page_for_writepage(wbc, page);
	unlock_page(page);
	return 0;
}

static int zero_readpage(struct page *page)
{
	void *kaddr;

	kaddr = kmap_atomic(page, KM_USER0);
	memset(kaddr, 0, PAGE_CACHE_SIZE);
	kunmap_atomic(page, KM_USER0);

	SetPageUptodate(page);

	return 0;
}

/**
 * stuffed_readpage - Fill in a Linux page with stuffed file data
 * @ip: the inode
 * @page: the page
 *
 * Returns: errno
 */

static int stuffed_readpage(struct gfs2_inode *ip, struct page *page)
{
	struct buffer_head *dibh;
	void *kaddr;
	int error;

	/* Only the first page of a stuffed file might contain data */
	if (unlikely(page->index))
		return zero_readpage(page);

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		return error;

	kaddr = kmap_atomic(page, KM_USER0);
	memcpy(kaddr, dibh->b_data + sizeof(struct gfs2_dinode),
	       ip->i_di.di_size);
	memset(kaddr + ip->i_di.di_size, 0, PAGE_CACHE_SIZE - ip->i_di.di_size);
	kunmap_atomic(page, KM_USER0);

	brelse(dibh);

	SetPageUptodate(page);

	return 0;
}


/**
 * gfs2_readpage - readpage with locking
 * @file: The file to read a page for. N.B. This may be NULL if we are
 * reading an internal file.
 * @page: The page to read
 *
 * Returns: errno
 */

static int gfs2_readpage(struct file *file, struct page *page)
{
	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;
	struct gfs2_holder gh;
	int error;

	if (likely(file != &gfs2_internal_file_sentinal)) {
		gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME|GL_AOP, &gh);
		error = gfs2_glock_nq_m_atime(1, &gh);
		if (unlikely(error))
			goto out_unlock;
	}

	if (gfs2_is_stuffed(ip)) {
		error = stuffed_readpage(ip, page);
		unlock_page(page);
	} else
		error = mpage_readpage(page, gfs2_get_block);

	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		error = -EIO;

	if (file != &gfs2_internal_file_sentinal) {
		gfs2_glock_dq_m(1, &gh);
		gfs2_holder_uninit(&gh);
	}
out:
	return error;
out_unlock:
	unlock_page(page);
	if (file != &gfs2_internal_file_sentinal)
		gfs2_holder_uninit(&gh);
	goto out;
}

#define list_to_page(head) (list_entry((head)->prev, struct page, lru))

/**
 * gfs2_readpages - Read a bunch of pages at once
 *
 * Some notes:
 * 1. This is only for readahead, so we can simply ignore any things
 *    which are slightly inconvenient (such as locking conflicts between
 *    the page lock and the glock) and return having done no I/O. Its
 *    obviously not something we'd want to do on too regular a basis.
 *    Any I/O we ignore at this time will be done via readpage later.
 * 2. We have to handle stuffed files here too.
 * 3. mpage_readpages() does most of the heavy lifting in the common case.
 * 4. gfs2_get_block() is relied upon to set BH_Boundary in the right places.
 * 5. We use LM_FLAG_TRY_1CB here, effectively we then have lock-ahead as
 *    well as read-ahead.
 */
static int gfs2_readpages(struct file *file, struct address_space *mapping,
			  struct list_head *pages, unsigned nr_pages)
{
	struct inode *inode = mapping->host;
	struct gfs2_inode *ip = inode->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;
	struct gfs2_holder gh;
	unsigned page_idx;
	int ret;

	if (likely(file != &gfs2_internal_file_sentinal)) {
		gfs2_holder_init(ip->i_gl, LM_ST_SHARED,
				 LM_FLAG_TRY_1CB|GL_ATIME|GL_AOP, &gh);
		ret = gfs2_glock_nq_m_atime(1, &gh);
		if (ret == GLR_TRYFAILED) 
			goto out_noerror;
		if (unlikely(ret))
			goto out_unlock;
	}

	if (gfs2_is_stuffed(ip)) {
		struct pagevec lru_pvec;
		pagevec_init(&lru_pvec, 0);
		for (page_idx = 0; page_idx < nr_pages; page_idx++) {
			struct page *page = list_to_page(pages);
			list_del(&page->lru);
			if (!add_to_page_cache(page, mapping,
					       page->index, GFP_KERNEL)) {
				ret = stuffed_readpage(ip, page);
				unlock_page(page);
				if (!pagevec_add(&lru_pvec, page))
					 __pagevec_lru_add(&lru_pvec);
			}
			page_cache_release(page);
		}
		pagevec_lru_add(&lru_pvec);
		ret = 0;
	} else {
		/* What we really want to do .... */
		ret = mpage_readpages(mapping, pages, nr_pages, gfs2_get_block);
	}

	if (likely(file != &gfs2_internal_file_sentinal)) {
		gfs2_glock_dq_m(1, &gh);
		gfs2_holder_uninit(&gh);
	}
out:
	if (unlikely(test_bit(SDF_SHUTDOWN, &sdp->sd_flags)))
		ret = -EIO;
	return ret;
out_noerror:
	ret = 0;
out_unlock:
	/* unlock all pages, we can't do any I/O right now */
	for (page_idx = 0; page_idx < nr_pages; page_idx++) {
		struct page *page = list_to_page(pages);
		list_del(&page->lru);
		unlock_page(page);
		page_cache_release(page);
	}
	if (likely(file != &gfs2_internal_file_sentinal))
		gfs2_holder_uninit(&gh);
	goto out;
}

/**
 * gfs2_prepare_write - Prepare to write a page to a file
 * @file: The file to write to
 * @page: The page which is to be prepared for writing
 * @from: From (byte range within page)
 * @to: To (byte range within page)
 *
 * Returns: errno
 */

static int gfs2_prepare_write(struct file *file, struct page *page,
			      unsigned from, unsigned to)
{
	struct gfs2_inode *ip = page->mapping->host->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;
	unsigned int data_blocks, ind_blocks, rblocks;
	int alloc_required;
	int error = 0;
	loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + from;
	loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
	struct gfs2_alloc *al;

	gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|GL_AOP, &ip->i_gh);
	error = gfs2_glock_nq_m_atime(1, &ip->i_gh);
	if (error)
		goto out_uninit;

	gfs2_write_calc_reserv(ip, to - from, &data_blocks, &ind_blocks);

	error = gfs2_write_alloc_required(ip, pos, from - to, &alloc_required);
	if (error)
		goto out_unlock;


	if (alloc_required) {
		al = gfs2_alloc_get(ip);

		error = gfs2_quota_lock(ip, NO_QUOTA_CHANGE, NO_QUOTA_CHANGE);
		if (error)
			goto out_alloc_put;

		error = gfs2_quota_check(ip, ip->i_di.di_uid, ip->i_di.di_gid);
		if (error)
			goto out_qunlock;

		al->al_requested = data_blocks + ind_blocks;
		error = gfs2_inplace_reserve(ip);
		if (error)
			goto out_qunlock;
	}

	rblocks = RES_DINODE + ind_blocks;
	if (gfs2_is_jdata(ip))
		rblocks += data_blocks ? data_blocks : 1;
	if (ind_blocks || data_blocks)
		rblocks += RES_STATFS + RES_QUOTA;

	error = gfs2_trans_begin(sdp, rblocks, 0);
	if (error)
		goto out;

	if (gfs2_is_stuffed(ip)) {
		if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
			error = gfs2_unstuff_dinode(ip, gfs2_unstuffer_page,
						    page);
			if (error == 0)
				goto prepare_write;
		} else if (!PageUptodate(page))
			error = stuffed_readpage(ip, page);
		goto out;
	}

prepare_write:
	error = block_prepare_write(page, from, to, gfs2_get_block);

out:
	if (error) {
		gfs2_trans_end(sdp);
		if (alloc_required) {
			gfs2_inplace_release(ip);
out_qunlock:
			gfs2_quota_unlock(ip);
out_alloc_put:
			gfs2_alloc_put(ip);
		}
out_unlock:
		gfs2_glock_dq_m(1, &ip->i_gh);
out_uninit:
		gfs2_holder_uninit(&ip->i_gh);
	}

	return error;
}

/**
 * gfs2_commit_write - Commit write to a file
 * @file: The file to write to
 * @page: The page containing the data
 * @from: From (byte range within page)
 * @to: To (byte range within page)
 *
 * Returns: errno
 */

static int gfs2_commit_write(struct file *file, struct page *page,
			     unsigned from, unsigned to)
{
	struct inode *inode = page->mapping->host;
	struct gfs2_inode *ip = inode->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;
	int error = -EOPNOTSUPP;
	struct buffer_head *dibh;
	struct gfs2_alloc *al = &ip->i_alloc;;

	if (gfs2_assert_withdraw(sdp, gfs2_glock_is_locked_by_me(ip->i_gl)))
                goto fail_nounlock;

	error = gfs2_meta_inode_buffer(ip, &dibh);
	if (error)
		goto fail_endtrans;

	gfs2_trans_add_bh(ip->i_gl, dibh, 1);

	if (gfs2_is_stuffed(ip)) {
		uint64_t file_size;
		void *kaddr;

		file_size = ((uint64_t)page->index << PAGE_CACHE_SHIFT) + to;

		kaddr = kmap_atomic(page, KM_USER0);
		memcpy(dibh->b_data + sizeof(struct gfs2_dinode) + from,
		       (char *)kaddr + from, to - from);
		kunmap_atomic(page, KM_USER0);

		SetPageUptodate(page);

		if (inode->i_size < file_size)
			i_size_write(inode, file_size);
	} else {
		if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED ||
		    gfs2_is_jdata(ip))
			gfs2_page_add_databufs(ip, page, from, to);
		error = generic_commit_write(file, page, from, to);
		if (error)
			goto fail;
	}

	if (ip->i_di.di_size < inode->i_size)
		ip->i_di.di_size = inode->i_size;

	gfs2_dinode_out(&ip->i_di, dibh->b_data);
	brelse(dibh);
	gfs2_trans_end(sdp);
	if (al->al_requested) {
		gfs2_inplace_release(ip);
		gfs2_quota_unlock(ip);
		gfs2_alloc_put(ip);
	}
	gfs2_glock_dq_m(1, &ip->i_gh);
	gfs2_holder_uninit(&ip->i_gh);
	return 0;

fail:
	brelse(dibh);
fail_endtrans:
	gfs2_trans_end(sdp);
	if (al->al_requested) {
		gfs2_inplace_release(ip);
		gfs2_quota_unlock(ip);
		gfs2_alloc_put(ip);
	}
	gfs2_glock_dq_m(1, &ip->i_gh);
	gfs2_holder_uninit(&ip->i_gh);
fail_nounlock:
	ClearPageUptodate(page);
	return error;
}

/**
 * gfs2_bmap - Block map function
 * @mapping: Address space info
 * @lblock: The block to map
 *
 * Returns: The disk address for the block or 0 on hole or error
 */

static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
{
	struct gfs2_inode *ip = mapping->host->u.generic_ip;
	struct gfs2_holder i_gh;
	sector_t dblock = 0;
	int error;

	error = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, LM_FLAG_ANY, &i_gh);
	if (error)
		return 0;

	if (!gfs2_is_stuffed(ip))
		dblock = generic_block_bmap(mapping, lblock, gfs2_get_block);

	gfs2_glock_dq_uninit(&i_gh);

	return dblock;
}

static void discard_buffer(struct gfs2_sbd *sdp, struct buffer_head *bh)
{
	struct gfs2_bufdata *bd;

	gfs2_log_lock(sdp);
	bd = bh->b_private;
	if (bd) {
		bd->bd_bh = NULL;
		bh->b_private = NULL;
		gfs2_log_unlock(sdp);
		brelse(bh);
	} else
		gfs2_log_unlock(sdp);

	lock_buffer(bh);
	clear_buffer_dirty(bh);
	bh->b_bdev = NULL;
	clear_buffer_mapped(bh);
	clear_buffer_req(bh);
	clear_buffer_new(bh);
	clear_buffer_delay(bh);
	unlock_buffer(bh);
}

static void gfs2_invalidatepage(struct page *page, unsigned long offset)
{
	struct gfs2_sbd *sdp = page->mapping->host->i_sb->s_fs_info;
	struct buffer_head *head, *bh, *next;
	unsigned int curr_off = 0;

	BUG_ON(!PageLocked(page));
	if (!page_has_buffers(page))
		return;

	bh = head = page_buffers(page);
	do {
		unsigned int next_off = curr_off + bh->b_size;
		next = bh->b_this_page;

		if (offset <= curr_off)
			discard_buffer(sdp, bh);

		curr_off = next_off;
		bh = next;
	} while (bh != head);

	if (!offset)
		try_to_release_page(page, 0);

	return;
}

static ssize_t gfs2_direct_IO_write(struct kiocb *iocb, const struct iovec *iov,
				    loff_t offset, unsigned long nr_segs)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file->f_mapping->host;
	struct gfs2_inode *ip = inode->u.generic_ip;
	struct gfs2_holder gh;
	int rv;

	/*
	 * Shared lock, even though its write, since we do no allocation
	 * on this path. All we need change is atime.
	 */
	gfs2_holder_init(ip->i_gl, LM_ST_SHARED, GL_ATIME, &gh);
	rv = gfs2_glock_nq_m_atime(1, &gh);
	if (rv)
		goto out;

	/*
	 * Should we return an error here? I can't see that O_DIRECT for
	 * a journaled file makes any sense. For now we'll silently fall
	 * back to buffered I/O, likewise we do the same for stuffed
	 * files since they are (a) small and (b) unaligned.
	 */
	if (gfs2_is_jdata(ip))
		goto out;

	if (gfs2_is_stuffed(ip))
		goto out;

	rv = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev,
				  iov, offset, nr_segs, gfs2_get_block,
				  NULL, DIO_OWN_LOCKING);
out:
	gfs2_glock_dq_m(1, &gh);
	gfs2_holder_uninit(&gh);

	return rv;
}

/**
 * gfs2_direct_IO
 *
 * This is called with a shared lock already held for the read path.
 * Currently, no locks are held when the write path is called.
 */
static ssize_t gfs2_direct_IO(int rw, struct kiocb *iocb,
			      const struct iovec *iov, loff_t offset,
			      unsigned long nr_segs)
{
	struct file *file = iocb->ki_filp;
	struct inode *inode = file->f_mapping->host;
	struct gfs2_inode *ip = inode->u.generic_ip;
	struct gfs2_sbd *sdp = ip->i_sbd;

	if (rw == WRITE)
		return gfs2_direct_IO_write(iocb, iov, offset, nr_segs);

	if (gfs2_assert_warn(sdp, gfs2_glock_is_locked_by_me(ip->i_gl)) ||
	    gfs2_assert_warn(sdp, !gfs2_is_stuffed(ip)))
		return -EINVAL;

	return __blockdev_direct_IO(READ, iocb, inode, inode->i_sb->s_bdev, iov,
			 	    offset, nr_segs, gfs2_get_block, NULL,
				    DIO_OWN_LOCKING);
}

struct address_space_operations gfs2_file_aops = {
	.writepage = gfs2_writepage,
	.readpage = gfs2_readpage,
	.readpages = gfs2_readpages,
	.sync_page = block_sync_page,
	.prepare_write = gfs2_prepare_write,
	.commit_write = gfs2_commit_write,
	.bmap = gfs2_bmap,
	.invalidatepage = gfs2_invalidatepage,
	.direct_IO = gfs2_direct_IO,
};

