From: "J. Bruce Fields" <bfields@fieldses.org>
To: Chuck Lever <chuck.lever@oracle.com>
Cc: Jeff Layton <jlayton@redhat.com>, NeilBrown <neilb@suse.de>,
"Myklebust, Trond" <Trond.Myklebust@netapp.com>,
Alexander Viro <viro@zeniv.linux.org.uk>,
NFS <linux-nfs@vger.kernel.org>,
steved@redhat.com
Subject: Re: More fun with unmounting ESTALE directories.
Date: Mon, 18 Feb 2013 16:58:29 -0500 [thread overview]
Message-ID: <20130218215829.GC3391@fieldses.org> (raw)
In-Reply-To: <343C8851-62FD-448D-BFD6-5CBAB8C9DCB5@oracle.com>
On Mon, Feb 18, 2013 at 10:36:52AM -0500, Chuck Lever wrote:
> Before removing FS_REVAL_DOT, I recommend some archaeology: find out what was fixed by adding that for NFS. I worked on something related years ago and have a vague recollection about this that there is a situation where revalidating dot is important.
>
> Unfortunately I don't see it in a quick browse through the commit log for fs/nfs/dir.c. It may be in BitKeeper.
Everybody should have one of these historical git repos set up--they're
awesome.
(No idea if this is helpful, I just note this seems to be where
FS_REVAL_DOT got added to fs_flags.)
--b.
commit e14720a157f5d8745006f44520dfa3b8ac498328
Author: Trond Myklebust <trond.myklebust@fys.uio.no>
Date: Tue Aug 19 21:35:45 2003 -0700
[PATCH] Support dentry revalidation under open(".")
link_path_walk() currently treats the special filenames ".", ".."
and "/" differently in that it does not call down to the filesystem in
order to revalidate the cached dentry, but just assumes that it is
fine.
For most filesystems this is OK, but it the case of the stateless
NFS, this means that it circumvents path staleness detection, and the
attribute+data cache revalidation code on such common commands as
opendir(".").
This change provides a way to do such revalidation for NFS without
impacting other filesystems.
Note: the failure to revalidate the path here does not result in a
call to d_invalidate() unlike (all?) other calls to d_revalidate(). It
only results in an ESTALE error being returned to the caller.
diff --git a/fs/namei.c b/fs/namei.c
index f922236..9e1fcb9 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -572,7 +572,7 @@ int link_path_walk(const char * name, struct nameidata *nd)
while (*name=='/')
name++;
if (!*name)
- goto return_base;
+ goto return_reval;
inode = nd->dentry->d_inode;
if (current->link_count)
@@ -693,7 +693,7 @@ last_component:
inode = nd->dentry->d_inode;
/* fallthrough */
case 1:
- goto return_base;
+ goto return_reval;
}
if (nd->dentry->d_op && nd->dentry->d_op->d_hash) {
err = nd->dentry->d_op->d_hash(nd->dentry, &this);
@@ -737,6 +737,20 @@ lookup_parent:
nd->last_type = LAST_DOT;
else if (this.len == 2 && this.name[1] == '.')
nd->last_type = LAST_DOTDOT;
+ else
+ goto return_base;
+return_reval:
+ /*
+ * We bypassed the ordinary revalidation routines.
+ * We may need to check the cached dentry for staleness.
+ */
+ if (nd->dentry && nd->dentry->d_sb &&
+ (nd->dentry->d_sb->s_type->fs_flags & FS_REVAL_DOT)) {
+ err = -ESTALE;
+ /* Note: we do not d_invalidate() */
+ if (!nd->dentry->d_op->d_revalidate(nd->dentry, nd))
+ break;
+ }
return_base:
return 0;
out_dput:
diff --git a/fs/nfs/inode.c b/fs/nfs/inode.c
index 1bae8c1..c8e3191 100644
--- a/fs/nfs/inode.c
+++ b/fs/nfs/inode.c
@@ -1343,7 +1343,7 @@ static struct file_system_type nfs_fs_type = {
.name = "nfs",
.get_sb = nfs_get_sb,
.kill_sb = nfs_kill_super,
- .fs_flags = FS_ODD_RENAME,
+ .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT,
};
#ifdef CONFIG_NFS_V4
@@ -1575,7 +1575,7 @@ static struct file_system_type nfs4_fs_type = {
.name = "nfs4",
.get_sb = nfs4_get_sb,
.kill_sb = nfs_kill_super,
- .fs_flags = FS_ODD_RENAME,
+ .fs_flags = FS_ODD_RENAME|FS_REVAL_DOT,
};
#define nfs4_zero_state(nfsi) \
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 8df205c..a9e02e3 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -89,6 +89,7 @@ extern int leases_enable, dir_notify_enable, lease_break_time;
/* public flags for file_system_type */
#define FS_REQUIRES_DEV 1
+#define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */
#define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon
* as nfs_rename() will be cleaned up
*/
next prev parent reply other threads:[~2013-02-18 21:58 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-02-12 0:38 More fun with unmounting ESTALE directories NeilBrown
2013-02-14 15:42 ` Jeff Layton
2013-02-18 2:25 ` NeilBrown
2013-02-18 12:41 ` Jeff Layton
2013-02-18 15:36 ` Chuck Lever
2013-02-18 21:58 ` J. Bruce Fields [this message]
2013-02-18 22:05 ` Jeff Layton
2013-02-18 22:16 ` Chuck Lever
2013-02-18 18:46 ` Al Viro
2013-02-18 19:46 ` Jeff Layton
2013-02-18 20:15 ` Al Viro
2013-02-18 23:14 ` NeilBrown
2013-02-19 12:33 ` Jeff Layton
2013-02-18 23:10 ` NeilBrown
2013-02-18 23:17 ` Myklebust, Trond
2013-02-18 23:31 ` NeilBrown
2013-02-19 14:27 ` Jeff Layton
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20130218215829.GC3391@fieldses.org \
--to=bfields@fieldses.org \
--cc=Trond.Myklebust@netapp.com \
--cc=chuck.lever@oracle.com \
--cc=jlayton@redhat.com \
--cc=linux-nfs@vger.kernel.org \
--cc=neilb@suse.de \
--cc=steved@redhat.com \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox