Loading fs/nfs/file.c +22 −6 Original line number Original line Diff line number Diff line Loading @@ -127,6 +127,21 @@ nfs_file_release(struct inode *inode, struct file *filp) return NFS_PROTO(inode)->file_release(inode, filp); return NFS_PROTO(inode)->file_release(inode, filp); } } /** * nfs_revalidate_file - Revalidate the page cache & related metadata * @inode - pointer to inode struct * @file - pointer to file */ static int nfs_revalidate_file(struct inode *inode, struct file *filp) { int retval = 0; if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode)) retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode); nfs_revalidate_mapping(inode, filp->f_mapping); return 0; } /** /** * nfs_revalidate_size - Revalidate the file size * nfs_revalidate_size - Revalidate the file size * @inode - pointer to inode struct * @inode - pointer to inode struct Loading @@ -149,7 +164,8 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) goto force_reval; goto force_reval; if (nfsi->npages != 0) if (nfsi->npages != 0) return 0; return 0; return nfs_revalidate_inode(server, inode); if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode)) return 0; force_reval: force_reval: return __nfs_revalidate_inode(server, inode); return __nfs_revalidate_inode(server, inode); } } Loading Loading @@ -210,7 +226,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long) pos); (unsigned long) count, (unsigned long) pos); result = nfs_revalidate_inode(NFS_SERVER(inode), inode); result = nfs_revalidate_file(inode, iocb->ki_filp); if (!result) if (!result) result = generic_file_aio_read(iocb, buf, count, pos); result = generic_file_aio_read(iocb, buf, count, pos); return result; return result; Loading @@ -228,7 +244,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long long) *ppos); (unsigned long) count, (unsigned long long) *ppos); res = nfs_revalidate_inode(NFS_SERVER(inode), inode); res = nfs_revalidate_file(inode, filp); if (!res) if (!res) res = generic_file_sendfile(filp, ppos, count, actor, target); res = generic_file_sendfile(filp, ppos, count, actor, target); return res; return res; Loading @@ -244,7 +260,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) dfprintk(VFS, "nfs: mmap(%s/%s)\n", dfprintk(VFS, "nfs: mmap(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name); status = nfs_revalidate_inode(NFS_SERVER(inode), inode); status = nfs_revalidate_file(inode, file); if (!status) if (!status) status = generic_file_mmap(file, vma); status = generic_file_mmap(file, vma); return status; return status; Loading Loading @@ -340,7 +356,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t result = nfs_revalidate_file_size(inode, iocb->ki_filp); result = nfs_revalidate_file_size(inode, iocb->ki_filp); if (result) if (result) goto out; goto out; } else } nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); result = count; result = count; Loading fs/nfs/inode.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -620,9 +620,9 @@ nfs_zap_caches(struct inode *inode) memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; else else nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; } } static void nfs_zap_acl_cache(struct inode *inode) static void nfs_zap_acl_cache(struct inode *inode) Loading Loading @@ -1055,6 +1055,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) goto out; goto out; } } flags = nfsi->flags; flags = nfsi->flags; nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE; /* /* * We may need to keep the attributes marked as invalid if * We may need to keep the attributes marked as invalid if * we raced with nfs_end_attr_update(). * we raced with nfs_end_attr_update(). Loading Loading @@ -1187,8 +1188,11 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 && nfsi->change_attr == fattr->pre_change_attr) && nfsi->change_attr == fattr->pre_change_attr) nfsi->change_attr = fattr->change_attr; nfsi->change_attr = fattr->change_attr; if (!data_unstable && nfsi->change_attr != fattr->change_attr) if (nfsi->change_attr != fattr->change_attr) { nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; if (!data_unstable) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } } } if ((fattr->valid & NFS_ATTR_FATTR) == 0) if ((fattr->valid & NFS_ATTR_FATTR) == 0) Loading @@ -1211,12 +1215,16 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) } } /* Verify a few of the more important attributes */ /* Verify a few of the more important attributes */ if (!data_unstable) { if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { if (!timespec_equal(&inode->i_mtime, &fattr->mtime) || cur_size != new_isize) nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; } else if (new_isize != cur_size && nfsi->npages == 0) if (!data_unstable) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } if (cur_size != new_isize) { nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; if (nfsi->npages == 0) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } /* Have any file permissions changed? */ /* Have any file permissions changed? */ if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) Loading include/linux/nfs_fs.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -198,6 +198,7 @@ struct nfs_inode { #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ #define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */ #define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */ #define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */ static inline struct nfs_inode *NFS_I(struct inode *inode) static inline struct nfs_inode *NFS_I(struct inode *inode) { { Loading Loading
fs/nfs/file.c +22 −6 Original line number Original line Diff line number Diff line Loading @@ -127,6 +127,21 @@ nfs_file_release(struct inode *inode, struct file *filp) return NFS_PROTO(inode)->file_release(inode, filp); return NFS_PROTO(inode)->file_release(inode, filp); } } /** * nfs_revalidate_file - Revalidate the page cache & related metadata * @inode - pointer to inode struct * @file - pointer to file */ static int nfs_revalidate_file(struct inode *inode, struct file *filp) { int retval = 0; if ((NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) || nfs_attribute_timeout(inode)) retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode); nfs_revalidate_mapping(inode, filp->f_mapping); return 0; } /** /** * nfs_revalidate_size - Revalidate the file size * nfs_revalidate_size - Revalidate the file size * @inode - pointer to inode struct * @inode - pointer to inode struct Loading @@ -149,7 +164,8 @@ static int nfs_revalidate_file_size(struct inode *inode, struct file *filp) goto force_reval; goto force_reval; if (nfsi->npages != 0) if (nfsi->npages != 0) return 0; return 0; return nfs_revalidate_inode(server, inode); if (!(NFS_FLAGS(inode) & NFS_INO_REVAL_PAGECACHE) && !nfs_attribute_timeout(inode)) return 0; force_reval: force_reval: return __nfs_revalidate_inode(server, inode); return __nfs_revalidate_inode(server, inode); } } Loading Loading @@ -210,7 +226,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long) pos); (unsigned long) count, (unsigned long) pos); result = nfs_revalidate_inode(NFS_SERVER(inode), inode); result = nfs_revalidate_file(inode, iocb->ki_filp); if (!result) if (!result) result = generic_file_aio_read(iocb, buf, count, pos); result = generic_file_aio_read(iocb, buf, count, pos); return result; return result; Loading @@ -228,7 +244,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_parent->d_name.name, dentry->d_name.name, (unsigned long) count, (unsigned long long) *ppos); (unsigned long) count, (unsigned long long) *ppos); res = nfs_revalidate_inode(NFS_SERVER(inode), inode); res = nfs_revalidate_file(inode, filp); if (!res) if (!res) res = generic_file_sendfile(filp, ppos, count, actor, target); res = generic_file_sendfile(filp, ppos, count, actor, target); return res; return res; Loading @@ -244,7 +260,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) dfprintk(VFS, "nfs: mmap(%s/%s)\n", dfprintk(VFS, "nfs: mmap(%s/%s)\n", dentry->d_parent->d_name.name, dentry->d_name.name); dentry->d_parent->d_name.name, dentry->d_name.name); status = nfs_revalidate_inode(NFS_SERVER(inode), inode); status = nfs_revalidate_file(inode, file); if (!status) if (!status) status = generic_file_mmap(file, vma); status = generic_file_mmap(file, vma); return status; return status; Loading Loading @@ -340,7 +356,7 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t result = nfs_revalidate_file_size(inode, iocb->ki_filp); result = nfs_revalidate_file_size(inode, iocb->ki_filp); if (result) if (result) goto out; goto out; } else } nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); result = count; result = count; Loading
fs/nfs/inode.c +16 −8 Original line number Original line Diff line number Diff line Loading @@ -620,9 +620,9 @@ nfs_zap_caches(struct inode *inode) memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode))); if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) if (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; else else nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; nfsi->flags |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL|NFS_INO_REVAL_PAGECACHE; } } static void nfs_zap_acl_cache(struct inode *inode) static void nfs_zap_acl_cache(struct inode *inode) Loading Loading @@ -1055,6 +1055,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) goto out; goto out; } } flags = nfsi->flags; flags = nfsi->flags; nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE; /* /* * We may need to keep the attributes marked as invalid if * We may need to keep the attributes marked as invalid if * we raced with nfs_end_attr_update(). * we raced with nfs_end_attr_update(). Loading Loading @@ -1187,8 +1188,11 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0 && nfsi->change_attr == fattr->pre_change_attr) && nfsi->change_attr == fattr->pre_change_attr) nfsi->change_attr = fattr->change_attr; nfsi->change_attr = fattr->change_attr; if (!data_unstable && nfsi->change_attr != fattr->change_attr) if (nfsi->change_attr != fattr->change_attr) { nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; if (!data_unstable) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } } } if ((fattr->valid & NFS_ATTR_FATTR) == 0) if ((fattr->valid & NFS_ATTR_FATTR) == 0) Loading @@ -1211,12 +1215,16 @@ int nfs_refresh_inode(struct inode *inode, struct nfs_fattr *fattr) } } /* Verify a few of the more important attributes */ /* Verify a few of the more important attributes */ if (!data_unstable) { if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) { if (!timespec_equal(&inode->i_mtime, &fattr->mtime) || cur_size != new_isize) nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; } else if (new_isize != cur_size && nfsi->npages == 0) if (!data_unstable) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } if (cur_size != new_isize) { nfsi->flags |= NFS_INO_INVALID_ATTR; nfsi->flags |= NFS_INO_INVALID_ATTR; if (nfsi->npages == 0) nfsi->flags |= NFS_INO_REVAL_PAGECACHE; } /* Have any file permissions changed? */ /* Have any file permissions changed? */ if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO) Loading
include/linux/nfs_fs.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -198,6 +198,7 @@ struct nfs_inode { #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ #define NFS_INO_INVALID_ATIME 0x0020 /* cached atime is invalid */ #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ #define NFS_INO_INVALID_ACCESS 0x0040 /* cached access cred invalid */ #define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */ #define NFS_INO_INVALID_ACL 0x0080 /* cached acls are invalid */ #define NFS_INO_REVAL_PAGECACHE 0x1000 /* must revalidate pagecache */ static inline struct nfs_inode *NFS_I(struct inode *inode) static inline struct nfs_inode *NFS_I(struct inode *inode) { { Loading