diff options
Diffstat (limited to 'fs/nfs/inode.c')
| -rw-r--r-- | fs/nfs/inode.c | 36 |
1 files changed, 28 insertions, 8 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index 360114ae8b82..0c438973f3c8 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
| @@ -128,7 +128,7 @@ EXPORT_SYMBOL_GPL(nfs_clear_inode); | |||
| 128 | 128 | ||
| 129 | void nfs_evict_inode(struct inode *inode) | 129 | void nfs_evict_inode(struct inode *inode) |
| 130 | { | 130 | { |
| 131 | truncate_inode_pages(&inode->i_data, 0); | 131 | truncate_inode_pages_final(&inode->i_data); |
| 132 | clear_inode(inode); | 132 | clear_inode(inode); |
| 133 | nfs_clear_inode(inode); | 133 | nfs_clear_inode(inode); |
| 134 | } | 134 | } |
| @@ -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 | } |
