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
* @inode - pointer to inode struct
goto force_reval;
if (nfsi->npages != 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:
return __nfs_revalidate_inode(server, inode);
}
dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long) pos);
- result = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ result = nfs_revalidate_file(inode, iocb->ki_filp);
if (!result)
result = generic_file_aio_read(iocb, buf, count, pos);
return result;
dentry->d_parent->d_name.name, dentry->d_name.name,
(unsigned long) count, (unsigned long long) *ppos);
- res = nfs_revalidate_inode(NFS_SERVER(inode), inode);
+ res = nfs_revalidate_file(inode, filp);
if (!res)
res = generic_file_sendfile(filp, ppos, count, actor, target);
return res;
dfprintk(VFS, "nfs: mmap(%s/%s)\n",
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)
status = generic_file_mmap(file, vma);
return status;
result = nfs_revalidate_file_size(inode, iocb->ki_filp);
if (result)
goto out;
- } else
- nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
+ }
+ nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping);
result = count;
if (!count)
memset(NFS_COOKIEVERF(inode), 0, sizeof(NFS_COOKIEVERF(inode)));
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
- 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)
goto out;
}
flags = nfsi->flags;
+ nfsi->flags &= ~NFS_INO_REVAL_PAGECACHE;
/*
* We may need to keep the attributes marked as invalid if
* we raced with nfs_end_attr_update().
if ((fattr->valid & NFS_ATTR_PRE_CHANGE) != 0
&& nfsi->change_attr == fattr->pre_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;
+ if (!data_unstable)
+ nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
+ }
}
if ((fattr->valid & NFS_ATTR_FATTR) == 0)
}
/* Verify a few of the more important attributes */
- if (!data_unstable) {
- if (!timespec_equal(&inode->i_mtime, &fattr->mtime)
- || cur_size != new_isize)
- nfsi->flags |= NFS_INO_INVALID_ATTR;
- } else if (new_isize != cur_size && nfsi->npages == 0)
+ if (!timespec_equal(&inode->i_mtime, &fattr->mtime)) {
nfsi->flags |= NFS_INO_INVALID_ATTR;
+ if (!data_unstable)
+ nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
+ }
+ if (cur_size != new_isize) {
+ nfsi->flags |= NFS_INO_INVALID_ATTR;
+ if (nfsi->npages == 0)
+ nfsi->flags |= NFS_INO_REVAL_PAGECACHE;
+ }
/* Have any file permissions changed? */
if ((inode->i_mode & S_IALLUGO) != (fattr->mode & S_IALLUGO)