Prior to commit 5ceb9d7fdaaf ("NFS: Refactor nfs_lookup_revalidate()") and error from nfs_lookup_verify_inode() other than -ESTALE would result in nfs_lookup_revalidate() returning that error code (-ESTALE is mapped to zero). Since that commit, all errors result in zero being returned.
When nfs_lookup_revalidate() returns zero, the dentry is invalidated and, significantly, if the dentry is a directory that is mounted on, that mountpoint is lost. If you: - mount an NFS filesystem which contains a directory - mount something (e.g. tmpfs) on that directory - use iptables (or scissors) to block traffic to the server - ls -l the-mounted-on-directory - interrupt the 'ls -l' you will find that the directory has been unmounted. This can be fixed by returning the actual error code from nfs_lookup_verify_inode() rather then zero (except for -ESTALE). Fixes: 5ceb9d7fdaaf ("NFS: Refactor nfs_lookup_revalidate()") Signed-off-by: NeilBrown <ne...@suse.de> --- fs/nfs/dir.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index cb52db9a0cfb..d24acf556e9e 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -1350,7 +1350,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, unsigned int flags) { struct inode *inode; - int error; + int error = 0; nfs_inc_stats(dir, NFSIOS_DENTRYREVALIDATE); inode = d_inode(dentry); @@ -1372,8 +1372,10 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, nfs_check_verifier(dir, dentry, flags & LOOKUP_RCU)) { error = nfs_lookup_verify_inode(inode, flags); if (error) { - if (error == -ESTALE) + if (error == -ESTALE) { nfs_zap_caches(dir); + error = 0; + } goto out_bad; } nfs_advise_use_readdirplus(dir); @@ -1395,7 +1397,7 @@ nfs_do_lookup_revalidate(struct inode *dir, struct dentry *dentry, out_bad: if (flags & LOOKUP_RCU) return -ECHILD; - return nfs_lookup_revalidate_done(dir, dentry, inode, 0); + return nfs_lookup_revalidate_done(dir, dentry, inode, error); } static int -- 2.29.2
signature.asc
Description: PGP signature