3 @@ -1656,8 +1656,10 @@ static int do_move_mount(struct path *pa
5 /* moving to or from a union mount is not supported */
8 if (IS_MNT_UNION(path->mnt))
11 if (IS_MNT_UNION(old_path.mnt))
16 @@ -260,8 +260,6 @@ int append_to_union(struct vfsmount *mnt
17 spin_lock(&union_lock);
18 um = union_lookup(dentry, mnt);
20 - BUG_ON((um->u_next.dentry != dest_dentry) ||
21 - (um->u_next.mnt != dest_mnt));
22 spin_unlock(&union_lock);
25 @@ -274,6 +272,23 @@ int append_to_union(struct vfsmount *mnt
29 +int follow_union_mountpoint(struct path *path)
31 + struct path new_path = *path;
33 + path_get(&new_path);
34 + while (follow_union_down(&new_path)) {
35 + if (new_path.dentry != new_path.mnt->mnt_root)
42 + path_put(&new_path);
47 * follow_union_down - follow the union stack one layer down
49 --- a/include/linux/union.h
50 +++ b/include/linux/union.h
51 @@ -47,6 +47,7 @@ extern int append_to_union(struct vfsmou
52 struct vfsmount *, struct dentry *);
53 extern int follow_union_down(struct path *);
54 extern int follow_union_mount(struct path *);
55 +extern int follow_union_mountpoint(struct path *path);
56 extern void __d_drop_unions(struct dentry *);
57 extern void shrink_d_unions(struct dentry *);
58 extern void __shrink_d_unions(struct dentry *, struct list_head *);
59 @@ -68,6 +69,7 @@ extern int union_permission(struct path
60 #define append_to_union(x1, y1, x2, y2) ({ BUG(); (0); })
61 #define follow_union_down(x) ({ (0); })
62 #define follow_union_mount(x) ({ (0); })
63 +#define follow_union_mountpoint(x) ({ (0); })
64 #define __d_drop_unions(x) do { } while (0)
65 #define shrink_d_unions(x) do { } while (0)
66 #define __shrink_d_unions(x,y) do { } while (0)
69 @@ -626,6 +626,9 @@ static int cache_lookup_union(struct nam
70 !S_ISDIR(path->dentry->d_inode->i_mode))
73 + if (follow_union_mountpoint(path))
76 /* Build the union stack for this part */
77 res = __cache_lookup_build_union(nd, name, path);
79 @@ -892,6 +895,9 @@ static int real_lookup_union(struct name
80 !S_ISDIR(path->dentry->d_inode->i_mode))
83 + if (follow_union_mountpoint(path))
86 /* Build the union stack for this part */
87 res = __real_lookup_build_union(nd, name, path);
89 @@ -1813,6 +1819,9 @@ int hash_lookup_union(struct nameidata *
90 !S_ISDIR(path->dentry->d_inode->i_mode))
93 + if (follow_union_mountpoint(path))
96 /* Build the union stack for this part */
97 res = __hash_lookup_build_union(nd, name, path);
102 #include <linux/syscalls.h>
103 #include <linux/unistd.h>
104 #include <linux/union.h>
105 +#include <linux/mount.h>
107 #include <asm/uaccess.h>
109 @@ -45,7 +46,7 @@ int vfs_readdir(struct file *file, filld
110 * below this one in the union stack.
112 if (is_unionized(file->f_path.dentry, file->f_path.mnt) &&
113 - !IS_OPAQUE(inode)) {
114 + !IS_OPAQUE(inode) && IS_MNT_UNION(file->f_path.mnt)) {
115 res = union_copyup_dir(&file->f_path);