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 f68c22215b14..966a8850aa30 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)
@@ -457,9 +457,18 @@ int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
457 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; 457 int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME;
458 int err; 458 int err;
459 459
460 /* Flush out writes to the server in order to update c/mtime */ 460 /*
461 if (S_ISREG(inode->i_mode)) 461 * Flush out writes to the server in order to update c/mtime.
462 *
463 * Hold the i_mutex to suspend application writes temporarily;
464 * this prevents long-running writing applications from blocking
465 * nfs_wb_nocommit.
466 */
467 if (S_ISREG(inode->i_mode)) {
468 mutex_lock(&inode->i_mutex);
462 nfs_wb_nocommit(inode); 469 nfs_wb_nocommit(inode);
470 mutex_unlock(&inode->i_mutex);
471 }
463 472
464 /* 473 /*
465 * We may force a getattr if the user cares about atime. 474 * We may force a getattr if the user cares about atime.
@@ -655,7 +664,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
655 if (status == -ESTALE) { 664 if (status == -ESTALE) {
656 nfs_zap_caches(inode); 665 nfs_zap_caches(inode);
657 if (!S_ISDIR(inode->i_mode)) 666 if (!S_ISDIR(inode->i_mode))
658 set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); 667 set_bit(NFS_INO_STALE, &NFS_I(inode)->flags);
659 } 668 }
660 goto out; 669 goto out;
661 } 670 }
@@ -810,8 +819,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr)
810 if (S_ISDIR(inode->i_mode)) 819 if (S_ISDIR(inode->i_mode))
811 nfsi->cache_validity |= NFS_INO_INVALID_DATA; 820 nfsi->cache_validity |= NFS_INO_INVALID_DATA;
812 } 821 }
813 if (inode->i_size == fattr->pre_size && nfsi->npages == 0) 822 if (inode->i_size == nfs_size_to_loff_t(fattr->pre_size) &&
814 inode->i_size = fattr->size; 823 nfsi->npages == 0)
824 inode->i_size = nfs_size_to_loff_t(fattr->size);
815 } 825 }
816} 826}
817 827
@@ -1015,7 +1025,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1015 dprintk("NFS: mtime change on server for file %s/%ld\n", 1025 dprintk("NFS: mtime change on server for file %s/%ld\n",
1016 inode->i_sb->s_id, inode->i_ino); 1026 inode->i_sb->s_id, inode->i_ino);
1017 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; 1027 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA;
1018 nfsi->cache_change_attribute = now; 1028 if (S_ISDIR(inode->i_mode))
1029 nfs_force_lookup_revalidate(inode);
1019 } 1030 }
1020 /* If ctime has changed we should definitely clear access+acl caches */ 1031 /* If ctime has changed we should definitely clear access+acl caches */
1021 if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) 1032 if (!timespec_equal(&inode->i_ctime, &fattr->ctime))
@@ -1024,7 +1035,8 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1024 dprintk("NFS: change_attr change on server for file %s/%ld\n", 1035 dprintk("NFS: change_attr change on server for file %s/%ld\n",
1025 inode->i_sb->s_id, inode->i_ino); 1036 inode->i_sb->s_id, inode->i_ino);
1026 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; 1037 invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL;
1027 nfsi->cache_change_attribute = now; 1038 if (S_ISDIR(inode->i_mode))
1039 nfs_force_lookup_revalidate(inode);
1028 } 1040 }
1029 1041
1030 /* Check if our cached file size is stale */ 1042 /* Check if our cached file size is stale */
@@ -1129,7 +1141,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr)
1129void nfs4_clear_inode(struct inode *inode) 1141void nfs4_clear_inode(struct inode *inode)
1130{ 1142{
1131 /* If we are holding a delegation, return it! */ 1143 /* If we are holding a delegation, return it! */
1132 nfs_inode_return_delegation(inode); 1144 nfs_inode_return_delegation_noreclaim(inode);
1133 /* First call standard NFS clear_inode() code */ 1145 /* First call standard NFS clear_inode() code */
1134 nfs_clear_inode(inode); 1146 nfs_clear_inode(inode);
1135} 1147}