diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index db5d96dc6107..3f332e54e760 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -192,7 +192,7 @@ void nfs_invalidate_atime(struct inode *inode) | |||
192 | */ | 192 | */ |
193 | static void nfs_invalidate_inode(struct inode *inode) | 193 | static void nfs_invalidate_inode(struct inode *inode) |
194 | { | 194 | { |
195 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); | 195 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
196 | nfs_zap_caches_locked(inode); | 196 | nfs_zap_caches_locked(inode); |
197 | } | 197 | } |
198 | 198 | ||
@@ -229,7 +229,7 @@ nfs_init_locked(struct inode *inode, void *opaque) | |||
229 | struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque; | 229 | struct nfs_find_desc *desc = (struct nfs_find_desc *)opaque; |
230 | struct nfs_fattr *fattr = desc->fattr; | 230 | struct nfs_fattr *fattr = desc->fattr; |
231 | 231 | ||
232 | NFS_FILEID(inode) = fattr->fileid; | 232 | set_nfs_fileid(inode, fattr->fileid); |
233 | nfs_copy_fh(NFS_FH(inode), desc->fh); | 233 | nfs_copy_fh(NFS_FH(inode), desc->fh); |
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
@@ -291,7 +291,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr) | |||
291 | inode->i_fop = &nfs_dir_operations; | 291 | inode->i_fop = &nfs_dir_operations; |
292 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) | 292 | if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) |
293 | && fattr->size <= NFS_LIMIT_READDIRPLUS) | 293 | && fattr->size <= NFS_LIMIT_READDIRPLUS) |
294 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode)); | 294 | set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_I(inode)->flags); |
295 | /* Deal with crossing mountpoints */ | 295 | /* Deal with crossing mountpoints */ |
296 | if (!nfs_fsid_equal(&NFS_SB(sb)->fsid, &fattr->fsid)) { | 296 | if (!nfs_fsid_equal(&NFS_SB(sb)->fsid, &fattr->fsid)) { |
297 | if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) | 297 | if (fattr->valid & NFS_ATTR_FATTR_V4_REFERRAL) |
@@ -461,9 +461,18 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | |||
461 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; | 461 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
462 | int err; | 462 | int err; |
463 | 463 | ||
464 | /* Flush out writes to the server in order to update c/mtime */ | 464 | /* |
465 | if (S_ISREG(inode->i_mode)) | 465 | * Flush out writes to the server in order to update c/mtime. |
466 | * | ||
467 | * Hold the i_mutex to suspend application writes temporarily; | ||
468 | * this prevents long-running writing applications from blocking | ||
469 | * nfs_wb_nocommit. | ||
470 | */ | ||
471 | if (S_ISREG(inode->i_mode)) { | ||
472 | mutex_lock(&inode->i_mutex); | ||
466 | nfs_wb_nocommit(inode); | 473 | nfs_wb_nocommit(inode); |
474 | mutex_unlock(&inode->i_mutex); | ||
475 | } | ||
467 | 476 | ||
468 | /* | 477 | /* |
469 | * We may force a getattr if the user cares about atime. | 478 | * We may force a getattr if the user cares about atime. |
@@ -659,7 +668,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
659 | if (status == -ESTALE) { | 668 | if (status == -ESTALE) { |
660 | nfs_zap_caches(inode); | 669 | nfs_zap_caches(inode); |
661 | if (!S_ISDIR(inode->i_mode)) | 670 | if (!S_ISDIR(inode->i_mode)) |
662 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); | 671 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
663 | } | 672 | } |
664 | goto out; | 673 | goto out; |
665 | } | 674 | } |
@@ -814,8 +823,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
814 | if (S_ISDIR(inode->i_mode)) | 823 | if (S_ISDIR(inode->i_mode)) |
815 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 824 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
816 | } | 825 | } |
817 | if (inode->i_size == fattr->pre_size && nfsi->npages == 0) | 826 | if (inode->i_size == nfs_size_to_loff_t(fattr->pre_size) && |
818 | inode->i_size = fattr->size; | 827 | nfsi->npages == 0) |
828 | inode->i_size = nfs_size_to_loff_t(fattr->size); | ||
819 | } | 829 | } |
820 | } | 830 | } |
821 | 831 | ||
@@ -1019,7 +1029,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1019 | dprintk("NFS: mtime change on server for file %s/%ld\n", | 1029 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1020 | inode->i_sb->s_id, inode->i_ino); | 1030 | inode->i_sb->s_id, inode->i_ino); |
1021 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1031 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1022 | nfsi->cache_change_attribute = now; | 1032 | if (S_ISDIR(inode->i_mode)) |
1033 | nfs_force_lookup_revalidate(inode); | ||
1023 | } | 1034 | } |
1024 | /* If ctime has changed we should definitely clear access+acl caches */ | 1035 | /* If ctime has changed we should definitely clear access+acl caches */ |
1025 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) | 1036 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) |
@@ -1028,7 +1039,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1028 | dprintk("NFS: change_attr change on server for file %s/%ld\n", | 1039 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1029 | inode->i_sb->s_id, inode->i_ino); | 1040 | inode->i_sb->s_id, inode->i_ino); |
1030 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; | 1041 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1031 | nfsi->cache_change_attribute = now; | 1042 | if (S_ISDIR(inode->i_mode)) |
1043 | nfs_force_lookup_revalidate(inode); | ||
1032 | } | 1044 | } |
1033 | 1045 | ||
1034 | /* Check if our cached file size is stale */ | 1046 | /* Check if our cached file size is stale */ |
@@ -1133,7 +1145,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1133 | void nfs4_clear_inode(struct inode *inode) | 1145 | void nfs4_clear_inode(struct inode *inode) |
1134 | { | 1146 | { |
1135 | /* If we are holding a delegation, return it! */ | 1147 | /* If we are holding a delegation, return it! */ |
1136 | nfs_inode_return_delegation(inode); | 1148 | nfs_inode_return_delegation_noreclaim(inode); |
1137 | /* First call standard NFS clear_inode() code */ | 1149 | /* First call standard NFS clear_inode() code */ |
1138 | nfs_clear_inode(inode); | 1150 | nfs_clear_inode(inode); |
1139 | } | 1151 | } |