aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/dir.c4
-rw-r--r--fs/nfs/inode.c69
-rw-r--r--include/linux/nfs_fs.h19
3 files changed, 53 insertions, 39 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}
diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h
index 229a1755842a..deef9567788a 100644
--- a/include/linux/nfs_fs.h
+++ b/include/linux/nfs_fs.h
@@ -112,8 +112,8 @@ struct nfs_inode {
112 /* 112 /*
113 * Various flags 113 * Various flags
114 */ 114 */
115 unsigned int flags; 115 unsigned long flags; /* atomic bit ops */
116 unsigned long cache_validity; 116 unsigned long cache_validity; /* bit mask */
117 117
118 /* 118 /*
119 * read_cache_jiffies is when we started read-caching this inode, 119 * read_cache_jiffies is when we started read-caching this inode,
@@ -175,8 +175,6 @@ struct nfs_inode {
175 /* Open contexts for shared mmap writes */ 175 /* Open contexts for shared mmap writes */
176 struct list_head open_files; 176 struct list_head open_files;
177 177
178 wait_queue_head_t nfs_i_wait;
179
180#ifdef CONFIG_NFS_V4 178#ifdef CONFIG_NFS_V4
181 struct nfs4_cached_acl *nfs4_acl; 179 struct nfs4_cached_acl *nfs4_acl;
182 /* NFSv4 state */ 180 /* NFSv4 state */
@@ -199,11 +197,11 @@ struct nfs_inode {
199#define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */ 197#define NFS_INO_REVAL_PAGECACHE 0x0020 /* must revalidate pagecache */
200 198
201/* 199/*
202 * Legal values of flags field 200 * Bit offsets in flags field
203 */ 201 */
204#define NFS_INO_REVALIDATING 0x0001 /* revalidating attrs */ 202#define NFS_INO_REVALIDATING (0) /* revalidating attrs */
205#define NFS_INO_ADVISE_RDPLUS 0x0002 /* advise readdirplus */ 203#define NFS_INO_ADVISE_RDPLUS (1) /* advise readdirplus */
206#define NFS_INO_STALE 0x0004 /* possible stale inode */ 204#define NFS_INO_STALE (2) /* possible stale inode */
207 205
208static inline struct nfs_inode *NFS_I(struct inode *inode) 206static inline struct nfs_inode *NFS_I(struct inode *inode)
209{ 207{
@@ -229,8 +227,7 @@ static inline struct nfs_inode *NFS_I(struct inode *inode)
229#define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp) 227#define NFS_ATTRTIMEO_UPDATE(inode) (NFS_I(inode)->attrtimeo_timestamp)
230 228
231#define NFS_FLAGS(inode) (NFS_I(inode)->flags) 229#define NFS_FLAGS(inode) (NFS_I(inode)->flags)
232#define NFS_REVALIDATING(inode) (NFS_FLAGS(inode) & NFS_INO_REVALIDATING) 230#define NFS_STALE(inode) (test_bit(NFS_INO_STALE, &NFS_FLAGS(inode)))
233#define NFS_STALE(inode) (NFS_FLAGS(inode) & NFS_INO_STALE)
234 231
235#define NFS_FILEID(inode) (NFS_I(inode)->fileid) 232#define NFS_FILEID(inode) (NFS_I(inode)->fileid)
236 233
@@ -252,7 +249,7 @@ static inline int nfs_server_capable(struct inode *inode, int cap)
252 249
253static inline int NFS_USE_READDIRPLUS(struct inode *inode) 250static inline int NFS_USE_READDIRPLUS(struct inode *inode)
254{ 251{
255 return NFS_FLAGS(inode) & NFS_INO_ADVISE_RDPLUS; 252 return test_bit(NFS_INO_ADVISE_RDPLUS, &NFS_FLAGS(inode));
256} 253}
257 254
258/** 255/**