From: Valerie Aurora <vaurora@redhat.com>
To: Jan Blunck <jblunck@suse.de>,
Alexander Viro <viro@zeniv.linux.org.uk>,
Christoph Hellwig <hch@infradead.org>,
Andy Whitcroft <apw@canonical.com>,
Scott James Remnant <scott@canonica
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org,
Jan Blunck <jblunck@suse.de>
Subject: [PATCH 31/41] fallthru: Support for fallthru entries in union mount lookup
Date: Wed, 21 Oct 2009 12:19:29 -0700 [thread overview]
Message-ID: <1256152779-10054-32-git-send-email-vaurora@redhat.com> (raw)
In-Reply-To: <1256152779-10054-31-git-send-email-vaurora@redhat.com>
A fallthru directory entry overrides the opaque flag for its parent
directory (for this directory entry only). Before, we stopped
building the union stack when we encountered an opaque directory; now
we include directories below opaque directories in the union stack and
check for opacity during lookup.
Signed-off-by: Jan Blunck <jblunck@suse.de>
Signed-off-by: Valerie Aurora <vaurora@redhat.com>
---
fs/dcache.c | 7 +++----
fs/namei.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--------------
2 files changed, 48 insertions(+), 18 deletions(-)
diff --git a/fs/dcache.c b/fs/dcache.c
index d80a3bb..ca8a661 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -1086,7 +1086,7 @@ struct dentry *d_alloc_name(struct dentry *parent, const char *name)
static void __d_instantiate(struct dentry *dentry, struct inode *inode)
{
if (inode) {
- dentry->d_flags &= ~DCACHE_WHITEOUT;
+ dentry->d_flags &= ~(DCACHE_WHITEOUT|DCACHE_FALLTHRU);
list_add(&dentry->d_alias, &inode->i_dentry);
}
dentry->d_inode = inode;
@@ -1638,9 +1638,8 @@ void d_delete(struct dentry * dentry)
static void __d_rehash(struct dentry * entry, struct hlist_head *list)
{
-
- entry->d_flags &= ~DCACHE_UNHASHED;
- hlist_add_head_rcu(&entry->d_hash, list);
+ entry->d_flags &= ~DCACHE_UNHASHED;
+ hlist_add_head_rcu(&entry->d_hash, list);
}
static void _d_rehash(struct dentry * entry)
diff --git a/fs/namei.c b/fs/namei.c
index 8d95eb1..61e94aa 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -416,6 +416,28 @@ static struct dentry *cache_lookup(struct dentry *parent, struct qstr *name,
return dentry;
}
+/*
+ * Theory of operation for opaque, whiteout, and fallthru:
+ *
+ * whiteout: Unconditionally stop lookup here - ENOENT
+ *
+ * opaque: Don't lookup in directories lower in the union stack
+ *
+ * fallthru: While looking up an entry, ignore the opaque flag for the
+ * current directory only.
+ *
+ * A union stack is a linked list of directory dentries which appear
+ * in the same place in the namespace. When constructing the union
+ * stack, we include directories below opaque directories so that we
+ * can properly handle fallthrus. All non-fallthru lookups have to
+ * check for the opaque flag on the parent directory and obey it.
+ *
+ * In general, the code pattern is to lookup the the topmost entry
+ * first (either the first visible non-negative dentry or a negative
+ * dentry in the topmost layer of the union), then build the union
+ * stack for the newly looked-up entry (if it is a directory).
+ */
+
/**
* __cache_lookup_topmost - lookup the topmost (non-)negative dentry
*
@@ -445,6 +467,10 @@ static int __cache_lookup_topmost(struct nameidata *nd, struct qstr *name,
if (!dentry || (dentry->d_inode || d_is_whiteout(dentry)))
return !dentry;
+ /* Keep going through opaque directories if we found a fallthru */
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(dentry))
+ return !dentry;
+
/* look for the first non-negative or whiteout dentry */
while (follow_union_down(&nd->path.mnt, &nd->path.dentry)) {
@@ -470,6 +496,10 @@ static int __cache_lookup_topmost(struct nameidata *nd, struct qstr *name,
if (dentry->d_inode || d_is_whiteout(dentry))
goto out_dput;
+ /* Stop the lookup on opaque parent and non-fallthru child */
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(dentry))
+ goto out_dput;
+
dput(dentry);
}
@@ -528,9 +558,6 @@ static int __cache_lookup_build_union(struct nameidata *nd, struct qstr *name,
path_put(&last);
last.dentry = dentry;
last.mnt = mntget(nd->path.mnt);
-
- if (IS_OPAQUE(last.dentry->d_inode))
- break;
}
if (last.dentry != path->dentry)
@@ -570,8 +597,7 @@ static int cache_lookup_union(struct nameidata *nd, struct qstr *name,
/* only directories can be part of a union stack */
if (!path->dentry->d_inode ||
- !S_ISDIR(path->dentry->d_inode->i_mode) ||
- IS_OPAQUE(path->dentry->d_inode))
+ !S_ISDIR(path->dentry->d_inode->i_mode))
goto out;
/* Build the union stack for this part */
@@ -738,6 +764,9 @@ static int __real_lookup_topmost(struct nameidata *nd, struct qstr *name,
if (path->dentry->d_inode || d_is_whiteout(path->dentry))
return 0;
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(path->dentry))
+ return 0;
+
while (follow_union_down(&nd->path.mnt, &nd->path.dentry)) {
name->hash = full_name_hash(name->name, name->len);
if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
@@ -758,6 +787,9 @@ static int __real_lookup_topmost(struct nameidata *nd, struct qstr *name,
goto out;
}
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(next.dentry))
+ goto out;
+
dput(next.dentry);
}
out:
@@ -817,9 +849,6 @@ static int __real_lookup_build_union(struct nameidata *nd, struct qstr *name,
path_put(&last);
last.dentry = next.dentry;
last.mnt = mntget(next.mnt);
-
- if (IS_OPAQUE(last.dentry->d_inode))
- break;
}
if (last.dentry != path->dentry)
@@ -841,8 +870,7 @@ static int real_lookup_union(struct nameidata *nd, struct qstr *name,
/* only directories can be part of a union stack */
if (!path->dentry->d_inode ||
- !S_ISDIR(path->dentry->d_inode->i_mode) ||
- IS_OPAQUE(path->dentry->d_inode))
+ !S_ISDIR(path->dentry->d_inode->i_mode))
goto out;
/* Build the union stack for this part */
@@ -1128,7 +1156,7 @@ static int do_lookup(struct nameidata *nd, struct qstr *name,
{
int err;
- if (IS_MNT_UNION(nd->path.mnt) && !IS_OPAQUE(nd->path.dentry->d_inode))
+ if (IS_MNT_UNION(nd->path.mnt))
goto need_union_lookup;
path->dentry = __d_lookup(nd->path.dentry, name);
@@ -1679,6 +1707,9 @@ static int __hash_lookup_topmost(struct nameidata *nd, struct qstr *name,
if (path->dentry->d_inode || d_is_whiteout(path->dentry))
return 0;
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(path->dentry))
+ return 0;
+
while (follow_union_down(&nd->path.mnt, &nd->path.dentry)) {
name->hash = full_name_hash(name->name, name->len);
if (nd->path.dentry->d_op && nd->path.dentry->d_op->d_hash) {
@@ -1701,6 +1732,9 @@ static int __hash_lookup_topmost(struct nameidata *nd, struct qstr *name,
goto out;
}
+ if (IS_OPAQUE(nd->path.dentry->d_inode) && !d_is_fallthru(next.dentry))
+ goto out;
+
dput(next.dentry);
}
out:
@@ -1755,9 +1789,6 @@ static int __hash_lookup_build_union(struct nameidata *nd, struct qstr *name,
path_put(&last);
last.dentry = next.dentry;
last.mnt = mntget(next.mnt);
-
- if (IS_OPAQUE(last.dentry->d_inode))
- break;
}
if (last.dentry != path->dentry)
--
1.6.3.3
next prev parent reply other threads:[~2009-10-21 19:19 UTC|newest]
Thread overview: 100+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-21 19:18 [RFC PATCH 00/40] Writable overlays (union mounts) Valerie Aurora
2009-10-21 19:18 ` [PATCH 01/41] VFS: BUG() if somebody tries to rehash an already hashed dentry Valerie Aurora
2009-10-21 19:19 ` [PATCH 02/41] VFS: propagate mnt_flags into do_loopback Valerie Aurora
2009-10-21 19:19 ` [PATCH 03/41] VFS: Make lookup_hash() return a struct path Valerie Aurora
2009-10-21 19:19 ` [PATCH 04/41] VFS: Remove unnecessary micro-optimization in cached_lookup() Valerie Aurora
2009-10-21 19:19 ` [PATCH 05/41] VFS: Make real_lookup() return a struct path Valerie Aurora
2009-10-21 19:19 ` [PATCH 06/41] VFS: Introduce dput() variant that maintains a kill-list Valerie Aurora
2009-10-21 19:19 ` [PATCH 07/41] VFS: Add read-only users count to superblock Valerie Aurora
2009-10-21 19:19 ` [PATCH 08/41] Don't replace nameidata path when following links Valerie Aurora
2009-10-21 19:19 ` [PATCH 09/41] whiteout: Don't return information about whiteouts to userspace Valerie Aurora
2009-10-21 19:19 ` [PATCH 10/41] whiteout: Add vfs_whiteout() and whiteout inode operation Valerie Aurora
2009-10-21 19:19 ` [PATCH 11/41] whiteout: Set S_OPAQUE inode flag when creating directories Valerie Aurora
2009-10-21 19:19 ` [PATCH 12/41] union-mount: Allow removal of a directory Valerie Aurora
2009-10-21 19:19 ` [PATCH 13/41] whiteout: tmpfs whiteout support Valerie Aurora
2009-10-21 19:19 ` [PATCH 14/41] whiteout: Split of ext2_append_link() from ext2_add_link() Valerie Aurora
2009-10-21 19:19 ` [PATCH 15/41] whiteout: ext2 whiteout support Valerie Aurora
2009-10-21 19:19 ` [PATCH 16/41] whiteout: jffs2 " Valerie Aurora
2009-10-21 19:19 ` [PATCH 17/41] whiteout: Add path_whiteout() helper Valerie Aurora
2009-10-21 19:19 ` [PATCH 18/41] union-mount: Documentation Valerie Aurora
2009-10-21 19:19 ` [PATCH 19/41] union-mount: Introduce MNT_UNION and MS_UNION flags Valerie Aurora
2009-10-21 19:19 ` [PATCH 20/41] union-mount: Introduce union_mount structure Valerie Aurora
2009-10-21 19:19 ` [PATCH 21/41] union-mount: Drive the union cache via dcache Valerie Aurora
2009-10-21 19:19 ` [PATCH 22/41] union-mount: Some checks during namespace changes Valerie Aurora
2009-10-21 19:19 ` [PATCH 23/41] union-mount: Changes to the namespace handling Valerie Aurora
2009-10-21 19:19 ` [PATCH 24/41] union-mount: Make lookup work for union-mounted file systems Valerie Aurora
2009-10-21 19:19 ` [PATCH 25/41] union-mount: stop lookup when directory has S_OPAQUE flag set Valerie Aurora
2009-10-21 19:19 ` [PATCH 26/41] union-mount: stop lookup when finding a whiteout Valerie Aurora
2009-10-21 19:19 ` [PATCH 27/41] union-mount: in-kernel file copy between union mounted filesystems Valerie Aurora
2009-10-21 19:19 ` [PATCH 28/41] union-mount: call do_whiteout() on unlink and rmdir Valerie Aurora
2009-10-21 19:19 ` [PATCH 29/41] union-mount: Always create topmost directory on open Valerie Aurora
2009-10-21 19:19 ` [PATCH 30/41] fallthru: Basic fallthru definitions Valerie Aurora
2009-10-21 19:19 ` Valerie Aurora [this message]
2009-10-21 19:19 ` [PATCH 32/41] fallthru: ext2 fallthru support Valerie Aurora
2009-10-21 19:19 ` [PATCH 33/41] fallthru: jffs2 " Valerie Aurora
2009-10-21 19:19 ` [PATCH 34/41] fallthru: tmpfs " Valerie Aurora
2009-10-21 19:19 ` [PATCH 35/41] union-mount: Copy up directory entries on first readdir() Valerie Aurora
2009-10-21 19:19 ` [PATCH 36/41] union-mount: Increment read-only users count for read-only layer Valerie Aurora
2009-10-21 19:19 ` [PATCH 37/41] union-mount: Check read-only/read-write status of layers Valerie Aurora
2009-10-21 19:19 ` [PATCH 38/41] union-mount: Make pivot_root work with union mounts Valerie Aurora
2009-10-21 19:19 ` [PATCH 39/41] union-mount: Ignore read-only file system in permission checks Valerie Aurora
2009-10-21 19:19 ` [PATCH 40/41] union-mount: Make truncate work in all its glorious UNIX variations Valerie Aurora
2009-10-21 19:19 ` [PATCH 41/41] union-mount: Add support for rename by __union_copyup() Valerie Aurora
2009-12-01 4:57 ` Erez Zadok
2009-12-01 4:50 ` [PATCH 40/41] union-mount: Make truncate work in all its glorious UNIX variations Erez Zadok
2009-12-01 4:34 ` [PATCH 39/41] union-mount: Ignore read-only file system in permission checks Erez Zadok
2009-12-01 4:26 ` [PATCH 38/41] union-mount: Make pivot_root work with union mounts Erez Zadok
2009-12-01 4:18 ` [PATCH 35/41] union-mount: Copy up directory entries on first readdir() Erez Zadok
2009-12-01 4:17 ` [PATCH 34/41] fallthru: tmpfs fallthru support Erez Zadok
2009-12-01 4:17 ` [PATCH 33/41] fallthru: jffs2 " Erez Zadok
2009-12-01 4:17 ` [PATCH 32/41] fallthru: ext2 " Erez Zadok
2009-12-01 4:15 ` [PATCH 31/41] fallthru: Support for fallthru entries in union mount lookup Erez Zadok
2009-12-01 4:14 ` [PATCH 30/41] fallthru: Basic fallthru definitions Erez Zadok
2009-12-01 4:14 ` [PATCH 29/41] union-mount: Always create topmost directory on open Erez Zadok
2009-12-01 4:13 ` [PATCH 27/41] union-mount: in-kernel file copy between union mounted filesystems Erez Zadok
2009-12-01 4:11 ` [PATCH 26/41] union-mount: stop lookup when finding a whiteout Erez Zadok
2009-12-01 4:10 ` [PATCH 25/41] union-mount: stop lookup when directory has S_OPAQUE flag set Erez Zadok
2009-12-01 4:10 ` [PATCH 24/41] union-mount: Make lookup work for union-mounted file systems Erez Zadok
2009-11-30 9:15 ` [PATCH 23/41] union-mount: Changes to the namespace handling Erez Zadok
2009-11-30 9:04 ` [PATCH 22/41] union-mount: Some checks during namespace changes Erez Zadok
2009-11-30 8:57 ` [PATCH 21/41] union-mount: Drive the union cache via dcache Erez Zadok
2009-11-30 8:46 ` [PATCH 20/41] union-mount: Introduce union_mount structure Erez Zadok
2010-01-26 22:38 ` Valerie Aurora
2009-11-30 8:02 ` [PATCH 19/41] union-mount: Introduce MNT_UNION and MS_UNION flags Erez Zadok
2010-01-26 20:03 ` Valerie Aurora
2009-12-01 5:37 ` [PATCH 18/41] union-mount: Documentation Erez Zadok
2009-11-30 7:57 ` [PATCH 17/41] whiteout: Add path_whiteout() helper Erez Zadok
2010-01-26 20:02 ` Valerie Aurora
2009-10-21 22:50 ` [PATCH 16/41] whiteout: jffs2 whiteout support David Woodhouse
2009-10-27 2:21 ` Valerie Aurora
2009-11-30 7:51 ` Erez Zadok
2010-01-26 19:52 ` Valerie Aurora
2009-10-21 21:17 ` [PATCH 15/41] whiteout: ext2 " Andreas Dilger
2009-10-27 2:14 ` Valerie Aurora
2009-11-30 7:45 ` Erez Zadok
2009-11-30 6:32 ` [PATCH 14/41] whiteout: Split of ext2_append_link() from ext2_add_link() Erez Zadok
2009-11-30 6:26 ` [PATCH 13/41] whiteout: tmpfs whiteout support Erez Zadok
2010-01-21 2:02 ` Valerie Aurora
2009-11-30 6:13 ` [PATCH 12/41] union-mount: Allow removal of a directory Erez Zadok
2010-01-21 0:52 ` Valerie Aurora
2009-10-27 14:36 ` [PATCH 10/41] whiteout: Add vfs_whiteout() and whiteout inode operation Eric Paris
2009-10-27 21:22 ` Valerie Aurora
2009-11-30 3:04 ` Erez Zadok
2010-01-21 0:35 ` Valerie Aurora
2009-11-30 2:53 ` [PATCH 09/41] whiteout: Don't return information about whiteouts to userspace Erez Zadok
2010-01-21 0:19 ` Valerie Aurora
2009-11-30 2:44 ` [PATCH 08/41] Don't replace nameidata path when following links Erez Zadok
2009-11-30 2:33 ` [PATCH 07/41] VFS: Add read-only users count to superblock Erez Zadok
2009-11-30 2:28 ` [PATCH 06/41] VFS: Introduce dput() variant that maintains a kill-list Erez Zadok
2010-01-20 23:31 ` Valerie Aurora
2009-11-30 2:11 ` [PATCH 05/41] VFS: Make real_lookup() return a struct path Erez Zadok
2009-11-30 2:07 ` [PATCH 04/41] VFS: Remove unnecessary micro-optimization in cached_lookup() Erez Zadok
2009-12-10 21:25 ` Valerie Aurora
2009-11-30 2:02 ` [PATCH 03/41] VFS: Make lookup_hash() return a struct path Erez Zadok
2009-12-10 21:23 ` Valerie Aurora
2009-11-30 6:04 ` Erez Zadok
2009-12-10 21:24 ` Valerie Aurora
2009-11-30 1:43 ` [PATCH 01/41] VFS: BUG() if somebody tries to rehash an already hashed dentry Erez Zadok
2009-12-10 20:20 ` Valerie Aurora
2009-10-22 2:44 ` [RFC PATCH 00/40] Writable overlays (union mounts) hooanon05
2009-10-27 2:23 ` Valerie Aurora
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=1256152779-10054-32-git-send-email-vaurora@redhat.com \
--to=vaurora@redhat.com \
--cc=apw@canonical.com \
--cc=hch@infradead.org \
--cc=jblunck@suse.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=scott@canonica \
--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;
as well as URLs for NNTP newsgroup(s).