Loading fs/nfs/internal.h +18 −0 Original line number Diff line number Diff line Loading @@ -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; } fs/nfs/read.c +3 −18 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <asm/system.h> #include "internal.h" #include "iostat.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); Loading fs/nfs/write.c +10 −45 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ #include <linux/smp_lock.h> #include "delegation.h" #include "internal.h" #include "iostat.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE Loading Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } /* Loading Loading
fs/nfs/internal.h +18 −0 Original line number Diff line number Diff line Loading @@ -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; }
fs/nfs/read.c +3 −18 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <asm/system.h> #include "internal.h" #include "iostat.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE Loading Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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); Loading
fs/nfs/write.c +10 −45 Original line number Diff line number Diff line Loading @@ -63,6 +63,7 @@ #include <linux/smp_lock.h> #include "delegation.h" #include "internal.h" #include "iostat.h" #define NFSDBG_FACILITY NFSDBG_PAGECACHE Loading Loading @@ -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. Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; } /* Loading