From fccca7fc6aab4e6b519e2d606ef34632e4f50e33 Mon Sep 17 00:00:00 2001 From: Trond Myklebust Date: Sat, 26 Jan 2008 17:37:47 -0500 Subject: 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 --- fs/nfs/dir.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) (limited to 'fs/nfs/dir.c') diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index f697b5c74b7..d9abdb1d6a2 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) -- cgit v1.2.3