aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorScott Mayhew <smayhew@redhat.com>2013-07-05 17:33:19 -0400
committerTrond Myklebust <Trond.Myklebust@netapp.com>2013-07-09 19:32:50 -0400
commitc7559663e42f4294ffe31fe159da6b6a66b35d61 (patch)
tree0b59b9bdc4a423efa64c79e9e9db1af68c27ff40 /fs
parent07b5ce8ef2d87f1914054804720d6facbaa3f4ce (diff)
NFS: Allow nfs_updatepage to extend a write under additional circumstances
Currently nfs_updatepage allows a write to be extended to cover a full page only if we don't have a byte range lock lock on the file... but if we have a write delegation on the file or if we have the whole file locked for writing then we should be allowed to extend the write as well. Signed-off-by: Scott Mayhew <smayhew@redhat.com> [Trond: fix up call to nfs_have_delegation()] Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/write.c31
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/nfs/write.c b/fs/nfs/write.c
index a2c7c28049d5..f1bdb7254776 100644
--- a/fs/nfs/write.c
+++ b/fs/nfs/write.c
@@ -888,6 +888,28 @@ out:
888 return PageUptodate(page) != 0; 888 return PageUptodate(page) != 0;
889} 889}
890 890
891/* If we know the page is up to date, and we're not using byte range locks (or
892 * if we have the whole file locked for writing), it may be more efficient to
893 * extend the write to cover the entire page in order to avoid fragmentation
894 * inefficiencies.
895 *
896 * If the file is opened for synchronous writes or if we have a write delegation
897 * from the server then we can just skip the rest of the checks.
898 */
899static int nfs_can_extend_write(struct file *file, struct page *page, struct inode *inode)
900{
901 if (file->f_flags & O_DSYNC)
902 return 0;
903 if (NFS_PROTO(inode)->have_delegation(inode, FMODE_WRITE))
904 return 1;
905 if (nfs_write_pageuptodate(page, inode) && (inode->i_flock == NULL ||
906 (inode->i_flock->fl_start == 0 &&
907 inode->i_flock->fl_end == OFFSET_MAX &&
908 inode->i_flock->fl_type != F_RDLCK)))
909 return 1;
910 return 0;
911}
912
891/* 913/*
892 * Update and possibly write a cached page of an NFS file. 914 * Update and possibly write a cached page of an NFS file.
893 * 915 *
@@ -908,14 +930,7 @@ int nfs_updatepage(struct file *file, struct page *page,
908 file->f_path.dentry->d_name.name, count, 930 file->f_path.dentry->d_name.name, count,
909 (long long)(page_file_offset(page) + offset)); 931 (long long)(page_file_offset(page) + offset));
910 932
911 /* If we're not using byte range locks, and we know the page 933 if (nfs_can_extend_write(file, page, inode)) {
912 * is up to date, it may be more efficient to extend the write
913 * to cover the entire page in order to avoid fragmentation
914 * inefficiencies.
915 */
916 if (nfs_write_pageuptodate(page, inode) &&
917 inode->i_flock == NULL &&
918 !(file->f_flags & O_DSYNC)) {
919 count = max(count + offset, nfs_page_length(page)); 934 count = max(count + offset, nfs_page_length(page));
920 offset = 0; 935 offset = 0;
921 } 936 }