diff options
-rw-r--r-- | fs/dcache.c | 6 | ||||
-rw-r--r-- | fs/mount.h | 6 | ||||
-rw-r--r-- | fs/namespace.c | 14 | ||||
-rw-r--r-- | fs/pnode.c | 2 | ||||
-rw-r--r-- | fs/pnode.h | 2 |
5 files changed, 18 insertions, 12 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 89509b5a090e..8a75e3b0f49d 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include <linux/prefetch.h> | 38 | #include <linux/prefetch.h> |
39 | #include <linux/ratelimit.h> | 39 | #include <linux/ratelimit.h> |
40 | #include "internal.h" | 40 | #include "internal.h" |
41 | #include "mount.h" | ||
41 | 42 | ||
42 | /* | 43 | /* |
43 | * Usage: | 44 | * Usage: |
@@ -2460,9 +2461,8 @@ static int prepend_path(const struct path *path, | |||
2460 | 2461 | ||
2461 | if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { | 2462 | if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { |
2462 | /* Global root? */ | 2463 | /* Global root? */ |
2463 | if (vfsmnt->mnt_parent == vfsmnt) { | 2464 | if (!mnt_has_parent(vfsmnt)) |
2464 | goto global_root; | 2465 | goto global_root; |
2465 | } | ||
2466 | dentry = vfsmnt->mnt_mountpoint; | 2466 | dentry = vfsmnt->mnt_mountpoint; |
2467 | vfsmnt = vfsmnt->mnt_parent; | 2467 | vfsmnt = vfsmnt->mnt_parent; |
2468 | continue; | 2468 | continue; |
@@ -2862,7 +2862,7 @@ int path_is_under(struct path *path1, struct path *path2) | |||
2862 | br_read_lock(vfsmount_lock); | 2862 | br_read_lock(vfsmount_lock); |
2863 | if (mnt != path2->mnt) { | 2863 | if (mnt != path2->mnt) { |
2864 | for (;;) { | 2864 | for (;;) { |
2865 | if (mnt->mnt_parent == mnt) { | 2865 | if (!mnt_has_parent(mnt)) { |
2866 | br_read_unlock(vfsmount_lock); | 2866 | br_read_unlock(vfsmount_lock); |
2867 | return 0; | 2867 | return 0; |
2868 | } | 2868 | } |
diff --git a/fs/mount.h b/fs/mount.h new file mode 100644 index 000000000000..7890e49f74ef --- /dev/null +++ b/fs/mount.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #include <linux/mount.h> | ||
2 | |||
3 | static inline int mnt_has_parent(struct vfsmount *mnt) | ||
4 | { | ||
5 | return mnt != mnt->mnt_parent; | ||
6 | } | ||
diff --git a/fs/namespace.c b/fs/namespace.c index 31d357450f7f..ec8512478b04 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -1182,7 +1182,7 @@ void release_mounts(struct list_head *head) | |||
1182 | while (!list_empty(head)) { | 1182 | while (!list_empty(head)) { |
1183 | mnt = list_first_entry(head, struct vfsmount, mnt_hash); | 1183 | mnt = list_first_entry(head, struct vfsmount, mnt_hash); |
1184 | list_del_init(&mnt->mnt_hash); | 1184 | list_del_init(&mnt->mnt_hash); |
1185 | if (mnt->mnt_parent != mnt) { | 1185 | if (mnt_has_parent(mnt)) { |
1186 | struct dentry *dentry; | 1186 | struct dentry *dentry; |
1187 | struct vfsmount *m; | 1187 | struct vfsmount *m; |
1188 | 1188 | ||
@@ -1222,7 +1222,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) | |||
1222 | p->mnt_ns = NULL; | 1222 | p->mnt_ns = NULL; |
1223 | __mnt_make_shortterm(p); | 1223 | __mnt_make_shortterm(p); |
1224 | list_del_init(&p->mnt_child); | 1224 | list_del_init(&p->mnt_child); |
1225 | if (p->mnt_parent != p) { | 1225 | if (mnt_has_parent(p)) { |
1226 | p->mnt_parent->mnt_ghosts++; | 1226 | p->mnt_parent->mnt_ghosts++; |
1227 | dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint); | 1227 | dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint); |
1228 | } | 1228 | } |
@@ -1867,7 +1867,7 @@ static int do_move_mount(struct path *path, char *old_name) | |||
1867 | if (old_path.dentry != old_path.mnt->mnt_root) | 1867 | if (old_path.dentry != old_path.mnt->mnt_root) |
1868 | goto out1; | 1868 | goto out1; |
1869 | 1869 | ||
1870 | if (old_path.mnt == old_path.mnt->mnt_parent) | 1870 | if (!mnt_has_parent(old_path.mnt)) |
1871 | goto out1; | 1871 | goto out1; |
1872 | 1872 | ||
1873 | if (S_ISDIR(path->dentry->d_inode->i_mode) != | 1873 | if (S_ISDIR(path->dentry->d_inode->i_mode) != |
@@ -1887,7 +1887,7 @@ static int do_move_mount(struct path *path, char *old_name) | |||
1887 | tree_contains_unbindable(old_path.mnt)) | 1887 | tree_contains_unbindable(old_path.mnt)) |
1888 | goto out1; | 1888 | goto out1; |
1889 | err = -ELOOP; | 1889 | err = -ELOOP; |
1890 | for (p = path->mnt; p->mnt_parent != p; p = p->mnt_parent) | 1890 | for (p = path->mnt; mnt_has_parent(p); p = p->mnt_parent) |
1891 | if (p == old_path.mnt) | 1891 | if (p == old_path.mnt) |
1892 | goto out1; | 1892 | goto out1; |
1893 | 1893 | ||
@@ -2604,17 +2604,17 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, | |||
2604 | error = -EINVAL; | 2604 | error = -EINVAL; |
2605 | if (root.mnt->mnt_root != root.dentry) | 2605 | if (root.mnt->mnt_root != root.dentry) |
2606 | goto out4; /* not a mountpoint */ | 2606 | goto out4; /* not a mountpoint */ |
2607 | if (root.mnt->mnt_parent == root.mnt) | 2607 | if (!mnt_has_parent(root.mnt)) |
2608 | goto out4; /* not attached */ | 2608 | goto out4; /* not attached */ |
2609 | if (new.mnt->mnt_root != new.dentry) | 2609 | if (new.mnt->mnt_root != new.dentry) |
2610 | goto out4; /* not a mountpoint */ | 2610 | goto out4; /* not a mountpoint */ |
2611 | if (new.mnt->mnt_parent == new.mnt) | 2611 | if (!mnt_has_parent(new.mnt)) |
2612 | goto out4; /* not attached */ | 2612 | goto out4; /* not attached */ |
2613 | /* make sure we can reach put_old from new_root */ | 2613 | /* make sure we can reach put_old from new_root */ |
2614 | tmp = old.mnt; | 2614 | tmp = old.mnt; |
2615 | if (tmp != new.mnt) { | 2615 | if (tmp != new.mnt) { |
2616 | for (;;) { | 2616 | for (;;) { |
2617 | if (tmp->mnt_parent == tmp) | 2617 | if (!mnt_has_parent(tmp)) |
2618 | goto out4; /* already mounted on put_old */ | 2618 | goto out4; /* already mounted on put_old */ |
2619 | if (tmp->mnt_parent == new.mnt) | 2619 | if (tmp->mnt_parent == new.mnt) |
2620 | break; | 2620 | break; |
diff --git a/fs/pnode.c b/fs/pnode.c index d42514e32380..f1cd958b92e5 100644 --- a/fs/pnode.c +++ b/fs/pnode.c | |||
@@ -36,7 +36,7 @@ static inline struct vfsmount *next_slave(struct vfsmount *p) | |||
36 | static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, | 36 | static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, |
37 | const struct path *root) | 37 | const struct path *root) |
38 | { | 38 | { |
39 | while (mnt != root->mnt && mnt->mnt_parent != mnt) { | 39 | while (mnt != root->mnt && mnt_has_parent(mnt)) { |
40 | dentry = mnt->mnt_mountpoint; | 40 | dentry = mnt->mnt_mountpoint; |
41 | mnt = mnt->mnt_parent; | 41 | mnt = mnt->mnt_parent; |
42 | } | 42 | } |
diff --git a/fs/pnode.h b/fs/pnode.h index 391287110274..7f0c13ae9484 100644 --- a/fs/pnode.h +++ b/fs/pnode.h | |||
@@ -9,7 +9,7 @@ | |||
9 | #define _LINUX_PNODE_H | 9 | #define _LINUX_PNODE_H |
10 | 10 | ||
11 | #include <linux/list.h> | 11 | #include <linux/list.h> |
12 | #include <linux/mount.h> | 12 | #include "mount.h" |
13 | 13 | ||
14 | #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) | 14 | #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) |
15 | #define IS_MNT_SLAVE(mnt) (mnt->mnt_master) | 15 | #define IS_MNT_SLAVE(mnt) (mnt->mnt_master) |