From: Bharata B Rao <bharata@linux.vnet.ibm.com>
To: Jan Blunck <jblunck@suse.de>
Cc: linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: Re: [RFC 16/26] union-mount: Introduce union_mount structure
Date: Mon, 6 Aug 2007 11:27:18 +0530 [thread overview]
Message-ID: <20070806055718.GA7489@in.ibm.com> (raw)
In-Reply-To: <20070730161324.628215686@weierstrass.suse.de>
On Mon, Jul 30, 2007 at 06:13:39PM +0200, Jan Blunck wrote:
> +
> +int append_to_union(struct vfsmount *mnt, struct dentry *dentry,
> + struct vfsmount *dest_mnt, struct dentry *dest_dentry)
> +{
> + struct union_mount *this, *um;
> +
> + BUG_ON(!IS_MNT_UNION(mnt));
> +
> + this = union_alloc(dentry, mnt, dest_dentry, dest_mnt);
> + if (!this)
> + return -ENOMEM;
> +
> + spin_lock(&union_lock);
> + um = union_lookup(dentry, mnt);
> + if (um) {
> + BUG_ON((um->u_next.dentry != dest_dentry) ||
> + (um->u_next.mnt != dest_mnt));
> + spin_unlock(&union_lock);
> + union_put(this);
> + return 0;
> + }
> + __union_hash(this);
> + spin_unlock(&union_lock);
> + return 0;
> +}
This breaks if we append to union stack from outside of the union.
A particular case I hit is with a 3 layer union with a subdir union
between topmost and bottom layer. Now if you create the same-named
directory in the middle layer from outside of this union, you hit the
above BUG_ON. The below patch fixes this and it applies on top of all of
your patches.
From: Bharata B Rao <bharata@linux.vnet.ibm.com>
Direct additions to union stack from outside of the union is resulting in
BUG_ON. But this is a valid case and hence needs to be supported. Modify
append_to_union() to correctly handle this case.
Signed-off-by: Bharata B Rao <bharata@linux.vnet.ibm.com>
---
fs/namei.c | 8 +++++---
fs/union.c | 32 ++++++++++++++++++++++++--------
include/linux/union.h | 4 ++--
3 files changed, 31 insertions(+), 13 deletions(-)
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -512,7 +512,7 @@ static int __cache_lookup_union(struct n
}
/* now we know we found something "real" */
- append_to_union(last.mnt, last.dentry, nd->mnt, dentry);
+ append_to_union(last.mnt, last.dentry, nd->mnt, dentry, 1);
if (last.dentry != path->dentry)
pathput(&last);
@@ -789,7 +789,8 @@ static int __real_lookup_union(struct na
}
/* now we know we found something "real" */
- append_to_union(last.mnt, last.dentry, next.mnt, next.dentry);
+ append_to_union(last.mnt, last.dentry,
+ next.mnt, next.dentry, 1);
if (last.dentry != path->dentry)
pathput(&last);
@@ -1775,7 +1776,8 @@ static int __hash_lookup_union(struct na
}
/* now we know we found something "real" */
- append_to_union(last.mnt, last.dentry, next.mnt, next.dentry);
+ append_to_union(last.mnt, last.dentry,
+ next.mnt, next.dentry, 1);
if (last.dentry != path->dentry)
pathput(&last);
--- a/fs/union.c
+++ b/fs/union.c
@@ -248,7 +248,8 @@ int is_unionized(struct dentry *dentry,
}
int append_to_union(struct vfsmount *mnt, struct dentry *dentry,
- struct vfsmount *dest_mnt, struct dentry *dest_dentry)
+ struct vfsmount *dest_mnt, struct dentry *dest_dentry,
+ int from_lookup)
{
struct union_mount *this, *um;
@@ -264,11 +265,26 @@ int append_to_union(struct vfsmount *mnt
spin_lock(&union_lock);
um = union_lookup(dentry, mnt);
if (um) {
- BUG_ON((um->u_next.dentry != dest_dentry) ||
- (um->u_next.mnt != dest_mnt));
- spin_unlock(&union_lock);
- union_put(this);
- return 0;
+ if (um->u_next.dentry == dest_dentry &&
+ um->u_next.mnt == dest_mnt) {
+ spin_unlock(&union_lock);
+ union_put(this);
+ return 0;
+ }
+ if (from_lookup) {
+ __union_unhash(um);
+ list_del(&um->u_list);
+ list_del(&um->u_unions);
+ um->u_next.dentry->d_unionized--;
+ spin_unlock(&union_lock);
+ union_put(um);
+ spin_lock(&union_lock);
+ } else {
+ BUG();
+ spin_unlock(&union_lock);
+ union_put(this);
+ return 0;
+ }
}
list_add(&this->u_list, &mnt->mnt_unions);
list_add(&this->u_unions, &dentry->d_unions);
@@ -451,7 +467,7 @@ int attach_mnt_union(struct vfsmount *mn
if (!IS_MNT_UNION(mnt))
return 0;
- return append_to_union(mnt, mnt->mnt_root, dest_mnt, dest_dentry);
+ return append_to_union(mnt, mnt->mnt_root, dest_mnt, dest_dentry, 0);
}
void detach_mnt_union(struct vfsmount *mnt)
@@ -941,7 +957,7 @@ struct dentry *union_create_topmost(stru
UM_DEBUG_DENTRY(dentry);
res = append_to_union(nd->mnt, dentry, path->mnt,
- path->dentry);
+ path->dentry, 0);
if (res) {
dput(dentry);
dentry = ERR_PTR(res);
--- a/include/linux/union.h
+++ b/include/linux/union.h
@@ -44,7 +44,7 @@ struct union_mount {
extern int is_unionized(struct dentry *, struct vfsmount *);
extern int append_to_union(struct vfsmount *, struct dentry *,
- struct vfsmount *, struct dentry *);
+ struct vfsmount *, struct dentry *, int);
extern int follow_union_down(struct vfsmount **, struct dentry **);
extern int follow_union_mount(struct vfsmount **, struct dentry **);
extern void __d_drop_unions(struct dentry *);
@@ -65,7 +65,7 @@ extern int union_copyup(struct nameidata
#define IS_UNION(x) (0)
#define IS_MNT_UNION(x) (0)
#define is_unionized(x, y) (0)
-#define append_to_union(x1, y1, x2, y2) ({ BUG(); (0); })
+#define append_to_union(x1, y1, x2, y2, z) ({ BUG(); (0); })
#define follow_union_down(x, y) ({ (0); })
#define follow_union_mount(x, y) ({ (0); })
#define __d_drop_unions(x) do { } while (0)
next prev parent reply other threads:[~2007-08-06 5:57 UTC|newest]
Thread overview: 66+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-07-30 16:13 [RFC 00/26] VFS based Union Mount (V2) Jan Blunck
2007-07-30 16:13 ` [RFC 01/26] [PATCH 14/18] shmem: convert to using splice instead of sendfile() Jan Blunck
2007-07-30 16:13 ` [RFC 02/26] VFS: Export dput_path() and path_to_nameidata() Jan Blunck
2007-07-30 16:13 ` [RFC 03/26] VFS: Make lookup_hash() return a struct path Jan Blunck
2007-07-30 16:13 ` [RFC 04/26] VFS: Make lookup_create() " Jan Blunck
2007-07-30 16:13 ` [RFC 05/26] VFS: cache_lookup() cleanup Jan Blunck
2007-07-30 16:13 ` [RFC 06/26] VFS: Make real_lookup() return a struct path Jan Blunck
2007-07-30 16:13 ` [RFC 07/26] VFS: Introduce dput() variante that maintains a kill-list Jan Blunck
2007-07-30 16:13 ` [RFC 08/26] VFS: Export lives_below_in_same_fs() Jan Blunck
2007-07-30 16:13 ` [RFC 09/26] linux/stat.h: Add the filetype white-out Jan Blunck
2007-07-30 16:13 ` [RFC 10/26] VFS white-out handling Jan Blunck
2007-07-30 16:13 ` [RFC 11/26] tmpfs white-out support Jan Blunck
2007-08-01 15:13 ` Hugh Dickins
2007-08-02 2:48 ` Matt Mackall
2007-07-30 16:13 ` [RFC 12/26] ext2 " Jan Blunck
2007-07-31 3:45 ` Theodore Tso
2007-07-31 7:44 ` Jan Blunck
2007-07-31 8:32 ` Andreas Dilger
2007-07-31 9:08 ` Jan Blunck
2007-07-31 10:53 ` Theodore Tso
2007-08-02 19:31 ` Pavel Machek
2007-07-31 16:36 ` Josef Sipek
2007-07-31 17:00 ` Jan Blunck
2007-07-31 17:11 ` Josef Sipek
2007-08-01 15:23 ` Dave Kleikamp
2007-08-01 18:44 ` Josef Sipek
2007-08-01 19:10 ` Dave Kleikamp
2007-08-01 19:33 ` Josef Sipek
2007-08-01 19:52 ` Dave Kleikamp
2007-08-01 22:06 ` Erez Zadok
2007-08-02 12:05 ` Jan Blunck
2007-08-02 11:55 ` Jan Blunck
2007-08-02 17:50 ` Jörn Engel
2007-08-02 17:50 ` Jörn Engel
2007-08-02 18:15 ` Jeremy Maitin-Shepard
2007-08-02 5:24 ` Ph. Marek
2007-08-02 12:12 ` Jan Blunck
2007-08-02 10:26 ` Jan Blunck
2007-08-01 10:00 ` Hans-Peter Jansen
2007-08-01 11:43 ` Josef Sipek
2007-08-01 18:01 ` Jan Engelhardt
2007-07-31 17:03 ` Mark Williamson
2007-07-31 17:16 ` Josef Sipek
2007-08-01 17:58 ` Jan Engelhardt
2007-08-01 18:03 ` Josef Sipek
2007-07-30 16:13 ` [RFC 13/26] ext3 whiteout support Jan Blunck
2007-07-30 16:13 ` [RFC 14/26] union-mount: Documentation Jan Blunck
2007-07-30 16:13 ` [RFC 15/26] union-mount: Add union-mount mount flag Jan Blunck
2007-07-30 16:13 ` [RFC 16/26] union-mount: Introduce union_mount structure Jan Blunck
2007-08-06 5:57 ` Bharata B Rao [this message]
2007-07-30 16:13 ` [RFC 17/26] union-mount: Drive the union cache via dcache Jan Blunck
2007-07-30 16:13 ` [RFC 18/26] union-mount: Changes to the namespace handling Jan Blunck
2007-08-08 10:10 ` Bharata B Rao
2007-07-30 16:13 ` [RFC 19/26] union-mount: Make lookup work for union-mounted file systems Jan Blunck
2007-08-09 5:42 ` Bharata B Rao
2007-07-30 16:13 ` [RFC 20/26] union-mount: Simple union-mount readdir implementation Jan Blunck
2007-08-06 11:08 ` Bharata B Rao
2007-07-30 16:13 ` [RFC 21/26] union-mount: in-kernel file copy between union mounted filesystems Jan Blunck
2007-07-30 16:13 ` [RFC 22/26] union-mount: white-out changes for copy-on-open Jan Blunck
2007-07-30 16:13 ` [RFC 23/26] union-mount: copyup on rename Jan Blunck
2007-07-30 16:13 ` [RFC 24/26] union-mount: dont report EROFS for union mounts Jan Blunck
2007-07-30 16:13 ` [RFC 25/26] union-mount: Debug Infrastructure Jan Blunck
2007-07-30 16:13 ` [RFC 26/26] union-mount: Debug code Jan Blunck
2007-07-30 18:23 ` [RFC 00/26] VFS based Union Mount (V2) Al Boldi
2007-08-02 6:49 ` Bharata B Rao
2007-08-02 10:17 ` Jan Blunck
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=20070806055718.GA7489@in.ibm.com \
--to=bharata@linux.vnet.ibm.com \
--cc=jblunck@suse.de \
--cc=linux-fsdevel@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.