diff options
Diffstat (limited to 'fs/nfs/write.c')
| -rw-r--r-- | fs/nfs/write.c | 31 |
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 | */ | ||
| 899 | static 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 | } |
