diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-11 15:11:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-07-11 15:11:35 -0400 |
commit | 1466b77a7be75144dee1cb09839be3435854dd0b (patch) | |
tree | 977a0b6c1cd69ff98e5027359bb7de7b8897276a /fs | |
parent | 19d2f8e0fb7bba99cc585d2467e9fa54a84c8557 (diff) | |
parent | eeee245268c951262b861bc1be4e9dc812352499 (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.c | 6 | ||||
-rw-r--r-- | fs/nfs/inode.c | 2 | ||||
-rw-r--r-- | fs/nfs/write.c | 31 |
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 | ||
939 | static int nfs_attribute_cache_expired(struct inode *inode) | 939 | int 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 | */ | ||
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 | } |