mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 02:19:51 +00:00
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: Trond Myklebust <Trond.Myklebust@netapp.com>
This commit is contained in:
parent
277459d2e2
commit
49a70f2786
3 changed files with 31 additions and 63 deletions
|
@ -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)
|
if (sb->s_maxbytes > MAX_LFS_FILESIZE || sb->s_maxbytes <= 0)
|
||||||
sb->s_maxbytes = MAX_LFS_FILESIZE;
|
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;
|
||||||
|
}
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
|
||||||
|
#include "internal.h"
|
||||||
#include "iostat.h"
|
#include "iostat.h"
|
||||||
|
|
||||||
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
|
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
|
||||||
|
@ -83,22 +84,6 @@ void nfs_readdata_release(void *data)
|
||||||
nfs_readdata_free(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
|
static
|
||||||
int nfs_return_empty_page(struct page *page)
|
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;
|
struct nfs_page *new;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
len = nfs_page_length(inode, page);
|
len = nfs_page_length(page);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return nfs_return_empty_page(page);
|
return nfs_return_empty_page(page);
|
||||||
new = nfs_create_request(ctx, inode, page, 0, len);
|
new = nfs_create_request(ctx, inode, page, 0, len);
|
||||||
|
@ -667,7 +652,7 @@ readpage_async_filler(void *data, struct page *page)
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
nfs_wb_page(inode, page);
|
nfs_wb_page(inode, page);
|
||||||
len = nfs_page_length(inode, page);
|
len = nfs_page_length(page);
|
||||||
if (len == 0)
|
if (len == 0)
|
||||||
return nfs_return_empty_page(page);
|
return nfs_return_empty_page(page);
|
||||||
new = nfs_create_request(desc->ctx, inode, page, 0, len);
|
new = nfs_create_request(desc->ctx, inode, page, 0, len);
|
||||||
|
|
|
@ -63,6 +63,7 @@
|
||||||
#include <linux/smp_lock.h>
|
#include <linux/smp_lock.h>
|
||||||
|
|
||||||
#include "delegation.h"
|
#include "delegation.h"
|
||||||
|
#include "internal.h"
|
||||||
#include "iostat.h"
|
#include "iostat.h"
|
||||||
|
|
||||||
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
|
#define NFSDBG_FACILITY NFSDBG_PAGECACHE
|
||||||
|
@ -199,30 +200,15 @@ 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)
|
static void nfs_mark_uptodate(struct page *page, unsigned int base, unsigned int count)
|
||||||
{
|
{
|
||||||
loff_t end_offs;
|
|
||||||
|
|
||||||
if (PageUptodate(page))
|
if (PageUptodate(page))
|
||||||
return;
|
return;
|
||||||
if (base != 0)
|
if (base != 0)
|
||||||
return;
|
return;
|
||||||
if (count == PAGE_CACHE_SIZE) {
|
if (count != nfs_page_length(page))
|
||||||
SetPageUptodate(page);
|
|
||||||
return;
|
return;
|
||||||
}
|
if (count != PAGE_CACHE_SIZE)
|
||||||
|
|
||||||
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))
|
|
||||||
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) {
|
|
||||||
memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count);
|
memclear_highpage_flush(page, count, PAGE_CACHE_SIZE - count);
|
||||||
SetPageUptodate(page);
|
SetPageUptodate(page);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -330,9 +316,7 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||||
{
|
{
|
||||||
struct nfs_open_context *ctx;
|
struct nfs_open_context *ctx;
|
||||||
struct inode *inode = page->mapping->host;
|
struct inode *inode = page->mapping->host;
|
||||||
unsigned long end_index;
|
unsigned offset;
|
||||||
unsigned offset = PAGE_CACHE_SIZE;
|
|
||||||
loff_t i_size = i_size_read(inode);
|
|
||||||
int inode_referenced = 0;
|
int inode_referenced = 0;
|
||||||
int priority = wb_priority(wbc);
|
int priority = wb_priority(wbc);
|
||||||
int err;
|
int err;
|
||||||
|
@ -350,22 +334,15 @@ int nfs_writepage(struct page *page, struct writeback_control *wbc)
|
||||||
*/
|
*/
|
||||||
if (igrab(inode) != 0)
|
if (igrab(inode) != 0)
|
||||||
inode_referenced = 1;
|
inode_referenced = 1;
|
||||||
end_index = i_size >> PAGE_CACHE_SHIFT;
|
|
||||||
|
|
||||||
/* Ensure we've flushed out any previous writes */
|
/* Ensure we've flushed out any previous writes */
|
||||||
nfs_wb_page_priority(inode, page, priority);
|
nfs_wb_page_priority(inode, page, priority);
|
||||||
|
|
||||||
/* easy case */
|
err = 0;
|
||||||
if (page->index < end_index)
|
offset = nfs_page_length(page);
|
||||||
goto do_it;
|
if (!offset)
|
||||||
/* 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)
|
|
||||||
goto out;
|
goto out;
|
||||||
do_it:
|
|
||||||
ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
|
ctx = nfs_find_open_context(inode, NULL, FMODE_WRITE);
|
||||||
if (ctx == NULL) {
|
if (ctx == NULL) {
|
||||||
err = -EBADF;
|
err = -EBADF;
|
||||||
|
@ -826,20 +803,8 @@ int nfs_updatepage(struct file *file, struct page *page,
|
||||||
* fragmenting write requests.
|
* fragmenting write requests.
|
||||||
*/
|
*/
|
||||||
if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
|
if (PageUptodate(page) && inode->i_flock == NULL && !(file->f_mode & O_SYNC)) {
|
||||||
loff_t end_offs = i_size_read(inode) - 1;
|
count = max(count + offset, nfs_page_length(page));
|
||||||
unsigned long end_index = end_offs >> PAGE_CACHE_SHIFT;
|
|
||||||
|
|
||||||
count += offset;
|
|
||||||
offset = 0;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
Loading…
Reference in a new issue