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.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index 74f92b717f78..2ab70d46ecbc 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -156,6 +156,7 @@ typedef struct {
156 decode_dirent_t decode; 156 decode_dirent_t decode;
157 int plus; 157 int plus;
158 unsigned long timestamp; 158 unsigned long timestamp;
159 unsigned long gencount;
159 int timestamp_valid; 160 int timestamp_valid;
160} nfs_readdir_descriptor_t; 161} nfs_readdir_descriptor_t;
161 162
@@ -177,7 +178,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
177 struct file *file = desc->file; 178 struct file *file = desc->file;
178 struct inode *inode = file->f_path.dentry->d_inode; 179 struct inode *inode = file->f_path.dentry->d_inode;
179 struct rpc_cred *cred = nfs_file_cred(file); 180 struct rpc_cred *cred = nfs_file_cred(file);
180 unsigned long timestamp; 181 unsigned long timestamp, gencount;
181 int error; 182 int error;
182 183
183 dfprintk(DIRCACHE, "NFS: %s: reading cookie %Lu into page %lu\n", 184 dfprintk(DIRCACHE, "NFS: %s: reading cookie %Lu into page %lu\n",
@@ -186,6 +187,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
186 187
187 again: 188 again:
188 timestamp = jiffies; 189 timestamp = jiffies;
190 gencount = nfs_inc_attr_generation_counter();
189 error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page, 191 error = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, desc->entry->cookie, page,
190 NFS_SERVER(inode)->dtsize, desc->plus); 192 NFS_SERVER(inode)->dtsize, desc->plus);
191 if (error < 0) { 193 if (error < 0) {
@@ -199,6 +201,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page *page)
199 goto error; 201 goto error;
200 } 202 }
201 desc->timestamp = timestamp; 203 desc->timestamp = timestamp;
204 desc->gencount = gencount;
202 desc->timestamp_valid = 1; 205 desc->timestamp_valid = 1;
203 SetPageUptodate(page); 206 SetPageUptodate(page);
204 /* Ensure consistent page alignment of the data. 207 /* Ensure consistent page alignment of the data.
@@ -224,9 +227,10 @@ int dir_decode(nfs_readdir_descriptor_t *desc)
224 if (IS_ERR(p)) 227 if (IS_ERR(p))
225 return PTR_ERR(p); 228 return PTR_ERR(p);
226 desc->ptr = p; 229 desc->ptr = p;
227 if (desc->timestamp_valid) 230 if (desc->timestamp_valid) {
228 desc->entry->fattr->time_start = desc->timestamp; 231 desc->entry->fattr->time_start = desc->timestamp;
229 else 232 desc->entry->fattr->gencount = desc->gencount;
233 } else
230 desc->entry->fattr->valid &= ~NFS_ATTR_FATTR; 234 desc->entry->fattr->valid &= ~NFS_ATTR_FATTR;
231 return 0; 235 return 0;
232} 236}
@@ -471,7 +475,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
471 struct rpc_cred *cred = nfs_file_cred(file); 475 struct rpc_cred *cred = nfs_file_cred(file);
472 struct page *page = NULL; 476 struct page *page = NULL;
473 int status; 477 int status;
474 unsigned long timestamp; 478 unsigned long timestamp, gencount;
475 479
476 dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n", 480 dfprintk(DIRCACHE, "NFS: uncached_readdir() searching for cookie %Lu\n",
477 (unsigned long long)*desc->dir_cookie); 481 (unsigned long long)*desc->dir_cookie);
@@ -482,6 +486,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
482 goto out; 486 goto out;
483 } 487 }
484 timestamp = jiffies; 488 timestamp = jiffies;
489 gencount = nfs_inc_attr_generation_counter();
485 status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred, 490 status = NFS_PROTO(inode)->readdir(file->f_path.dentry, cred,
486 *desc->dir_cookie, page, 491 *desc->dir_cookie, page,
487 NFS_SERVER(inode)->dtsize, 492 NFS_SERVER(inode)->dtsize,
@@ -490,6 +495,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent,
490 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */ 495 desc->ptr = kmap(page); /* matching kunmap in nfs_do_filldir */
491 if (status >= 0) { 496 if (status >= 0) {
492 desc->timestamp = timestamp; 497 desc->timestamp = timestamp;
498 desc->gencount = gencount;
493 desc->timestamp_valid = 1; 499 desc->timestamp_valid = 1;
494 if ((status = dir_decode(desc)) == 0) 500 if ((status = dir_decode(desc)) == 0)
495 desc->entry->prev_cookie = *desc->dir_cookie; 501 desc->entry->prev_cookie = *desc->dir_cookie;
@@ -655,7 +661,7 @@ static int nfs_fsync_dir(struct file *filp, struct dentry *dentry, int datasync)
655 */ 661 */
656void nfs_force_lookup_revalidate(struct inode *dir) 662void nfs_force_lookup_revalidate(struct inode *dir)
657{ 663{
658 NFS_I(dir)->cache_change_attribute = jiffies; 664 NFS_I(dir)->cache_change_attribute++;
659} 665}
660 666
661/* 667/*
@@ -667,6 +673,8 @@ static int nfs_check_verifier(struct inode *dir, struct dentry *dentry)
667{ 673{
668 if (IS_ROOT(dentry)) 674 if (IS_ROOT(dentry))
669 return 1; 675 return 1;
676 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONE)
677 return 0;
670 if (!nfs_verify_change_attribute(dir, dentry->d_time)) 678 if (!nfs_verify_change_attribute(dir, dentry->d_time))
671 return 0; 679 return 0;
672 /* Revalidate nfsi->cache_change_attribute before we declare a match */ 680 /* Revalidate nfsi->cache_change_attribute before we declare a match */
@@ -750,6 +758,8 @@ int nfs_neg_need_reval(struct inode *dir, struct dentry *dentry,
750 /* Don't revalidate a negative dentry if we're creating a new file */ 758 /* Don't revalidate a negative dentry if we're creating a new file */
751 if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0) 759 if (nd != NULL && nfs_lookup_check_intent(nd, LOOKUP_CREATE) != 0)
752 return 0; 760 return 0;
761 if (NFS_SERVER(dir)->flags & NFS_MOUNT_LOOKUP_CACHE_NONEG)
762 return 1;
753 return !nfs_check_verifier(dir, dentry); 763 return !nfs_check_verifier(dir, dentry);
754} 764}
755 765