aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:11:35 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-11 15:11:35 -0400
commit1466b77a7be75144dee1cb09839be3435854dd0b (patch)
tree977a0b6c1cd69ff98e5027359bb7de7b8897276a /fs
parent19d2f8e0fb7bba99cc585d2467e9fa54a84c8557 (diff)
parenteeee245268c951262b861bc1be4e9dc812352499 (diff)
Merge tag 'nfs-for-3.11-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs
Pull second set of NFS client updates from Trond Myklebust: "This mainly contains some small readdir optimisations that had dependencies on Al Viro's readdir rewrite. There is also a fix for a nasty deadlock which surfaced earlier in this merge window. Highlights include: - Fix an_rpc pipefs regression that causes a deadlock on mount - Readdir optimisations by Scott Mayhew and Jeff Layton - clean up the rpc_pipefs dentry operation setup" * tag 'nfs-for-3.11-2' of git://git.linux-nfs.org/projects/trondmy/linux-nfs: SUNRPC: Fix a deadlock in rpc_client_register() rpc_pipe: rpc_dir_inode_operations can be static NFS: Allow nfs_updatepage to extend a write under additional circumstances NFS: Make nfs_readdir revalidate less often NFS: Make nfs_attribute_cache_expired() non-static rpc_pipe: set dentry operations at d_alloc time nfs: set verifier on existing dentries in nfs_prime_dcache
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/dir.c6
-rw-r--r--fs/nfs/inode.c2
-rw-r--r--fs/nfs/write.c31
3 files changed, 28 insertions, 11 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 0fac2cb1ea18..e474ca2b2bfe 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -450,6 +450,7 @@ void nfs_prime_dcache(struct dentry *parent, struct nfs_entry *entry)
450 dentry = d_lookup(parent, &filename); 450 dentry = d_lookup(parent, &filename);
451 if (dentry != NULL) { 451 if (dentry != NULL) {
452 if (nfs_same_file(dentry, entry)) { 452 if (nfs_same_file(dentry, entry)) {
453 nfs_set_verifier(dentry, nfs_save_change_attribute(dir));
453 status = nfs_refresh_inode(dentry->d_inode, entry->fattr); 454 status = nfs_refresh_inode(dentry->d_inode, entry->fattr);
454 if (!status) 455 if (!status)
455 nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label); 456 nfs_setsecurity(dentry->d_inode, entry->fattr, entry->label);
@@ -817,7 +818,7 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
817 nfs_readdir_descriptor_t my_desc, 818 nfs_readdir_descriptor_t my_desc,
818 *desc = &my_desc; 819 *desc = &my_desc;
819 struct nfs_open_dir_context *dir_ctx = file->private_data; 820 struct nfs_open_dir_context *dir_ctx = file->private_data;
820 int res; 821 int res = 0;
821 822
822 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n", 823 dfprintk(FILE, "NFS: readdir(%s/%s) starting at cookie %llu\n",
823 dentry->d_parent->d_name.name, dentry->d_name.name, 824 dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -839,7 +840,8 @@ static int nfs_readdir(struct file *file, struct dir_context *ctx)
839 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0; 840 desc->plus = nfs_use_readdirplus(inode, ctx) ? 1 : 0;
840 841
841 nfs_block_sillyrename(dentry); 842 nfs_block_sillyrename(dentry);
842 res = nfs_revalidate_mapping(inode, file->f_mapping); 843 if (ctx->pos == 0 || nfs_attribute_cache_expired(inode))
844 res = nfs_revalidate_mapping(inode, file->f_mapping);
843 if (res < 0) 845 if (res < 0)
844 goto out; 846 goto out;
845 847
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index c93639e6cf68..af6e806044d7 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -936,7 +936,7 @@ int nfs_attribute_timeout(struct inode *inode)
936 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo); 936 return !time_in_range_open(jiffies, nfsi->read_cache_jiffies, nfsi->read_cache_jiffies + nfsi->attrtimeo);
937} 937}
938 938
939static int nfs_attribute_cache_expired(struct inode *inode) 939int nfs_attribute_cache_expired(struct inode *inode)
940{ 940{
941 if (nfs_have_delegated_attributes(inode)) 941 if (nfs_have_delegated_attributes(inode))
942 return 0; 942 return 0;
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 }