aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r--fs/nfs/inode.c34
1 files changed, 27 insertions, 7 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 360114ae8b82..9dbef878a2b2 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -588,6 +588,25 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
588} 588}
589EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); 589EXPORT_SYMBOL_GPL(nfs_setattr_update_inode);
590 590
591static void nfs_request_parent_use_readdirplus(struct dentry *dentry)
592{
593 struct dentry *parent;
594
595 parent = dget_parent(dentry);
596 nfs_force_use_readdirplus(parent->d_inode);
597 dput(parent);
598}
599
600static bool nfs_need_revalidate_inode(struct inode *inode)
601{
602 if (NFS_I(inode)->cache_validity &
603 (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
604 return true;
605 if (nfs_attribute_cache_expired(inode))
606 return true;
607 return false;
608}
609
591int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 610int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
592{ 611{
593 struct inode *inode = dentry->d_inode; 612 struct inode *inode = dentry->d_inode;
@@ -616,10 +635,13 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
616 ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode))) 635 ((mnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
617 need_atime = 0; 636 need_atime = 0;
618 637
619 if (need_atime) 638 if (need_atime || nfs_need_revalidate_inode(inode)) {
620 err = __nfs_revalidate_inode(NFS_SERVER(inode), inode); 639 struct nfs_server *server = NFS_SERVER(inode);
621 else 640
622 err = nfs_revalidate_inode(NFS_SERVER(inode), inode); 641 if (server->caps & NFS_CAP_READDIRPLUS)
642 nfs_request_parent_use_readdirplus(dentry);
643 err = __nfs_revalidate_inode(server, inode);
644 }
623 if (!err) { 645 if (!err) {
624 generic_fillattr(inode, stat); 646 generic_fillattr(inode, stat);
625 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode)); 647 stat->ino = nfs_compat_user_ino64(NFS_FILEID(inode));
@@ -961,9 +983,7 @@ int nfs_attribute_cache_expired(struct inode *inode)
961 */ 983 */
962int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) 984int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
963{ 985{
964 if (!(NFS_I(inode)->cache_validity & 986 if (!nfs_need_revalidate_inode(inode))
965 (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_LABEL))
966 && !nfs_attribute_cache_expired(inode))
967 return NFS_STALE(inode) ? -ESTALE : 0; 987 return NFS_STALE(inode) ? -ESTALE : 0;
968 return __nfs_revalidate_inode(server, inode); 988 return __nfs_revalidate_inode(server, inode);
969} 989}