Commit 49a70f27 authored by Trond Myklebust's avatar Trond Myklebust
Browse files

NFS: Cleanup: add common helper nfs_page_length()



Clean up a lot of ad-hoc page length calculations in fs/nfs/write.c

Signed-off-by: default avatarTrond Myklebust <Trond.Myklebust@netapp.com>
parent 277459d2
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -217,3 +217,21 @@ void nfs_super_set_maxbytes(struct super_block *sb, __u64 maxfilesize)
	if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
		sb->s_maxbytes = MAX_LFS_FILESIZE;
}

/*
 * Determine the number of bytes of data the page contains
 */
static inline
unsigned int nfs_page_length(struct page *page)
{
	loff_t i_size = i_size_read(page->mapping->host);

	if (i_size > 0) {
		pgoff_t end_index = (i_size - 1) >> PAGE_CACHE_SHIFT;
		if (page->index < end_index)
			return PAGE_CACHE_SIZE;
		if (page->index == end_index)
			return ((i_size - 1) & ~PAGE_CACHE_MASK) + 1;
	}
	return 0;
}
+3 −18
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@

#include <asm/system.h>

#include "internal.h"
#include "iostat.h"

#define NFSDBG_FACILITY		NFSDBG_PAGECACHE
@@ -83,22 +84,6 @@ void nfs_readdata_release(void *data)
        nfs_readdata_free(data);
}

static
unsigned int nfs_page_length(struct inode *inode, struct page *page)
{
	loff_t i_size = i_size_read(inode);
	unsigned long idx;

	if (i_size <= 0)
		return 0;
	idx = (i_size - 1) >> PAGE_CACHE_SHIFT;
	if (page->index > idx)
		return 0;
	if (page->index != idx)
		return PAGE_CACHE_SIZE;
	return 1 + ((i_size - 1) & (PAGE_CACHE_SIZE - 1));
}

static
int nfs_return_empty_page(struct page *page)
{
@@ -231,7 +216,7 @@ static int nfs_readpage_async(struct nfs_open_context *ctx, struct inode *inode,
	struct nfs_page	*new;
	unsigned int len;

	len = nfs_page_length(inode, page);
	len = nfs_page_length(page);
	if (len == 0)
		return nfs_return_empty_page(page);
	new = nfs_create_request(ctx, inode, page, 0, len);
@@ -667,7 +652,7 @@ readpage_async_filler(void *data, struct page *page)
	unsigned int len;

	nfs_wb_page(inode, page);
	len = nfs_page_length(inode, page);
	len = nfs_page_length(page);
	if (len == 0)
		return nfs_return_empty_page(page);
	new = nfs_create_request(desc->ctx, inode, page, 0, len);
+10 −45
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@
#include <linux/smp_lock.h>

#include "delegation.h"
#include "internal.h"
#include "iostat.h"

#define NFSDBG_FACILITY		NFSDBG_PAGECACHE
@@ -199,31 +200,16 @@ static void nfs_grow_file(struct page *page, unsigned int offset, unsigned int c
 */
static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count)
{
	loff_t end_offs;

	if (PageUptodate(page))
		return;
	if (base != 0)
		return;
	if (count == PAGE_CACHE_SIZE) {
		SetPageUptodate(page);
		return;
	}

	end_offs = i_size_read(page->mapping->host) - 1;
	if (end_offs < 0)
		return;
	/* Is this the last page? */
	if (page->index != (unsigned long)(end_offs >> PAGE_CACHE_SHIFT))
	if (count != nfs_page_length(page))
		return;
	/* This is the last page: set PG_uptodate if we cover the entire
	 * extent of the data, then zero the rest of the page.
	 */
	if (count == (unsigned int)(end_offs & (PAGE_CACHE_SIZE - 1)) + 1) {
	if (count != PAGE_CACHE_SIZE)
		memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count);
	SetPageUptodate(page);
}
}

/*
 * Write a page synchronously.
@@ -330,9 +316,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
{
	struct nfs_open_context *ctx;
	struct inode *inode = page->mapping->host;
	unsigned long end_index;
	unsigned offset = PAGE_CACHE_SIZE;
	loff_t i_size = i_size_read(inode);
	unsigned offset;
	int inode_referenced = 0;
	int priority = wb_priority(wbc);
	int err;
@@ -350,22 +334,15 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
	 */
	if (igrab(inode) != 0)
		inode_referenced = 1;
	end_index = i_size >> PAGE_CACHE_SHIFT;

	/* Ensure we've flushed out any previous writes */
	nfs_wb_page_priority(inode, page, priority);

	/* easy case */
	if (page->index < end_index)
		goto do_it;
	/* things got complicated... */
	offset = i_size & (PAGE_CACHE_SIZE-1);

	/* OK, are we completely out? */
	err = 0; /* potential race with truncate - ignore */
	if (page->index >= end_index+1 || !offset)
	err = 0;
	offset = nfs_page_length(page);
	if (!offset)
		goto out;
do_it:

	ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
	if (ctx == NULL) {
		err = -EBADF;
@@ -826,20 +803,8 @@ int nfs_updatepage(struct file *file, struct page *page,
	 * fragmenting write requests.
	 */
	if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
		loff_t end_offs = i_size_read(inode) - 1;
		unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT;

		count += offset;
		count = max(count + offset, nfs_page_length(page));
		offset = 0;
		if (unlikely(end_offs < 0)) {
			/* Do nothing */
		} else if (page->index == end_index) {
			unsigned int pglen;
			pglen = (unsigned int)(end_offs & (PAGE_CACHE_SIZE-1)) + 1;
			if (count < pglen)
				count = pglen;
		} else if (page->index < end_index)
			count = PAGE_CACHE_SIZE;
	}

	/*