aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
Diffstat (limited to 'fs')
-rw-r--r--fs/nfs/dir.c4
-rw-r--r--fs/nfs/inode.c69
2 files changed, 45 insertions, 28 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 5732e13cd0da..27cf5577f239 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -182,7 +182,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
182 /* We requested READDIRPLUS, but the server doesn't grok it */ 182 /* We requested READDIRPLUS, but the server doesn't grok it */
183 if (error == -ENOTSUPP && desc->plus) { 183 if (error == -ENOTSUPP && desc->plus) {
184 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS; 184 NFS_SERVER(inode)->caps &= ~NFS_CAP_READDIRPLUS;
185 NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; 185 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
186 desc->plus = 0; 186 desc->plus = 0;
187 goto again; 187 goto again;
188 } 188 }
@@ -545,7 +545,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
545 break; 545 break;
546 } 546 }
547 if (res == -ETOOSMALL && desc->plus) { 547 if (res == -ETOOSMALL && desc->plus) {
548 NFS_FLAGS(inode) &= ~NFS_INO_ADVISE_RDPLUS; 548 clear_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
549 nfs_zap_caches(inode); 549 nfs_zap_caches(inode);
550 desc->plus = 0; 550 desc->plus = 0;
551 desc->entry->eof = 0; 551 desc->entry->eof = 0;
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 622184553516..ee27578277f3 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -739,7 +739,7 @@ nfs_fhget(struct super_block *sb, struct nfs_fh *fh, struct nfs_fattr *fattr)
739 inode->i_fop = &nfs_dir_operations; 739 inode->i_fop = &nfs_dir_operations;
740 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS) 740 if (nfs_server_capable(inode, NFS_CAP_READDIRPLUS)
741 && fattr->size <= NFS_LIMIT_READDIRPLUS) 741 && fattr->size <= NFS_LIMIT_READDIRPLUS)
742 NFS_FLAGS(inode) |= NFS_INO_ADVISE_RDPLUS; 742 set_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
743 } else if (S_ISLNK(inode->i_mode)) 743 } else if (S_ISLNK(inode->i_mode))
744 inode->i_op = &nfs_symlink_inode_operations; 744 inode->i_op = &nfs_symlink_inode_operations;
745 else 745 else
@@ -849,26 +849,43 @@ void nfs_setattr_update_inode(struct inode *inode, struct iattr *attr)
849 } 849 }
850} 850}
851 851
852static int nfs_wait_schedule(void *word)
853{
854 if (signal_pending(current))
855 return -ERESTARTSYS;
856 schedule();
857 return 0;
858}
859
852/* 860/*
853 * Wait for the inode to get unlocked. 861 * Wait for the inode to get unlocked.
854 * (Used for NFS_INO_LOCKED and NFS_INO_REVALIDATING).
855 */ 862 */
856static int 863static int nfs_wait_on_inode(struct inode *inode)
857nfs_wait_on_inode(struct inode *inode, int flag)
858{ 864{
859 struct rpc_clnt *clnt = NFS_CLIENT(inode); 865 struct rpc_clnt *clnt = NFS_CLIENT(inode);
860 struct nfs_inode *nfsi = NFS_I(inode); 866 struct nfs_inode *nfsi = NFS_I(inode);
861 867 sigset_t oldmask;
862 int error; 868 int error;
863 if (!(NFS_FLAGS(inode) & flag)) 869
864 return 0;
865 atomic_inc(&inode->i_count); 870 atomic_inc(&inode->i_count);
866 error = nfs_wait_event(clnt, nfsi->nfs_i_wait, 871 rpc_clnt_sigmask(clnt, &oldmask);
867 !(NFS_FLAGS(inode) & flag)); 872 error = wait_on_bit_lock(&nfsi->flags, NFS_INO_REVALIDATING,
873 nfs_wait_schedule, TASK_INTERRUPTIBLE);
874 rpc_clnt_sigunmask(clnt, &oldmask);
868 iput(inode); 875 iput(inode);
876
869 return error; 877 return error;
870} 878}
871 879
880static void nfs_wake_up_inode(struct inode *inode)
881{
882 struct nfs_inode *nfsi = NFS_I(inode);
883
884 clear_bit(NFS_INO_REVALIDATING, &nfsi->flags);
885 smp_mb__after_clear_bit();
886 wake_up_bit(&nfsi->flags, NFS_INO_REVALIDATING);
887}
888
872int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) 889int nfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat)
873{ 890{
874 struct inode *inode = dentry->d_inode; 891 struct inode *inode = dentry->d_inode;
@@ -1029,18 +1046,19 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1029 if (NFS_STALE(inode)) 1046 if (NFS_STALE(inode))
1030 goto out_nowait; 1047 goto out_nowait;
1031 1048
1032 while (NFS_REVALIDATING(inode)) { 1049 status = nfs_wait_on_inode(inode);
1033 status = nfs_wait_on_inode(inode, NFS_INO_REVALIDATING); 1050 if (status < 0)
1034 if (status < 0) 1051 goto out;
1035 goto out_nowait; 1052 if (NFS_STALE(inode)) {
1036 if (NFS_ATTRTIMEO(inode) == 0) 1053 status = -ESTALE;
1037 continue; 1054 /* Do we trust the cached ESTALE? */
1038 if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) 1055 if (NFS_ATTRTIMEO(inode) != 0) {
1039 continue; 1056 if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) {
1040 status = NFS_STALE(inode) ? -ESTALE : 0; 1057 /* no */
1041 goto out_nowait; 1058 } else
1059 goto out;
1060 }
1042 } 1061 }
1043 NFS_FLAGS(inode) |= NFS_INO_REVALIDATING;
1044 1062
1045 /* Protect against RPC races by saving the change attribute */ 1063 /* Protect against RPC races by saving the change attribute */
1046 verifier = nfs_save_change_attribute(inode); 1064 verifier = nfs_save_change_attribute(inode);
@@ -1052,7 +1070,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1052 if (status == -ESTALE) { 1070 if (status == -ESTALE) {
1053 nfs_zap_caches(inode); 1071 nfs_zap_caches(inode);
1054 if (!S_ISDIR(inode->i_mode)) 1072 if (!S_ISDIR(inode->i_mode))
1055 NFS_FLAGS(inode) |= NFS_INO_STALE; 1073 set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
1056 } 1074 }
1057 goto out; 1075 goto out;
1058 } 1076 }
@@ -1083,9 +1101,9 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode)
1083 inode->i_sb->s_id, 1101 inode->i_sb->s_id,
1084 (long long)NFS_FILEID(inode)); 1102 (long long)NFS_FILEID(inode));
1085 1103
1086out: 1104 out:
1087 NFS_FLAGS(inode) &= ~NFS_INO_REVALIDATING; 1105 nfs_wake_up_inode(inode);
1088 wake_up(&nfsi->nfs_i_wait); 1106
1089 out_nowait: 1107 out_nowait:
1090 unlock_kernel(); 1108 unlock_kernel();
1091 return status; 1109 return status;
@@ -1404,7 +1422,7 @@ static int nfs_update_inode(struct inode *inode, struct nfs_fattr *fattr, unsign
1404 */ 1422 */
1405 nfs_invalidate_inode(inode); 1423 nfs_invalidate_inode(inode);
1406 out_err: 1424 out_err:
1407 NFS_FLAGS(inode) |= NFS_INO_STALE; 1425 set_bit(NFS_INO_STALE, &NFS_FLAGS(inode));
1408 return -ESTALE; 1426 return -ESTALE;
1409} 1427}
1410 1428
@@ -1996,7 +2014,6 @@ static void init_once(void * foo, kmem_cache_t * cachep, unsigned long flags)
1996 nfsi->ndirty = 0; 2014 nfsi->ndirty = 0;
1997 nfsi->ncommit = 0; 2015 nfsi->ncommit = 0;
1998 nfsi->npages = 0; 2016 nfsi->npages = 0;
1999 init_waitqueue_head(&nfsi->nfs_i_wait);
2000 nfs4_init_once(nfsi); 2017 nfs4_init_once(nfsi);
2001 } 2018 }
2002} 2019}