diff options
Diffstat (limited to 'fs/nfs/inode.c')
-rw-r--r-- | fs/nfs/inode.c | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index db5d96dc6107..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 | */ |
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) |
@@ -433,15 +433,11 @@ static int nfs_wait_schedule(void *word) | |||
433 | */ | 433 | */ |
434 | static int nfs_wait_on_inode(struct inode *inode) | 434 | static int nfs_wait_on_inode(struct inode *inode) |
435 | { | 435 | { |
436 | struct rpc_clnt *clnt = NFS_CLIENT(inode); | ||
437 | struct nfs_inode *nfsi = NFS_I(inode); | 436 | struct nfs_inode *nfsi = NFS_I(inode); |
438 | sigset_t oldmask; | ||
439 | int error; | 437 | int error; |
440 | 438 | ||
441 | rpc_clnt_sigmask(clnt, &oldmask); | ||
442 | error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING, | 439 | error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING, |
443 | nfs_wait_schedule, TASK_INTERRUPTIBLE); | 440 | nfs_wait_schedule, TASK_KILLABLE); |
444 | rpc_clnt_sigunmask(clnt, &oldmask); | ||
445 | 441 | ||
446 | return error; | 442 | return error; |
447 | } | 443 | } |
@@ -461,9 +457,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; | 457 | int need_atime = NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATIME; |
462 | int err; | 458 | int err; |
463 | 459 | ||
464 | /* Flush out writes to the server in order to update c/mtime */ | 460 | /* |
465 | 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); | ||
466 | nfs_wb_nocommit(inode); | 469 | nfs_wb_nocommit(inode); |
470 | mutex_unlock(&inode->i_mutex); | ||
471 | } | ||
467 | 472 | ||
468 | /* | 473 | /* |
469 | * We may force a getattr if the user cares about atime. | 474 | * We may force a getattr if the user cares about atime. |
@@ -659,7 +664,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
659 | if (status == -ESTALE) { | 664 | if (status == -ESTALE) { |
660 | nfs_zap_caches(inode); | 665 | nfs_zap_caches(inode); |
661 | if (!S_ISDIR(inode->i_mode)) | 666 | if (!S_ISDIR(inode->i_mode)) |
662 | set_bit(NFS_INO_STALE, &NFS_FLAGS(inode)); | 667 | set_bit(NFS_INO_STALE, &NFS_I(inode)->flags); |
663 | } | 668 | } |
664 | goto out; | 669 | goto out; |
665 | } | 670 | } |
@@ -814,8 +819,9 @@ static void nfs_wcc_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
814 | if (S_ISDIR(inode->i_mode)) | 819 | if (S_ISDIR(inode->i_mode)) |
815 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; | 820 | nfsi->cache_validity |= NFS_INO_INVALID_DATA; |
816 | } | 821 | } |
817 | if (inode->i_size == fattr->pre_size && nfsi->npages == 0) | 822 | if (inode->i_size == nfs_size_to_loff_t(fattr->pre_size) && |
818 | inode->i_size = fattr->size; | 823 | nfsi->npages == 0) |
824 | inode->i_size = nfs_size_to_loff_t(fattr->size); | ||
819 | } | 825 | } |
820 | } | 826 | } |
821 | 827 | ||
@@ -1019,7 +1025,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", | 1025 | dprintk("NFS: mtime change on server for file %s/%ld\n", |
1020 | inode->i_sb->s_id, inode->i_ino); | 1026 | inode->i_sb->s_id, inode->i_ino); |
1021 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; | 1027 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA; |
1022 | nfsi->cache_change_attribute = now; | 1028 | if (S_ISDIR(inode->i_mode)) |
1029 | nfs_force_lookup_revalidate(inode); | ||
1023 | } | 1030 | } |
1024 | /* If ctime has changed we should definitely clear access+acl caches */ | 1031 | /* If ctime has changed we should definitely clear access+acl caches */ |
1025 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) | 1032 | if (!timespec_equal(&inode->i_ctime, &fattr->ctime)) |
@@ -1028,7 +1035,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", | 1035 | dprintk("NFS: change_attr change on server for file %s/%ld\n", |
1029 | inode->i_sb->s_id, inode->i_ino); | 1036 | 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; | 1037 | invalid |= NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ACCESS|NFS_INO_INVALID_ACL; |
1031 | nfsi->cache_change_attribute = now; | 1038 | if (S_ISDIR(inode->i_mode)) |
1039 | nfs_force_lookup_revalidate(inode); | ||
1032 | } | 1040 | } |
1033 | 1041 | ||
1034 | /* Check if our cached file size is stale */ | 1042 | /* Check if our cached file size is stale */ |
@@ -1133,7 +1141,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr) | |||
1133 | void nfs4_clear_inode(struct inode *inode) | 1141 | void nfs4_clear_inode(struct inode *inode) |
1134 | { | 1142 | { |
1135 | /* If we are holding a delegation, return it! */ | 1143 | /* If we are holding a delegation, return it! */ |
1136 | nfs_inode_return_delegation(inode); | 1144 | nfs_inode_return_delegation_noreclaim(inode); |
1137 | /* First call standard NFS clear_inode() code */ | 1145 | /* First call standard NFS clear_inode() code */ |
1138 | nfs_clear_inode(inode); | 1146 | nfs_clear_inode(inode); |
1139 | } | 1147 | } |