diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-05-25 01:40:59 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-06-09 09:34:09 -0400 |
commit | 44b11874ff583b6e766a05856b04f3c492c32b84 (patch) | |
tree | b17effcaf70ed67f61b1ec2ed2dea1ea2f884d60 /fs/nfs | |
parent | 38478b24e37587f1c4fedf8ac070ca54f052ed28 (diff) |
NFS: Separate metadata and page cache revalidation mechanisms
Separate out the function of revalidating the inode metadata, and
revalidating the mapping. The former may be called by lookup(),
and only really needs to check that permissions, ctime, etc haven't changed
whereas the latter needs only done when we want to read data from the page
cache, and may need to sync and then invalidate the mapping.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/dir.c | 2 | ||||
-rw-r--r-- | fs/nfs/file.c | 24 | ||||
-rw-r--r-- | fs/nfs/inode.c | 16 | ||||
-rw-r--r-- | fs/nfs/symlink.c | 2 |
4 files changed, 16 insertions, 28 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index cae74dd4c7f5..1d3d8922a663 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c | |||
@@ -528,7 +528,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir) | |||
528 | 528 | ||
529 | lock_kernel(); | 529 | lock_kernel(); |
530 | 530 | ||
531 | res = nfs_revalidate_inode(NFS_SERVER(inode), inode); | 531 | res = nfs_revalidate_mapping(inode, filp->f_mapping); |
532 | if (res < 0) { | 532 | if (res < 0) { |
533 | unlock_kernel(); | 533 | unlock_kernel(); |
534 | return res; | 534 | return res; |
diff --git a/fs/nfs/file.c b/fs/nfs/file.c index fade02c15e6e..63154070145a 100644 --- a/fs/nfs/file.c +++ b/fs/nfs/file.c | |||
@@ -127,23 +127,6 @@ nfs_file_release(struct inode *inode, struct file *filp) | |||
127 | } | 127 | } |
128 | 128 | ||
129 | /** | 129 | /** |
130 | * nfs_revalidate_file - Revalidate the page cache & related metadata | ||
131 | * @inode - pointer to inode struct | ||
132 | * @file - pointer to file | ||
133 | */ | ||
134 | static int nfs_revalidate_file(struct inode *inode, struct file *filp) | ||
135 | { | ||
136 | struct nfs_inode *nfsi = NFS_I(inode); | ||
137 | int retval = 0; | ||
138 | |||
139 | if ((nfsi->cache_validity & (NFS_INO_REVAL_PAGECACHE|NFS_INO_INVALID_ATTR)) | ||
140 | || nfs_attribute_timeout(inode)) | ||
141 | retval = __nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
142 | nfs_revalidate_mapping(inode, filp->f_mapping); | ||
143 | return 0; | ||
144 | } | ||
145 | |||
146 | /** | ||
147 | * nfs_revalidate_size - Revalidate the file size | 130 | * nfs_revalidate_size - Revalidate the file size |
148 | * @inode - pointer to inode struct | 131 | * @inode - pointer to inode struct |
149 | * @file - pointer to struct file | 132 | * @file - pointer to struct file |
@@ -228,7 +211,7 @@ nfs_file_read(struct kiocb *iocb, char __user * buf, size_t count, loff_t pos) | |||
228 | dentry->d_parent->d_name.name, dentry->d_name.name, | 211 | dentry->d_parent->d_name.name, dentry->d_name.name, |
229 | (unsigned long) count, (unsigned long) pos); | 212 | (unsigned long) count, (unsigned long) pos); |
230 | 213 | ||
231 | result = nfs_revalidate_file(inode, iocb->ki_filp); | 214 | result = nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); |
232 | nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); | 215 | nfs_add_stats(inode, NFSIOS_NORMALREADBYTES, count); |
233 | if (!result) | 216 | if (!result) |
234 | result = generic_file_aio_read(iocb, buf, count, pos); | 217 | result = generic_file_aio_read(iocb, buf, count, pos); |
@@ -247,7 +230,7 @@ nfs_file_sendfile(struct file *filp, loff_t *ppos, size_t count, | |||
247 | dentry->d_parent->d_name.name, dentry->d_name.name, | 230 | dentry->d_parent->d_name.name, dentry->d_name.name, |
248 | (unsigned long) count, (unsigned long long) *ppos); | 231 | (unsigned long) count, (unsigned long long) *ppos); |
249 | 232 | ||
250 | res = nfs_revalidate_file(inode, filp); | 233 | res = nfs_revalidate_mapping(inode, filp->f_mapping); |
251 | if (!res) | 234 | if (!res) |
252 | res = generic_file_sendfile(filp, ppos, count, actor, target); | 235 | res = generic_file_sendfile(filp, ppos, count, actor, target); |
253 | return res; | 236 | return res; |
@@ -263,7 +246,7 @@ nfs_file_mmap(struct file * file, struct vm_area_struct * vma) | |||
263 | dfprintk(VFS, "nfs: mmap(%s/%s)\n", | 246 | dfprintk(VFS, "nfs: mmap(%s/%s)\n", |
264 | dentry->d_parent->d_name.name, dentry->d_name.name); | 247 | dentry->d_parent->d_name.name, dentry->d_name.name); |
265 | 248 | ||
266 | status = nfs_revalidate_file(inode, file); | 249 | status = nfs_revalidate_mapping(inode, file->f_mapping); |
267 | if (!status) | 250 | if (!status) |
268 | status = generic_file_mmap(file, vma); | 251 | status = generic_file_mmap(file, vma); |
269 | return status; | 252 | return status; |
@@ -373,7 +356,6 @@ nfs_file_write(struct kiocb *iocb, const char __user *buf, size_t count, loff_t | |||
373 | if (result) | 356 | if (result) |
374 | goto out; | 357 | goto out; |
375 | } | 358 | } |
376 | nfs_revalidate_mapping(inode, iocb->ki_filp->f_mapping); | ||
377 | 359 | ||
378 | result = count; | 360 | result = count; |
379 | if (!count) | 361 | if (!count) |
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c index eddd0e982d23..69036ef39866 100644 --- a/fs/nfs/inode.c +++ b/fs/nfs/inode.c | |||
@@ -1220,7 +1220,7 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1220 | status = -ESTALE; | 1220 | status = -ESTALE; |
1221 | /* Do we trust the cached ESTALE? */ | 1221 | /* Do we trust the cached ESTALE? */ |
1222 | if (NFS_ATTRTIMEO(inode) != 0) { | 1222 | if (NFS_ATTRTIMEO(inode) != 0) { |
1223 | if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA|NFS_INO_INVALID_ATIME)) { | 1223 | if (nfsi->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_ATIME)) { |
1224 | /* no */ | 1224 | /* no */ |
1225 | } else | 1225 | } else |
1226 | goto out; | 1226 | goto out; |
@@ -1251,8 +1251,6 @@ __nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1251 | } | 1251 | } |
1252 | spin_unlock(&inode->i_lock); | 1252 | spin_unlock(&inode->i_lock); |
1253 | 1253 | ||
1254 | nfs_revalidate_mapping(inode, inode->i_mapping); | ||
1255 | |||
1256 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) | 1254 | if (nfsi->cache_validity & NFS_INO_INVALID_ACL) |
1257 | nfs_zap_acl_cache(inode); | 1255 | nfs_zap_acl_cache(inode); |
1258 | 1256 | ||
@@ -1287,7 +1285,7 @@ int nfs_attribute_timeout(struct inode *inode) | |||
1287 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | 1285 | int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) |
1288 | { | 1286 | { |
1289 | nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); | 1287 | nfs_inc_stats(inode, NFSIOS_INODEREVALIDATE); |
1290 | if (!(NFS_I(inode)->cache_validity & (NFS_INO_INVALID_ATTR|NFS_INO_INVALID_DATA)) | 1288 | if (!(NFS_I(inode)->cache_validity & NFS_INO_INVALID_ATTR) |
1291 | && !nfs_attribute_timeout(inode)) | 1289 | && !nfs_attribute_timeout(inode)) |
1292 | return NFS_STALE(inode) ? -ESTALE : 0; | 1290 | return NFS_STALE(inode) ? -ESTALE : 0; |
1293 | return __nfs_revalidate_inode(server, inode); | 1291 | return __nfs_revalidate_inode(server, inode); |
@@ -1298,9 +1296,16 @@ int nfs_revalidate_inode(struct nfs_server *server, struct inode *inode) | |||
1298 | * @inode - pointer to host inode | 1296 | * @inode - pointer to host inode |
1299 | * @mapping - pointer to mapping | 1297 | * @mapping - pointer to mapping |
1300 | */ | 1298 | */ |
1301 | void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | 1299 | int nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) |
1302 | { | 1300 | { |
1303 | struct nfs_inode *nfsi = NFS_I(inode); | 1301 | struct nfs_inode *nfsi = NFS_I(inode); |
1302 | int ret = 0; | ||
1303 | |||
1304 | if (NFS_STALE(inode)) | ||
1305 | ret = -ESTALE; | ||
1306 | if ((nfsi->cache_validity & NFS_INO_REVAL_PAGECACHE) | ||
1307 | || nfs_attribute_timeout(inode)) | ||
1308 | ret = __nfs_revalidate_inode(NFS_SERVER(inode), inode); | ||
1304 | 1309 | ||
1305 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { | 1310 | if (nfsi->cache_validity & NFS_INO_INVALID_DATA) { |
1306 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); | 1311 | nfs_inc_stats(inode, NFSIOS_DATAINVALIDATE); |
@@ -1321,6 +1326,7 @@ void nfs_revalidate_mapping(struct inode *inode, struct address_space *mapping) | |||
1321 | inode->i_sb->s_id, | 1326 | inode->i_sb->s_id, |
1322 | (long long)NFS_FILEID(inode)); | 1327 | (long long)NFS_FILEID(inode)); |
1323 | } | 1328 | } |
1329 | return ret; | ||
1324 | } | 1330 | } |
1325 | 1331 | ||
1326 | /** | 1332 | /** |
diff --git a/fs/nfs/symlink.c b/fs/nfs/symlink.c index 18dc95b0b646..636c479995bc 100644 --- a/fs/nfs/symlink.c +++ b/fs/nfs/symlink.c | |||
@@ -52,7 +52,7 @@ static void *nfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
52 | { | 52 | { |
53 | struct inode *inode = dentry->d_inode; | 53 | struct inode *inode = dentry->d_inode; |
54 | struct page *page; | 54 | struct page *page; |
55 | void *err = ERR_PTR(nfs_revalidate_inode(NFS_SERVER(inode), inode)); | 55 | void *err = ERR_PTR(nfs_revalidate_mapping(inode, inode->i_mapping)); |
56 | if (err) | 56 | if (err) |
57 | goto read_failed; | 57 | goto read_failed; |
58 | page = read_cache_page(&inode->i_data, 0, | 58 | page = read_cache_page(&inode->i_data, 0, |