diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 34 |
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 | } |
589 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); | 589 | EXPORT_SYMBOL_GPL(nfs_setattr_update_inode); |
590 | 590 | ||
591 | static 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 | |||
600 | static 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 | |||
591 | int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 610 | int 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 | */ |
962 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 984 | int 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 | } |