aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/file.c12
-rw-r--r--fs/nfs/inode.c44
-rw-r--r--include/linux/nfs_fs.h1
3 files changed, 39 insertions, 18 deletions
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index a606708264ed..40436857ed42 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -333,9 +333,15 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t
333 result = -EBUSY; 333 result = -EBUSY;
334 if (IS_SWAPFILE(inode)) 334 if (IS_SWAPFILE(inode))
335 goto out_swapfile; 335 goto out_swapfile;
336 result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 336 /*
337 if (result) 337 * O_APPEND implies that we must revalidate the file length.
338 goto out; 338 */
339 if (iocb->ki_filp->f_flags & O_APPEND) {
340 result = nfs_revalidate_file_size(inode, iocb->ki_filp);
341 if (result)
342 goto out;
343 } else
344 nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
339 345
340 result = count; 346 result = count;
341 if (!count) 347 if (!count)
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index b2d16758ced8..a3922f4cc0a8 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1062,21 +1062,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1062 if (verifier == nfsi->cache_change_attribute) 1062 if (verifier == nfsi->cache_change_attribute)
1063 nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1063 nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME);
1064 /* Do the page cache invalidation */ 1064 /* Do the page cache invalidation */
1065 if (flags & NFS_INO_INVALID_DATA) { 1065 nfs_revalidate_mapping(inode, inode->i_mapping);
1066 if (S_ISREG(inode->i_mode)) {
1067 if (filemap_fdatawrite(inode->i_mapping) == 0)
1068 filemap_fdatawait(inode->i_mapping);
1069 nfs_wb_all(inode);
1070 }
1071 nfsi->flags &= ~NFS_INO_INVALID_DATA;
1072 invalidate_inode_pages2(inode->i_mapping);
1073 memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
1074 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
1075 inode->i_sb->s_id,
1076 (long long)NFS_FILEID(inode));
1077 /* This ensures we revalidate dentries */
1078 nfsi->cache_change_attribute++;
1079 }
1080 if (flags & NFS_INO_INVALID_ACL) 1066 if (flags & NFS_INO_INVALID_ACL)
1081 nfs_zap_acl_cache(inode); 1067 nfs_zap_acl_cache(inode);
1082 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", 1068 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n",
@@ -1116,6 +1102,34 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1116} 1102}
1117 1103
1118/** 1104/**
1105 * nfs_revalidate_mapping - Revalidate the pagecache
1106 * @inode - pointer to host inode
1107 * @mapping - pointer to mapping
1108 */
1109void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping)
1110{
1111 struct nfs_inode *nfsi = NFS_I(inode);
1112
1113 if (nfsi->flags & NFS_INO_INVALID_DATA) {
1114 if (S_ISREG(inode->i_mode)) {
1115 if (filemap_fdatawrite(mapping) == 0)
1116 filemap_fdatawait(mapping);
1117 nfs_wb_all(inode);
1118 }
1119 invalidate_inode_pages2(mapping);
1120 nfsi->flags &= ~NFS_INO_INVALID_DATA;
1121 if (S_ISDIR(inode->i_mode)) {
1122 memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf));
1123 /* This ensures we revalidate child dentries */
1124 nfsi->cache_change_attribute++;
1125 }
1126 dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n",
1127 inode->i_sb->s_id,
1128 (long long)NFS_FILEID(inode));
1129 }
1130}
1131
1132/**
1119 * nfs_begin_data_update 1133 * nfs_begin_data_update
1120 * @inode - pointer to inode 1134 * @inode - pointer to inode
1121 * Declare that a set of operations will update file data on the server 1135 * Declare that a set of operations will update file data on the server
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 211266c56ce5..443103c13e53 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -289,6 +289,7 @@ extern int nfs_release(struct inode *, struct file *);
289extern int nfs_attribute_timeout(struct inode *inode); 289extern int nfs_attribute_timeout(struct inode *inode);
290extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); 290extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode);
291extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); 291extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *);
292extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping);
292extern int nfs_setattr(struct dentry *, struct iattr *); 293extern int nfs_setattr(struct dentry *, struct iattr *);
293extern void nfs_begin_attr_update(struct inode *); 294extern void nfs_begin_attr_update(struct inode *);
294extern void nfs_end_attr_update(struct inode *); 295extern void nfs_end_attr_update(struct inode *);