From: Menyhart Zoltan Date: Sun, 12 Sep 2010 23:55:26 +0000 (-0400) Subject: statfs() gives ESTALE error X-Git-Tag: v2.6.35.5~46 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bcedd390d037d0e3b43da97a86e37a9bb7ceac91;p=thirdparty%2Fkernel%2Fstable.git statfs() gives ESTALE error commit fbf3fdd2443965d9ba6fb4b5fecd1f6e0847218f upstream. Hi, An NFS client executes a statfs("file", &buff) call. "file" exists / existed, the client has read / written it, but it has already closed it. user_path(pathname, &path) looks up "file" successfully in the directory-cache and restarts the aging timer of the directory-entry. Even if "file" has already been removed from the server, because the lookupcache=positive option I use, keeps the entries valid for a while. nfs_statfs() returns ESTALE if "file" has already been removed from the server. If the user application repeats the statfs("file", &buff) call, we are stuck: "file" remains young forever in the directory-cache. Signed-off-by: Zoltan Menyhart Signed-off-by: Trond Myklebust Signed-off-by: Greg Kroah-Hartman --- diff --git a/fs/nfs/super.c b/fs/nfs/super.c index 6bf11d745a3f5..381d9291ea177 100644 --- a/fs/nfs/super.c +++ b/fs/nfs/super.c @@ -431,7 +431,15 @@ static int nfs_statfs(struct dentry *dentry, struct kstatfs *buf) goto out_err; error = server->nfs_client->rpc_ops->statfs(server, fh, &res); + if (unlikely(error == -ESTALE)) { + struct dentry *pd_dentry; + pd_dentry = dget_parent(dentry); + if (pd_dentry != NULL) { + nfs_zap_caches(pd_dentry->d_inode); + dput(pd_dentry); + } + } nfs_free_fattr(res.fattr); if (error < 0) goto out_err;