/*
 * GPL HEADER START
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 only,
 * as published by the Free Software Foundation.
 *
 * 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 version 2 for more details (a copy is included
 * in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU General Public License
 * version 2 along with this program; If not, see
 * http://www.sun.com/software/products/lustre/docs/GPLv2.pdf
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 *
 * GPL HEADER END
 */
/*
 * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
 * Use is subject to license terms.
 *
 * Copyright (c) 2011, 2012, Intel Corporation.
 */
/*
 * This file is part of Lustre, http://www.lustre.org/
 * Lustre is a trademark of Sun Microsystems, Inc.
 *
 * lustre/llite/rw.c
 *
 * Lustre Lite I/O page cache routines shared by different kernel revs
 */

#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/string.h>
#include <linux/stat.h>
#include <linux/errno.h>
#include <linux/unistd.h>
#include <linux/writeback.h>
#include <linux/uaccess.h>

#include <linux/fs.h>
#include <linux/pagemap.h>
/* current_is_kswapd() */
#include <linux/swap.h>

#define DEBUG_SUBSYSTEM S_LLITE

#include "../include/lustre_lite.h"
#include "../include/obd_cksum.h"
#include "llite_internal.h"
#include "../include/linux/lustre_compat25.h"

/**
 * Finalizes cl-data before exiting typical address_space operation. Dual to
 * ll_cl_init().
 */
static void ll_cl_fini(struct ll_cl_context *lcc)
{
	struct lu_env  *env  = lcc->lcc_env;
	struct cl_io   *io   = lcc->lcc_io;
	struct cl_page *page = lcc->lcc_page;

	LASSERT(lcc->lcc_cookie == current);
	LASSERT(env != NULL);

	if (page != NULL) {
		lu_ref_del(&page->cp_reference, "cl_io", io);
		cl_page_put(env, page);
	}

	cl_env_put(env, &lcc->lcc_refcheck);
}

/**
 * Initializes common cl-data at the typical address_space operation entry
 * point.
 */
static struct ll_cl_context *ll_cl_init(struct file *file,
					struct page *vmpage, int create)
{
	struct ll_cl_context *lcc;
	struct lu_env    *env;
	struct cl_io     *io;
	struct cl_object *clob;
	struct ccc_io    *cio;

	int refcheck;
	int result = 0;

	clob = ll_i2info(vmpage->mapping->host)->lli_clob;
	LASSERT(clob != NULL);

	env = cl_env_get(&refcheck);
	if (IS_ERR(env))
		return ERR_CAST(env);

	lcc = &vvp_env_info(env)->vti_io_ctx;
	memset(lcc, 0, sizeof(*lcc));
	lcc->lcc_env = env;
	lcc->lcc_refcheck = refcheck;
	lcc->lcc_cookie = current;

	cio = ccc_env_io(env);
	io = cio->cui_cl.cis_io;
	if (io == NULL && create) {
		struct inode *inode = vmpage->mapping->host;
		loff_t pos;

		if (mutex_trylock(&inode->i_mutex)) {
			mutex_unlock(&(inode)->i_mutex);

			/* this is too bad. Someone is trying to write the
			 * page w/o holding inode mutex. This means we can
			 * add dirty pages into cache during truncate */
			CERROR("Proc %s is dirtying page w/o inode lock, this will break truncate\n",
			       current->comm);
			dump_stack();
			LBUG();
			return ERR_PTR(-EIO);
		}

		/*
		 * Loop-back driver calls ->prepare_write().
		 * methods directly, bypassing file system ->write() operation,
		 * so cl_io has to be created here.
		 */
		io = ccc_env_thread_io(env);
		ll_io_init(io, file, 1);

		/* No lock at all for this kind of IO - we can't do it because
		 * we have held page lock, it would cause deadlock.
		 * XXX: This causes poor performance to loop device - One page
		 *      per RPC.
		 *      In order to get better performance, users should use
		 *      lloop driver instead.
		 */
		io->ci_lockreq = CILR_NEVER;

		pos = vmpage->index << PAGE_CACHE_SHIFT;

		/* Create a temp IO to serve write. */
		result = cl_io_rw_init(env, io, CIT_WRITE, pos, PAGE_CACHE_SIZE);
		if (result == 0) {
			cio->cui_fd = LUSTRE_FPRIVATE(file);
			cio->cui_iter = NULL;
			result = cl_io_iter_init(env, io);
			if (result == 0) {
				result = cl_io_lock(env, io);
				if (result == 0)
					result = cl_io_start(env, io);
			}
		} else
			result = io->ci_result;
	}

	lcc->lcc_io = io;
	if (io == NULL)
		result = -EIO;
	if (result == 0) {
		struct cl_page   *page;

		LASSERT(io != NULL);
		LASSERT(io->ci_state == CIS_IO_GOING);
		LASSERT(cio->cui_fd == LUSTRE_FPRIVATE(file));
		page = cl_page_find(env, clob, vmpage->index, vmpage,
				    CPT_CACHEABLE);
		if (!IS_ERR(page)) {
			lcc->lcc_page = page;
			lu_ref_add(&page->cp_reference, "cl_io", io);
			result = 0;
		} else
			result = PTR_ERR(page);
	}
	if (result) {
		ll_cl_fini(lcc);
		lcc = ERR_PTR(result);
	}

	CDEBUG(D_VFSTRACE, "%lu@"DFID" -> %d %p %p\n",
	       vmpage->index, PFID(lu_object_fid(&clob->co_lu)), result,
	       env, io);
	return lcc;
}

static struct ll_cl_context *ll_cl_get(void)
{
	struct ll_cl_context *lcc;
	struct lu_env *env;
	int refcheck;

	env = cl_env_get(&refcheck);
	LASSERT(!IS_ERR(env));
	lcc = &vvp_env_info(env)->vti_io_ctx;
	LASSERT(env == lcc->lcc_env);
	LASSERT(current == lcc->lcc_cookie);
	cl_env_put(env, &refcheck);

	/* env has got in ll_cl_init, so it is still usable. */
	return lcc;
}

/**
 * ->prepare_write() address space operation called by generic_file_write()
 * for every page during write.
 */
int ll_prepare_write(struct file *file, struct page *vmpage, unsigned from,
		     unsigned to)
{
	struct ll_cl_context *lcc;
	int result;

	lcc = ll_cl_init(file, vmpage, 1);
	if (!IS_ERR(lcc)) {
		struct lu_env  *env = lcc->lcc_env;
		struct cl_io   *io  = lcc->lcc_io;
		struct cl_page *page = lcc->lcc_page;

		cl_page_assume(env, io, page);

		result = cl_io_prepare_write(env, io, page, from, to);
		if (result == 0) {
			/*
			 * Add a reference, so that page is not evicted from
			 * the cache until ->commit_write() is called.
			 */
			cl_page_get(page);
			lu_ref_add(&page->cp_reference, "prepare_write",
				   current);
		} else {
			cl_page_unassume(env, io, page);
			ll_cl_fini(lcc);
		}
		/* returning 0 in prepare assumes commit must be called
		 * afterwards */
	} else {
		result = PTR_ERR(lcc);
	}
	return result;
}

int ll_commit_write(struct file *file, struct page *vmpage, unsigned from,
		    unsigned to)
{
	struct ll_cl_context *lcc;
	struct lu_env    *env;
	struct cl_io     *io;
	struct cl_page   *page;
	int result = 0;

	lcc  = ll_cl_get();
	env  = lcc->lcc_env;
	page = lcc->lcc_page;
	io   = lcc->lcc_io;

	LASSERT(cl_page_is_owned(page, io));
	LASSERT(from <= to);
	if (from != to) /* handle short write case. */
		result = cl_io_commit_write(env, io, page, from, to);
	if (cl_page_is_owned(page, io))
		cl_page_unassume(env, io, page);

	/*
	 * Release reference acquired by ll_prepare_write().
	 */
	lu_ref_del(&page->cp_reference, "prepare_write", current);
	cl_page_put(env, page);
	ll_cl_fini(lcc);
	return result;
}

struct obd_capa *cl_capa_lookup(struct inode *inode, enum cl_req_type crt)
{
	__u64 opc;

	opc = crt == CRT_WRITE ? CAPA_OPC_OSS_WRITE : CAPA_OPC_OSS_RW;
	return ll_osscapa_get(inode, opc);
}

static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which);

/**
 * Get readahead pages from the filesystem readahead pool of the client for a
 * thread.
 *
 * /param sbi superblock for filesystem readahead state ll_ra_info
 * /param ria per-thread readahead state
 * /param pages number of pages requested for readahead for the thread.
 *
 * WARNING: This algorithm is used to reduce contention on sbi->ll_lock.
 * It should work well if the ra_max_pages is much greater than the single
 * file's read-ahead window, and not too many threads contending for
 * these readahead pages.
 *
 * TODO: There may be a 'global sync problem' if many threads are trying
 * to get an ra budget that is larger than the remaining readahead pages
 * and reach here at exactly the same time. They will compute /a ret to
 * consume the remaining pages, but will fail at atomic_add_return() and
 * get a zero ra window, although there is still ra space remaining. - Jay */

static unsigned long ll_ra_count_get(struct ll_sb_info *sbi,
				     struct ra_io_arg *ria,
				     unsigned long pages)
{
	struct ll_ra_info *ra = &sbi->ll_ra_info;
	long ret;

	/* If read-ahead pages left are less than 1M, do not do read-ahead,
	 * otherwise it will form small read RPC(< 1M), which hurt server
	 * performance a lot. */
	ret = min(ra->ra_max_pages - atomic_read(&ra->ra_cur_pages), pages);
	if (ret < 0 || ret < min_t(long, PTLRPC_MAX_BRW_PAGES, pages)) {
		ret = 0;
		goto out;
	}

	/* If the non-strided (ria_pages == 0) readahead window
	 * (ria_start + ret) has grown across an RPC boundary, then trim
	 * readahead size by the amount beyond the RPC so it ends on an
	 * RPC boundary. If the readahead window is already ending on
	 * an RPC boundary (beyond_rpc == 0), or smaller than a full
	 * RPC (beyond_rpc < ret) the readahead size is unchanged.
	 * The (beyond_rpc != 0) check is skipped since the conditional
	 * branch is more expensive than subtracting zero from the result.
	 *
	 * Strided read is left unaligned to avoid small fragments beyond
	 * the RPC boundary from needing an extra read RPC. */
	if (ria->ria_pages == 0) {
		long beyond_rpc = (ria->ria_start + ret) % PTLRPC_MAX_BRW_PAGES;
		if (/* beyond_rpc != 0 && */ beyond_rpc < ret)
			ret -= beyond_rpc;
	}

	if (atomic_add_return(ret, &ra->ra_cur_pages) > ra->ra_max_pages) {
		atomic_sub(ret, &ra->ra_cur_pages);
		ret = 0;
	}

out:
	return ret;
}

void ll_ra_count_put(struct ll_sb_info *sbi, unsigned long len)
{
	struct ll_ra_info *ra = &sbi->ll_ra_info;
	atomic_sub(len, &ra->ra_cur_pages);
}

static void ll_ra_stats_inc_sbi(struct ll_sb_info *sbi, enum ra_stat which)
{
	LASSERTF(which >= 0 && which < _NR_RA_STAT, "which: %u\n", which);
	lprocfs_counter_incr(sbi->ll_ra_stats, which);
}

void ll_ra_stats_inc(struct address_space *mapping, enum ra_stat which)
{
	struct ll_sb_info *sbi = ll_i2sbi(mapping->host);
	ll_ra_stats_inc_sbi(sbi, which);
}

#define RAS_CDEBUG(ras) \
	CDEBUG(D_READA,						      \
	       "lrp %lu cr %lu cp %lu ws %lu wl %lu nra %lu r %lu ri %lu"    \
	       "csr %lu sf %lu sp %lu sl %lu \n",			    \
	       ras->ras_last_readpage, ras->ras_consecutive_requests,	\
	       ras->ras_consecutive_pages, ras->ras_window_start,	    \
	       ras->ras_window_len, ras->ras_next_readahead,		 \
	       ras->ras_requests, ras->ras_request_index,		    \
	       ras->ras_consecutive_stride_requests, ras->ras_stride_offset, \
	       ras->ras_stride_pages, ras->ras_stride_length)

static int index_in_window(unsigned long index, unsigned long point,
			   unsigned long before, unsigned long after)
{
	unsigned long start = point - before, end = point + after;

	if (start > point)
	       start = 0;
	if (end < point)
	       end = ~0;

	return start <= index && index <= end;
}

static struct ll_readahead_state *ll_ras_get(struct file *f)
{
	struct ll_file_data       *fd;

	fd = LUSTRE_FPRIVATE(f);
	return &fd->fd_ras;
}

void ll_ra_read_in(struct file *f, struct ll_ra_read *rar)
{
	struct ll_readahead_state *ras;

	ras = ll_ras_get(f);

	spin_lock(&ras->ras_lock);
	ras->ras_requests++;
	ras->ras_request_index = 0;
	ras->ras_consecutive_requests++;
	rar->lrr_reader = current;

	list_add(&rar->lrr_linkage, &ras->ras_read_beads);
	spin_unlock(&ras->ras_lock);
}

void ll_ra_read_ex(struct file *f, struct ll_ra_read *rar)
{
	struct ll_readahead_state *ras;

	ras = ll_ras_get(f);

	spin_lock(&ras->ras_lock);
	list_del_init(&rar->lrr_linkage);
	spin_unlock(&ras->ras_lock);
}

static struct ll_ra_read *ll_ra_read_get_locked(struct ll_readahead_state *ras)
{
	struct ll_ra_read *scan;

	list_for_each_entry(scan, &ras->ras_read_beads, lrr_linkage) {
		if (scan->lrr_reader == current)
			return scan;
	}
	return NULL;
}

struct ll_ra_read *ll_ra_read_get(struct file *f)
{
	struct ll_readahead_state *ras;
	struct ll_ra_read	 *bead;

	ras = ll_ras_get(f);

	spin_lock(&ras->ras_lock);
	bead = ll_ra_read_get_locked(ras);
	spin_unlock(&ras->ras_lock);
	return bead;
}

static int cl_read_ahead_page(const struct lu_env *env, struct cl_io *io,
			      struct cl_page_list *queue, struct cl_page *page,
			      struct page *vmpage)
{
	struct ccc_page *cp;
	int	      rc;

	rc = 0;
	cl_page_assume(env, io, page);
	lu_ref_add(&page->cp_reference, "ra", current);
	cp = cl2ccc_page(cl_page_at(page, &vvp_device_type));
	if (!cp->cpg_defer_uptodate && !PageUptodate(vmpage)) {
		rc = cl_page_is_under_lock(env, io, page);
		if (rc == -EBUSY) {
			cp->cpg_defer_uptodate = 1;
			cp->cpg_ra_used = 0;
			cl_page_list_add(queue, page);
			rc = 1;
		} else {
			cl_page_delete(env, page);
			rc = -ENOLCK;
		}
	} else {
		/* skip completed pages */
		cl_page_unassume(env, io, page);
	}
	lu_ref_del(&page->cp_reference, "ra", current);
	cl_page_put(env, page);
	return rc;
}

/**
 * Initiates read-ahead of a page with given index.
 *
 * \retval     +ve: page was added to \a queue.
 *
 * \retval -ENOLCK: there is no extent lock for this part of a file, stop
 *		  read-ahead.
 *
 * \retval  -ve, 0: page wasn't added to \a queue for other reason.
 */
static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io,
			      struct cl_page_list *queue,
			      pgoff_t index, struct address_space *mapping)
{
	struct page      *vmpage;
	struct cl_object *clob  = ll_i2info(mapping->host)->lli_clob;
	struct cl_page   *page;
	enum ra_stat      which = _NR_RA_STAT; /* keep gcc happy */
	int	       rc    = 0;
	const char       *msg   = NULL;

	vmpage = grab_cache_page_nowait(mapping, index);
	if (vmpage != NULL) {
		/* Check if vmpage was truncated or reclaimed */
		if (vmpage->mapping == mapping) {
			page = cl_page_find(env, clob, vmpage->index,
					    vmpage, CPT_CACHEABLE);
			if (!IS_ERR(page)) {
				rc = cl_read_ahead_page(env, io, queue,
							page, vmpage);
				if (rc == -ENOLCK) {
					which = RA_STAT_FAILED_MATCH;
					msg   = "lock match failed";
				}
			} else {
				which = RA_STAT_FAILED_GRAB_PAGE;
				msg   = "cl_page_find failed";
			}
		} else {
			which = RA_STAT_WRONG_GRAB_PAGE;
			msg   = "g_c_p_n returned invalid page";
		}
		if (rc != 1)
			unlock_page(vmpage);
		page_cache_release(vmpage);
	} else {
		which = RA_STAT_FAILED_GRAB_PAGE;
		msg   = "g_c_p_n failed";
	}
	if (msg != NULL) {
		ll_ra_stats_inc(mapping, which);
		CDEBUG(D_READA, "%s\n", msg);
	}
	return rc;
}

#define RIA_DEBUG(ria)						       \
	CDEBUG(D_READA, "rs %lu re %lu ro %lu rl %lu rp %lu\n",       \
	ria->ria_start, ria->ria_end, ria->ria_stoff, ria->ria_length,\
	ria->ria_pages)

/* Limit this to the blocksize instead of PTLRPC_BRW_MAX_SIZE, since we don't
 * know what the actual RPC size is.  If this needs to change, it makes more
 * sense to tune the i_blkbits value for the file based on the OSTs it is
 * striped over, rather than having a constant value for all files here. */

/* RAS_INCREASE_STEP should be (1UL << (inode->i_blkbits - PAGE_CACHE_SHIFT)).
 * Temporarily set RAS_INCREASE_STEP to 1MB. After 4MB RPC is enabled
 * by default, this should be adjusted corresponding with max_read_ahead_mb
 * and max_read_ahead_per_file_mb otherwise the readahead budget can be used
 * up quickly which will affect read performance significantly. See LU-2816 */
#define RAS_INCREASE_STEP(inode) (ONE_MB_BRW_SIZE >> PAGE_CACHE_SHIFT)

static inline int stride_io_mode(struct ll_readahead_state *ras)
{
	return ras->ras_consecutive_stride_requests > 1;
}
/* The function calculates how much pages will be read in
 * [off, off + length], in such stride IO area,
 * stride_offset = st_off, stride_length = st_len,
 * stride_pages = st_pgs
 *
 *   |------------------|*****|------------------|*****|------------|*****|....
 * st_off
 *   |--- st_pgs     ---|
 *   |-----     st_len   -----|
 *
 *	      How many pages it should read in such pattern
 *	      |-------------------------------------------------------------|
 *	      off
 *	      |<------		  length		      ------->|
 *
 *	  =   |<----->|  +  |-------------------------------------| +   |---|
 *	     start_left		 st_pgs * i		    end_left
 */
static unsigned long
stride_pg_count(pgoff_t st_off, unsigned long st_len, unsigned long st_pgs,
		unsigned long off, unsigned long length)
{
	__u64 start = off > st_off ? off - st_off : 0;
	__u64 end = off + length > st_off ? off + length - st_off : 0;
	unsigned long start_left = 0;
	unsigned long end_left = 0;
	unsigned long pg_count;

	if (st_len == 0 || length == 0 || end == 0)
		return length;

	start_left = do_div(start, st_len);
	if (start_left < st_pgs)
		start_left = st_pgs - start_left;
	else
		start_left = 0;

	end_left = do_div(end, st_len);
	if (end_left > st_pgs)
		end_left = st_pgs;

	CDEBUG(D_READA, "start %llu, end %llu start_left %lu end_left %lu \n",
	       start, end, start_left, end_left);

	if (start == end)
		pg_count = end_left - (st_pgs - start_left);
	else
		pg_count = start_left + st_pgs * (end - start - 1) + end_left;

	CDEBUG(D_READA, "st_off %lu, st_len %lu st_pgs %lu off %lu length %lu pgcount %lu\n",
	       st_off, st_len, st_pgs, off, length, pg_count);

	return pg_count;
}

static int ria_page_count(struct ra_io_arg *ria)
{
	__u64 length = ria->ria_end >= ria->ria_start ?
		       ria->ria_end - ria->ria_start + 1 : 0;

	return stride_pg_count(ria->ria_stoff, ria->ria_length,
			       ria->ria_pages, ria->ria_start,
			       length);
}

/*Check whether the index is in the defined ra-window */
static int ras_inside_ra_window(unsigned long idx, struct ra_io_arg *ria)
{
	/* If ria_length == ria_pages, it means non-stride I/O mode,
	 * idx should always inside read-ahead window in this case
	 * For stride I/O mode, just check whether the idx is inside
	 * the ria_pages. */
	return ria->ria_length == 0 || ria->ria_length == ria->ria_pages ||
	       (idx >= ria->ria_stoff && (idx - ria->ria_stoff) %
		ria->ria_length < ria->ria_pages);
}

static int ll_read_ahead_pages(const struct lu_env *env,
			       struct cl_io *io, struct cl_page_list *queue,
			       struct ra_io_arg *ria,
			       unsigned long *reserved_pages,
			       struct address_space *mapping,
			       unsigned long *ra_end)
{
	int rc, count = 0, stride_ria;
	unsigned long page_idx;

	LASSERT(ria != NULL);
	RIA_DEBUG(ria);

	stride_ria = ria->ria_length > ria->ria_pages && ria->ria_pages > 0;
	for (page_idx = ria->ria_start; page_idx <= ria->ria_end &&
			*reserved_pages > 0; page_idx++) {
		if (ras_inside_ra_window(page_idx, ria)) {
			/* If the page is inside the read-ahead window*/
			rc = ll_read_ahead_page(env, io, queue,
						page_idx, mapping);
			if (rc == 1) {
				(*reserved_pages)--;
				count ++;
			} else if (rc == -ENOLCK)
				break;
		} else if (stride_ria) {
			/* If it is not in the read-ahead window, and it is
			 * read-ahead mode, then check whether it should skip
			 * the stride gap */
			pgoff_t offset;
			/* FIXME: This assertion only is valid when it is for
			 * forward read-ahead, it will be fixed when backward
			 * read-ahead is implemented */
			LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu rs %lu re %lu ro %lu rl %lu rp %lu\n",
				 page_idx,
				 ria->ria_start, ria->ria_end, ria->ria_stoff,
				 ria->ria_length, ria->ria_pages);
			offset = page_idx - ria->ria_stoff;
			offset = offset % (ria->ria_length);
			if (offset > ria->ria_pages) {
				page_idx += ria->ria_length - offset;
				CDEBUG(D_READA, "i %lu skip %lu \n", page_idx,
				       ria->ria_length - offset);
				continue;
			}
		}
	}
	*ra_end = page_idx;
	return count;
}

int ll_readahead(const struct lu_env *env, struct cl_io *io,
		 struct ll_readahead_state *ras, struct address_space *mapping,
		 struct cl_page_list *queue, int flags)
{
	struct vvp_io *vio = vvp_env_io(env);
	struct vvp_thread_info *vti = vvp_env_info(env);
	struct cl_attr *attr = ccc_env_thread_attr(env);
	unsigned long start = 0, end = 0, reserved;
	unsigned long ra_end, len;
	struct inode *inode;
	struct ll_ra_read *bead;
	struct ra_io_arg *ria = &vti->vti_ria;
	struct ll_inode_info *lli;
	struct cl_object *clob;
	int ret = 0;
	__u64 kms;

	inode = mapping->host;
	lli = ll_i2info(inode);
	clob = lli->lli_clob;

	memset(ria, 0, sizeof(*ria));

	cl_object_attr_lock(clob);
	ret = cl_object_attr_get(env, clob, attr);
	cl_object_attr_unlock(clob);

	if (ret != 0)
		return ret;
	kms = attr->cat_kms;
	if (kms == 0) {
		ll_ra_stats_inc(mapping, RA_STAT_ZERO_LEN);
		return 0;
	}

	spin_lock(&ras->ras_lock);
	if (vio->cui_ra_window_set)
		bead = &vio->cui_bead;
	else
		bead = NULL;

	/* Enlarge the RA window to encompass the full read */
	if (bead != NULL && ras->ras_window_start + ras->ras_window_len <
	    bead->lrr_start + bead->lrr_count) {
		ras->ras_window_len = bead->lrr_start + bead->lrr_count -
				      ras->ras_window_start;
	}
	/* Reserve a part of the read-ahead window that we'll be issuing */
	if (ras->ras_window_len) {
		start = ras->ras_next_readahead;
		end = ras->ras_window_start + ras->ras_window_len - 1;
	}
	if (end != 0) {
		unsigned long rpc_boundary;
		/*
		 * Align RA window to an optimal boundary.
		 *
		 * XXX This would be better to align to cl_max_pages_per_rpc
		 * instead of PTLRPC_MAX_BRW_PAGES, because the RPC size may
		 * be aligned to the RAID stripe size in the future and that
		 * is more important than the RPC size.
		 */
		/* Note: we only trim the RPC, instead of extending the RPC
		 * to the boundary, so to avoid reading too much pages during
		 * random reading. */
		rpc_boundary = (end + 1) & (~(PTLRPC_MAX_BRW_PAGES - 1));
		if (rpc_boundary > 0)
			rpc_boundary--;

		if (rpc_boundary  > start)
			end = rpc_boundary;

		/* Truncate RA window to end of file */
		end = min(end, (unsigned long)((kms - 1) >> PAGE_CACHE_SHIFT));

		ras->ras_next_readahead = max(end, end + 1);
		RAS_CDEBUG(ras);
	}
	ria->ria_start = start;
	ria->ria_end = end;
	/* If stride I/O mode is detected, get stride window*/
	if (stride_io_mode(ras)) {
		ria->ria_stoff = ras->ras_stride_offset;
		ria->ria_length = ras->ras_stride_length;
		ria->ria_pages = ras->ras_stride_pages;
	}
	spin_unlock(&ras->ras_lock);

	if (end == 0) {
		ll_ra_stats_inc(mapping, RA_STAT_ZERO_WINDOW);
		return 0;
	}
	len = ria_page_count(ria);
	if (len == 0)
		return 0;

	reserved = ll_ra_count_get(ll_i2sbi(inode), ria, len);
	if (reserved < len)
		ll_ra_stats_inc(mapping, RA_STAT_MAX_IN_FLIGHT);

	CDEBUG(D_READA, "reserved page %lu ra_cur %d ra_max %lu\n", reserved,
	       atomic_read(&ll_i2sbi(inode)->ll_ra_info.ra_cur_pages),
	       ll_i2sbi(inode)->ll_ra_info.ra_max_pages);

	ret = ll_read_ahead_pages(env, io, queue,
				  ria, &reserved, mapping, &ra_end);

	LASSERTF(reserved >= 0, "reserved %lu\n", reserved);
	if (reserved != 0)
		ll_ra_count_put(ll_i2sbi(inode), reserved);

	if (ra_end == end + 1 && ra_end == (kms >> PAGE_CACHE_SHIFT))
		ll_ra_stats_inc(mapping, RA_STAT_EOF);

	/* if we didn't get to the end of the region we reserved from
	 * the ras we need to go back and update the ras so that the
	 * next read-ahead tries from where we left off.  we only do so
	 * if the region we failed to issue read-ahead on is still ahead
	 * of the app and behind the next index to start read-ahead from */
	CDEBUG(D_READA, "ra_end %lu end %lu stride end %lu \n",
	       ra_end, end, ria->ria_end);

	if (ra_end != end + 1) {
		spin_lock(&ras->ras_lock);
		if (ra_end < ras->ras_next_readahead &&
		    index_in_window(ra_end, ras->ras_window_start, 0,
				    ras->ras_window_len)) {
			ras->ras_next_readahead = ra_end;
			RAS_CDEBUG(ras);
		}
		spin_unlock(&ras->ras_lock);
	}

	return ret;
}

static void ras_set_start(struct inode *inode, struct ll_readahead_state *ras,
			  unsigned long index)
{
	ras->ras_window_start = index & (~(RAS_INCREASE_STEP(inode) - 1));
}

/* called with the ras_lock held or from places where it doesn't matter */
static void ras_reset(struct inode *inode, struct ll_readahead_state *ras,
		      unsigned long index)
{
	ras->ras_last_readpage = index;
	ras->ras_consecutive_requests = 0;
	ras->ras_consecutive_pages = 0;
	ras->ras_window_len = 0;
	ras_set_start(inode, ras, index);
	ras->ras_next_readahead = max(ras->ras_window_start, index);

	RAS_CDEBUG(ras);
}

/* called with the ras_lock held or from places where it doesn't matter */
static void ras_stride_reset(struct ll_readahead_state *ras)
{
	ras->ras_consecutive_stride_requests = 0;
	ras->ras_stride_length = 0;
	ras->ras_stride_pages = 0;
	RAS_CDEBUG(ras);
}

void ll_readahead_init(struct inode *inode, struct ll_readahead_state *ras)
{
	spin_lock_init(&ras->ras_lock);
	ras_reset(inode, ras, 0);
	ras->ras_requests = 0;
	INIT_LIST_HEAD(&ras->ras_read_beads);
}

/*
 * Check whether the read request is in the stride window.
 * If it is in the stride window, return 1, otherwise return 0.
 */
static int index_in_stride_window(struct ll_readahead_state *ras,
				  unsigned long index)
{
	unsigned long stride_gap;

	if (ras->ras_stride_length == 0 || ras->ras_stride_pages == 0 ||
	    ras->ras_stride_pages == ras->ras_stride_length)
		return 0;

	stride_gap = index - ras->ras_last_readpage - 1;

	/* If it is contiguous read */
	if (stride_gap == 0)
		return ras->ras_consecutive_pages + 1 <= ras->ras_stride_pages;

	/* Otherwise check the stride by itself */
	return (ras->ras_stride_length - ras->ras_stride_pages) == stride_gap &&
		ras->ras_consecutive_pages == ras->ras_stride_pages;
}

static void ras_update_stride_detector(struct ll_readahead_state *ras,
				       unsigned long index)
{
	unsigned long stride_gap = index - ras->ras_last_readpage - 1;

	if (!stride_io_mode(ras) && (stride_gap != 0 ||
	     ras->ras_consecutive_stride_requests == 0)) {
		ras->ras_stride_pages = ras->ras_consecutive_pages;
		ras->ras_stride_length = stride_gap +ras->ras_consecutive_pages;
	}
	LASSERT(ras->ras_request_index == 0);
	LASSERT(ras->ras_consecutive_stride_requests == 0);

	if (index <= ras->ras_last_readpage) {
		/*Reset stride window for forward read*/
		ras_stride_reset(ras);
		return;
	}

	ras->ras_stride_pages = ras->ras_consecutive_pages;
	ras->ras_stride_length = stride_gap +ras->ras_consecutive_pages;

	RAS_CDEBUG(ras);
	return;
}

static unsigned long
stride_page_count(struct ll_readahead_state *ras, unsigned long len)
{
	return stride_pg_count(ras->ras_stride_offset, ras->ras_stride_length,
			       ras->ras_stride_pages, ras->ras_stride_offset,
			       len);
}

/* Stride Read-ahead window will be increased inc_len according to
 * stride I/O pattern */
static void ras_stride_increase_window(struct ll_readahead_state *ras,
				       struct ll_ra_info *ra,
				       unsigned long inc_len)
{
	unsigned long left, step, window_len;
	unsigned long stride_len;

	LASSERT(ras->ras_stride_length > 0);
	LASSERTF(ras->ras_window_start + ras->ras_window_len
		 >= ras->ras_stride_offset, "window_start %lu, window_len %lu stride_offset %lu\n",
		 ras->ras_window_start,
		 ras->ras_window_len, ras->ras_stride_offset);

	stride_len = ras->ras_window_start + ras->ras_window_len -
		     ras->ras_stride_offset;

	left = stride_len % ras->ras_stride_length;
	window_len = ras->ras_window_len - left;

	if (left < ras->ras_stride_pages)
		left += inc_len;
	else
		left = ras->ras_stride_pages + inc_len;

	LASSERT(ras->ras_stride_pages != 0);

	step = left / ras->ras_stride_pages;
	left %= ras->ras_stride_pages;

	window_len += step * ras->ras_stride_length + left;

	if (stride_page_count(ras, window_len) <= ra->ra_max_pages_per_file)
		ras->ras_window_len = window_len;

	RAS_CDEBUG(ras);
}

static void ras_increase_window(struct inode *inode,
				struct ll_readahead_state *ras,
				struct ll_ra_info *ra)
{
	/* The stretch of ra-window should be aligned with max rpc_size
	 * but current clio architecture does not support retrieve such
	 * information from lower layer. FIXME later
	 */
	if (stride_io_mode(ras))
		ras_stride_increase_window(ras, ra, RAS_INCREASE_STEP(inode));
	else
		ras->ras_window_len = min(ras->ras_window_len +
					  RAS_INCREASE_STEP(inode),
					  ra->ra_max_pages_per_file);
}

void ras_update(struct ll_sb_info *sbi, struct inode *inode,
		struct ll_readahead_state *ras, unsigned long index,
		unsigned hit)
{
	struct ll_ra_info *ra = &sbi->ll_ra_info;
	int zero = 0, stride_detect = 0, ra_miss = 0;

	spin_lock(&ras->ras_lock);

	ll_ra_stats_inc_sbi(sbi, hit ? RA_STAT_HIT : RA_STAT_MISS);

	/* reset the read-ahead window in two cases.  First when the app seeks
	 * or reads to some other part of the file.  Secondly if we get a
	 * read-ahead miss that we think we've previously issued.  This can
	 * be a symptom of there being so many read-ahead pages that the VM is
	 * reclaiming it before we get to it. */
	if (!index_in_window(index, ras->ras_last_readpage, 8, 8)) {
		zero = 1;
		ll_ra_stats_inc_sbi(sbi, RA_STAT_DISTANT_READPAGE);
	} else if (!hit && ras->ras_window_len &&
		   index < ras->ras_next_readahead &&
		   index_in_window(index, ras->ras_window_start, 0,
				   ras->ras_window_len)) {
		ra_miss = 1;
		ll_ra_stats_inc_sbi(sbi, RA_STAT_MISS_IN_WINDOW);
	}

	/* On the second access to a file smaller than the tunable
	 * ra_max_read_ahead_whole_pages trigger RA on all pages in the
	 * file up to ra_max_pages_per_file.  This is simply a best effort
	 * and only occurs once per open file.  Normal RA behavior is reverted
	 * to for subsequent IO.  The mmap case does not increment
	 * ras_requests and thus can never trigger this behavior. */
	if (ras->ras_requests == 2 && !ras->ras_request_index) {
		__u64 kms_pages;

		kms_pages = (i_size_read(inode) + PAGE_CACHE_SIZE - 1) >>
			    PAGE_CACHE_SHIFT;

		CDEBUG(D_READA, "kmsp %llu mwp %lu mp %lu\n", kms_pages,
		       ra->ra_max_read_ahead_whole_pages, ra->ra_max_pages_per_file);

		if (kms_pages &&
		    kms_pages <= ra->ra_max_read_ahead_whole_pages) {
			ras->ras_window_start = 0;
			ras->ras_last_readpage = 0;
			ras->ras_next_readahead = 0;
			ras->ras_window_len = min(ra->ra_max_pages_per_file,
				ra->ra_max_read_ahead_whole_pages);
			goto out_unlock;
		}
	}
	if (zero) {
		/* check whether it is in stride I/O mode*/
		if (!index_in_stride_window(ras, index)) {
			if (ras->ras_consecutive_stride_requests == 0 &&
			    ras->ras_request_index == 0) {
				ras_update_stride_detector(ras, index);
				ras->ras_consecutive_stride_requests++;
			} else {
				ras_stride_reset(ras);
			}
			ras_reset(inode, ras, index);
			ras->ras_consecutive_pages++;
			goto out_unlock;
		} else {
			ras->ras_consecutive_pages = 0;
			ras->ras_consecutive_requests = 0;
			if (++ras->ras_consecutive_stride_requests > 1)
				stride_detect = 1;
			RAS_CDEBUG(ras);
		}
	} else {
		if (ra_miss) {
			if (index_in_stride_window(ras, index) &&
			    stride_io_mode(ras)) {
				/*If stride-RA hit cache miss, the stride dector
				 *will not be reset to avoid the overhead of
				 *redetecting read-ahead mode */
				if (index != ras->ras_last_readpage + 1)
					ras->ras_consecutive_pages = 0;
				ras_reset(inode, ras, index);
				RAS_CDEBUG(ras);
			} else {
				/* Reset both stride window and normal RA
				 * window */
				ras_reset(inode, ras, index);
				ras->ras_consecutive_pages++;
				ras_stride_reset(ras);
				goto out_unlock;
			}
		} else if (stride_io_mode(ras)) {
			/* If this is contiguous read but in stride I/O mode
			 * currently, check whether stride step still is valid,
			 * if invalid, it will reset the stride ra window*/
			if (!index_in_stride_window(ras, index)) {
				/* Shrink stride read-ahead window to be zero */
				ras_stride_reset(ras);
				ras->ras_window_len = 0;
				ras->ras_next_readahead = index;
			}
		}
	}
	ras->ras_consecutive_pages++;
	ras->ras_last_readpage = index;
	ras_set_start(inode, ras, index);

	if (stride_io_mode(ras))
		/* Since stride readahead is sensitive to the offset
		 * of read-ahead, so we use original offset here,
		 * instead of ras_window_start, which is RPC aligned */
		ras->ras_next_readahead = max(index, ras->ras_next_readahead);
	else
		ras->ras_next_readahead = max(ras->ras_window_start,
					      ras->ras_next_readahead);
	RAS_CDEBUG(ras);

	/* Trigger RA in the mmap case where ras_consecutive_requests
	 * is not incremented and thus can't be used to trigger RA */
	if (!ras->ras_window_len && ras->ras_consecutive_pages == 4) {
		ras->ras_window_len = RAS_INCREASE_STEP(inode);
		goto out_unlock;
	}

	/* Initially reset the stride window offset to next_readahead*/
	if (ras->ras_consecutive_stride_requests == 2 && stride_detect) {
		/**
		 * Once stride IO mode is detected, next_readahead should be
		 * reset to make sure next_readahead > stride offset
		 */
		ras->ras_next_readahead = max(index, ras->ras_next_readahead);
		ras->ras_stride_offset = index;
		ras->ras_window_len = RAS_INCREASE_STEP(inode);
	}

	/* The initial ras_window_len is set to the request size.  To avoid
	 * uselessly reading and discarding pages for random IO the window is
	 * only increased once per consecutive request received. */
	if ((ras->ras_consecutive_requests > 1 || stride_detect) &&
	    !ras->ras_request_index)
		ras_increase_window(inode, ras, ra);
out_unlock:
	RAS_CDEBUG(ras);
	ras->ras_request_index++;
	spin_unlock(&ras->ras_lock);
	return;
}

int ll_writepage(struct page *vmpage, struct writeback_control *wbc)
{
	struct inode	       *inode = vmpage->mapping->host;
	struct ll_inode_info   *lli   = ll_i2info(inode);
	struct lu_env	  *env;
	struct cl_io	   *io;
	struct cl_page	 *page;
	struct cl_object       *clob;
	struct cl_env_nest      nest;
	bool redirtied = false;
	bool unlocked = false;
	int result;

	LASSERT(PageLocked(vmpage));
	LASSERT(!PageWriteback(vmpage));

	LASSERT(ll_i2dtexp(inode) != NULL);

	env = cl_env_nested_get(&nest);
	if (IS_ERR(env)) {
		result = PTR_ERR(env);
		goto out;
	}

	clob  = ll_i2info(inode)->lli_clob;
	LASSERT(clob != NULL);

	io = ccc_env_thread_io(env);
	io->ci_obj = clob;
	io->ci_ignore_layout = 1;
	result = cl_io_init(env, io, CIT_MISC, clob);
	if (result == 0) {
		page = cl_page_find(env, clob, vmpage->index,
				    vmpage, CPT_CACHEABLE);
		if (!IS_ERR(page)) {
			lu_ref_add(&page->cp_reference, "writepage",
				   current);
			cl_page_assume(env, io, page);
			result = cl_page_flush(env, io, page);
			if (result != 0) {
				/*
				 * Re-dirty page on error so it retries write,
				 * but not in case when IO has actually
				 * occurred and completed with an error.
				 */
				if (!PageError(vmpage)) {
					redirty_page_for_writepage(wbc, vmpage);
					result = 0;
					redirtied = true;
				}
			}
			cl_page_disown(env, io, page);
			unlocked = true;
			lu_ref_del(&page->cp_reference,
				   "writepage", current);
			cl_page_put(env, page);
		} else {
			result = PTR_ERR(page);
		}
	}
	cl_io_fini(env, io);

	if (redirtied && wbc->sync_mode == WB_SYNC_ALL) {
		loff_t offset = cl_offset(clob, vmpage->index);

		/* Flush page failed because the extent is being written out.
		 * Wait for the write of extent to be finished to avoid
		 * breaking kernel which assumes ->writepage should mark
		 * PageWriteback or clean the page. */
		result = cl_sync_file_range(inode, offset,
					    offset + PAGE_CACHE_SIZE - 1,
					    CL_FSYNC_LOCAL, 1);
		if (result > 0) {
			/* actually we may have written more than one page.
			 * decreasing this page because the caller will count
			 * it. */
			wbc->nr_to_write -= result - 1;
			result = 0;
		}
	}

	cl_env_nested_put(&nest, env);
	goto out;

out:
	if (result < 0) {
		if (!lli->lli_async_rc)
			lli->lli_async_rc = result;
		SetPageError(vmpage);
		if (!unlocked)
			unlock_page(vmpage);
	}
	return result;
}

int ll_writepages(struct address_space *mapping, struct writeback_control *wbc)
{
	struct inode *inode = mapping->host;
	struct ll_sb_info *sbi = ll_i2sbi(inode);
	loff_t start;
	loff_t end;
	enum cl_fsync_mode mode;
	int range_whole = 0;
	int result;
	int ignore_layout = 0;

	if (wbc->range_cyclic) {
		start = mapping->writeback_index << PAGE_CACHE_SHIFT;
		end = OBD_OBJECT_EOF;
	} else {
		start = wbc->range_start;
		end = wbc->range_end;
		if (end == LLONG_MAX) {
			end = OBD_OBJECT_EOF;
			range_whole = start == 0;
		}
	}

	mode = CL_FSYNC_NONE;
	if (wbc->sync_mode == WB_SYNC_ALL)
		mode = CL_FSYNC_LOCAL;

	if (sbi->ll_umounting)
		/* if the mountpoint is being umounted, all pages have to be
		 * evicted to avoid hitting LBUG when truncate_inode_pages()
		 * is called later on. */
		ignore_layout = 1;
	result = cl_sync_file_range(inode, start, end, mode, ignore_layout);
	if (result > 0) {
		wbc->nr_to_write -= result;
		result = 0;
	 }

	if (wbc->range_cyclic || (range_whole && wbc->nr_to_write > 0)) {
		if (end == OBD_OBJECT_EOF)
			end = i_size_read(inode);
		mapping->writeback_index = (end >> PAGE_CACHE_SHIFT) + 1;
	}
	return result;
}

int ll_readpage(struct file *file, struct page *vmpage)
{
	struct ll_cl_context *lcc;
	int result;

	lcc = ll_cl_init(file, vmpage, 0);
	if (!IS_ERR(lcc)) {
		struct lu_env  *env  = lcc->lcc_env;
		struct cl_io   *io   = lcc->lcc_io;
		struct cl_page *page = lcc->lcc_page;

		LASSERT(page->cp_type == CPT_CACHEABLE);
		if (likely(!PageUptodate(vmpage))) {
			cl_page_assume(env, io, page);
			result = cl_io_read_page(env, io, page);
		} else {
			/* Page from a non-object file. */
			unlock_page(vmpage);
			result = 0;
		}
		ll_cl_fini(lcc);
	} else {
		unlock_page(vmpage);
		result = PTR_ERR(lcc);
	}
	return result;
}
