summary refs log tree commit diff
path: root/fs/nfs/dir.c
diff options
context:
space:
mode:
authorTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-26 17:37:47 -0500
committerTrond Myklebust <Trond.Myklebust@netapp.com>2008-01-30 02:05:21 -0500
commitfccca7fc6aab4e6b519e2d606ef34632e4f50e33 (patch)
tree4d12d88039d229263a610647df6c751585f714dc /fs/nfs/dir.c
parent5b10ca19ea4859d3884d10a3eb8495de92089792 (diff)
downloadlinux-fccca7fc6aab4e6b519e2d606ef34632e4f50e33.tar.gz
NFS: Fix a sillyrename race...
Ensure that readdir revalidates its data cache after blocking on
sillyrename.

Also fix a typo in nfs_do_call_unlink(): swap the ^= for an |=. The result
is the same, since we've already checked that the flag is unset, but it
makes the code more readable.

Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs/dir.c')
-rw-r--r--fs/nfs/dir.c11
1 files changed, 5 insertions, 6 deletions
diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c
index f697b5c74b7c..d9abdb1d6a2a 100644
--- a/fs/nfs/dir.c
+++ b/fs/nfs/dir.c
@@ -537,12 +537,6 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 
 	lock_kernel();
 
-	res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping);
-	if (res < 0) {
-		unlock_kernel();
-		return res;
-	}
-
 	/*
 	 * filp->f_pos points to the dirent entry number.
 	 * *desc->dir_cookie has the cookie for the next entry. We have
@@ -564,6 +558,10 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 	desc->entry = &my_entry;
 
 	nfs_block_sillyrename(dentry);
+	res = nfs_revalidate_mapping_nolock(inode, filp->f_mapping);
+	if (res < 0)
+		goto out;
+
 	while(!desc->entry->eof) {
 		res = readdir_search_pagecache(desc);
 
@@ -594,6 +592,7 @@ static int nfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
 			break;
 		}
 	}
+out:
 	nfs_unblock_sillyrename(dentry);
 	unlock_kernel();
 	if (res > 0)