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, 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 */
193static void nfs_invalidate_inode(struct inode *inode) 193static 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)
1133void nfs4_clear_inode(struct inode *inode) 1145void 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}