aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index cd3469720cbf..d971547ce609 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -154,6 +154,8 @@ typedef struct {
154 decode_dirent_t decode; 154 decode_dirent_t decode;
155 int plus; 155 int plus;
156 int error; 156 int error;
157 unsigned long timestamp;
158 int timestamp_valid;
157} nfs_readdir_descriptor_t; 159} nfs_readdir_descriptor_t;
158 160
159/* Now we cache directories properly, by stuffing the dirent 161/* Now we cache directories properly, by stuffing the dirent
@@ -195,6 +197,8 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
195 } 197 }
196 goto error; 198 goto error;
197 } 199 }
200 desc->timestamp = timestamp;
201 desc->timestamp_valid = 1;
198 SetPageUptodate(page); 202 SetPageUptodate(page);
199 spin_lock(&inode->i_lock); 203 spin_lock(&inode->i_lock);
200 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME; 204 NFS_I(inode)->cache_validity |= NFS_INO_INVALID_ATIME;
@@ -225,6 +229,10 @@ int dir_decode(nfs_readdir_descriptor_t *desc)
225 if (IS_ERR(p)) 229 if (IS_ERR(p))
226 return PTR_ERR(p); 230 return PTR_ERR(p);
227 desc->ptr = p; 231 desc->ptr = p;
232 if (desc->timestamp_valid)
233 desc->entry->fattr->time_start = desc->timestamp;
234 else
235 desc->entry->fattr->valid &= ~NFS_ATTR_FATTR;
228 return 0; 236 return 0;
229} 237}
230 238
@@ -316,6 +324,10 @@ int find_dirent_page(nfs_readdir_descriptor_t *desc)
316 __FUNCTION__, desc->page_index, 324 __FUNCTION__, desc->page_index,
317 (long long) *desc->dir_cookie); 325 (long long) *desc->dir_cookie);
318 326
327 /* If we find the page in the page_cache, we cannot be sure
328 * how fresh the data is, so we will ignore readdir_plus attributes.
329 */
330 desc->timestamp_valid = 0;
319 page = read_cache_page(inode->i_mapping, desc->page_index, 331 page = read_cache_page(inode->i_mapping, desc->page_index,
320 (filler_t *)nfs_readdir_filler, desc); 332 (filler_t *)nfs_readdir_filler, desc);
321 if (IS_ERR(page)) { 333 if (IS_ERR(page)) {
@@ -468,6 +480,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
468 struct rpc_cred *cred = nfs_file_cred(file); 480 struct rpc_cred *cred = nfs_file_cred(file);
469 struct page *page = NULL; 481 struct page *page = NULL;
470 int status; 482 int status;
483 unsigned long timestamp;
471 484
472 dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", 485 dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
473 (unsigned long long)*desc->dir_cookie); 486 (unsigned long long)*desc->dir_cookie);
@@ -477,6 +490,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
477 status = -ENOMEM; 490 status = -ENOMEM;
478 goto out; 491 goto out;
479 } 492 }
493 timestamp = jiffies;
480 desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie, 494 desc->error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, *desc->dir_cookie,
481 page, 495 page,
482 NFS_SERVER(inode)->dtsize, 496 NFS_SERVER(inode)->dtsize,
@@ -487,6 +501,8 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
487 desc->page = page; 501 desc->page = page;
488 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ 502 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
489 if (desc->error >= 0) { 503 if (desc->error >= 0) {
504 desc->timestamp = timestamp;
505 desc->timestamp_valid = 1;
490 if ((status = dir_decode(desc)) == 0) 506 if ((status = dir_decode(desc)) == 0)
491 desc->entry->prev_cookie = *desc->dir_cookie; 507 desc->entry->prev_cookie = *desc->dir_cookie;
492 } else 508 } else