Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] NFS: Cleanup of caching code, and slight optimization of writes.

Unless we're doing O_APPEND writes, we really don't care about revalidating
the file length. Just make sure that we catch any page cache invalidations.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>

+39 -18
+9 -3
fs/nfs/file.c
··· 333 333 result = -EBUSY; 334 334 if (IS_SWAPFILE(inode)) 335 335 goto out_swapfile; 336 - result = nfs_revalidate_inode(NFS_SERVER(inode), inode); 337 - if (result) 338 - goto out; 336 + /* 337 + * O_APPEND implies that we must revalidate the file length. 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 346 result = count; 341 347 if (!count)
+29 -15
fs/nfs/inode.c
··· 1062 1062 if (verifier == nfsi->cache_change_attribute) 1063 1063 nfsi->flags &= ~(NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME); 1064 1064 /* Do the page cache invalidation */ 1065 - if (flags & NFS_INO_INVALID_DATA) { 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 - } 1065 + nfs_revalidate_mapping(inode, inode->i_mapping); 1080 1066 if (flags & NFS_INO_INVALID_ACL) 1081 1067 nfs_zap_acl_cache(inode); 1082 1068 dfprintk(PAGECACHE, "NFS: (%s/%Ld) revalidation complete\n", ··· 1099 1113 && !nfs_attribute_timeout(inode)) 1100 1114 return NFS_STALE(inode) ? -ESTALE : 0; 1101 1115 return __nfs_revalidate_inode(server, inode); 1116 + } 1117 + 1118 + /** 1119 + * nfs_revalidate_mapping - Revalidate the pagecache 1120 + * @inode - pointer to host inode 1121 + * @mapping - pointer to mapping 1122 + */ 1123 + void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) 1124 + { 1125 + struct nfs_inode *nfsi = NFS_I(inode); 1126 + 1127 + if (nfsi->flags & NFS_INO_INVALID_DATA) { 1128 + if (S_ISREG(inode->i_mode)) { 1129 + if (filemap_fdatawrite(mapping) == 0) 1130 + filemap_fdatawait(mapping); 1131 + nfs_wb_all(inode); 1132 + } 1133 + invalidate_inode_pages2(mapping); 1134 + nfsi->flags &= ~NFS_INO_INVALID_DATA; 1135 + if (S_ISDIR(inode->i_mode)) { 1136 + memset(nfsi->cookieverf, 0, sizeof(nfsi->cookieverf)); 1137 + /* This ensures we revalidate child dentries */ 1138 + nfsi->cache_change_attribute++; 1139 + } 1140 + dfprintk(PAGECACHE, "NFS: (%s/%Ld) data cache invalidated\n", 1141 + inode->i_sb->s_id, 1142 + (long long)NFS_FILEID(inode)); 1143 + } 1102 1144 } 1103 1145 1104 1146 /**
+1
include/linux/nfs_fs.h
··· 289 289 extern int nfs_attribute_timeout(struct inode *inode); 290 290 extern int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode); 291 291 extern int __nfs_revalidate_inode(struct nfs_server *, struct inode *); 292 + extern void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping); 292 293 extern int nfs_setattr(struct dentry *, struct iattr *); 293 294 extern void nfs_begin_attr_update(struct inode *); 294 295 extern void nfs_end_attr_update(struct inode *);