From f47ec3f28354795f000c14bf18ed967ec81a3ec3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Mon, 21 Nov 2011 21:15:42 -0500 Subject: trim fs/internal.h some stuff in there can actually become static; some belongs to pnode.h as it's a private interface between namespace.c and pnode.c... Signed-off-by: Al Viro --- fs/pnode.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'fs/pnode.h') diff --git a/fs/pnode.h b/fs/pnode.h index 1ea4ae1efcd3..391287110274 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -36,4 +36,10 @@ int propagate_umount(struct list_head *); int propagate_mount_busy(struct vfsmount *, int); void mnt_release_group_id(struct vfsmount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); +unsigned int mnt_get_count(struct vfsmount *mnt); +void mnt_set_mountpoint(struct vfsmount *, struct dentry *, + struct vfsmount *); +void release_mounts(struct list_head *); +void umount_tree(struct vfsmount *, int, struct list_head *); +struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); #endif /* _LINUX_PNODE_H */ -- cgit v1.2.3-70-g09d2 From b2dba1af3c4157040303a76d25216b1713d333d0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Nov 2011 19:26:23 -0500 Subject: vfs: new internal helper: mnt_has_parent(mnt) vfsmounts have ->mnt_parent pointing either to a different vfsmount or to itself; it's never NULL and termination condition in loops traversing the tree towards root is mnt == mnt->mnt_parent. At least one place (see the next patch) is confused about what's going on; let's add an explicit helper checking it right way and use it in all places where we need it. Not that there had been too many, but... Signed-off-by: Al Viro --- fs/dcache.c | 6 +++--- fs/mount.h | 6 ++++++ fs/namespace.c | 14 +++++++------- fs/pnode.c | 2 +- fs/pnode.h | 2 +- 5 files changed, 18 insertions(+), 12 deletions(-) create mode 100644 fs/mount.h (limited to 'fs/pnode.h') 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 @@ #include #include #include "internal.h" +#include "mount.h" /* * Usage: @@ -2460,9 +2461,8 @@ static int prepend_path(const struct path *path, if (dentry == vfsmnt->mnt_root || IS_ROOT(dentry)) { /* Global root? */ - if (vfsmnt->mnt_parent == vfsmnt) { + if (!mnt_has_parent(vfsmnt)) goto global_root; - } dentry = vfsmnt->mnt_mountpoint; vfsmnt = vfsmnt->mnt_parent; continue; @@ -2862,7 +2862,7 @@ int path_is_under(struct path *path1, struct path *path2) br_read_lock(vfsmount_lock); if (mnt != path2->mnt) { for (;;) { - if (mnt->mnt_parent == mnt) { + if (!mnt_has_parent(mnt)) { br_read_unlock(vfsmount_lock); return 0; } 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 @@ +#include + +static inline int mnt_has_parent(struct vfsmount *mnt) +{ + return mnt != mnt->mnt_parent; +} 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) while (!list_empty(head)) { mnt = list_first_entry(head, struct vfsmount, mnt_hash); list_del_init(&mnt->mnt_hash); - if (mnt->mnt_parent != mnt) { + if (mnt_has_parent(mnt)) { struct dentry *dentry; struct vfsmount *m; @@ -1222,7 +1222,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) p->mnt_ns = NULL; __mnt_make_shortterm(p); list_del_init(&p->mnt_child); - if (p->mnt_parent != p) { + if (mnt_has_parent(p)) { p->mnt_parent->mnt_ghosts++; dentry_reset_mounted(p->mnt_parent, p->mnt_mountpoint); } @@ -1867,7 +1867,7 @@ static int do_move_mount(struct path *path, char *old_name) if (old_path.dentry != old_path.mnt->mnt_root) goto out1; - if (old_path.mnt == old_path.mnt->mnt_parent) + if (!mnt_has_parent(old_path.mnt)) goto out1; if (S_ISDIR(path->dentry->d_inode->i_mode) != @@ -1887,7 +1887,7 @@ static int do_move_mount(struct path *path, char *old_name) tree_contains_unbindable(old_path.mnt)) goto out1; err = -ELOOP; - for (p = path->mnt; p->mnt_parent != p; p = p->mnt_parent) + for (p = path->mnt; mnt_has_parent(p); p = p->mnt_parent) if (p == old_path.mnt) goto out1; @@ -2604,17 +2604,17 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, error = -EINVAL; if (root.mnt->mnt_root != root.dentry) goto out4; /* not a mountpoint */ - if (root.mnt->mnt_parent == root.mnt) + if (!mnt_has_parent(root.mnt)) goto out4; /* not attached */ if (new.mnt->mnt_root != new.dentry) goto out4; /* not a mountpoint */ - if (new.mnt->mnt_parent == new.mnt) + if (!mnt_has_parent(new.mnt)) goto out4; /* not attached */ /* make sure we can reach put_old from new_root */ tmp = old.mnt; if (tmp != new.mnt) { for (;;) { - if (tmp->mnt_parent == tmp) + if (!mnt_has_parent(tmp)) goto out4; /* already mounted on put_old */ if (tmp->mnt_parent == new.mnt) 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) static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, const struct path *root) { - while (mnt != root->mnt && mnt->mnt_parent != mnt) { + while (mnt != root->mnt && mnt_has_parent(mnt)) { dentry = mnt->mnt_mountpoint; mnt = mnt->mnt_parent; } 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 @@ #define _LINUX_PNODE_H #include -#include +#include "mount.h" #define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) #define IS_MNT_SLAVE(mnt) (mnt->mnt_master) -- cgit v1.2.3-70-g09d2 From afac7cba7ed31968a95e181dc25e204e45009ea8 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Nov 2011 19:34:49 -0500 Subject: vfs: more mnt_parent cleanups a) mount --move is checking that ->mnt_parent is non-NULL before looking if that parent happens to be shared; ->mnt_parent is never NULL and it's not even an misspelled !mnt_has_parent() b) pivot_root open-codes is_path_reachable(), poorly. c) so does path_is_under(), while we are at it. Signed-off-by: Al Viro --- fs/dcache.c | 25 ------------------------- fs/namespace.c | 42 +++++++++++++++++++++++++++--------------- fs/pnode.c | 15 --------------- fs/pnode.h | 2 ++ 4 files changed, 29 insertions(+), 55 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/dcache.c b/fs/dcache.c index 8a75e3b0f49d..64c8ce4c147f 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2853,31 +2853,6 @@ int is_subdir(struct dentry *new_dentry, struct dentry *old_dentry) return result; } -int path_is_under(struct path *path1, struct path *path2) -{ - struct vfsmount *mnt = path1->mnt; - struct dentry *dentry = path1->dentry; - int res; - - br_read_lock(vfsmount_lock); - if (mnt != path2->mnt) { - for (;;) { - if (!mnt_has_parent(mnt)) { - br_read_unlock(vfsmount_lock); - return 0; - } - if (mnt->mnt_parent == path2->mnt) - break; - mnt = mnt->mnt_parent; - } - dentry = mnt->mnt_mountpoint; - } - res = is_subdir(dentry, path2->dentry); - br_read_unlock(vfsmount_lock); - return res; -} -EXPORT_SYMBOL(path_is_under); - void d_genocide(struct dentry *root) { struct dentry *this_parent; diff --git a/fs/namespace.c b/fs/namespace.c index ec8512478b04..7aad258dcaf6 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1876,8 +1876,7 @@ static int do_move_mount(struct path *path, char *old_name) /* * Don't move a mount residing in a shared parent. */ - if (old_path.mnt->mnt_parent && - IS_MNT_SHARED(old_path.mnt->mnt_parent)) + if (IS_MNT_SHARED(old_path.mnt->mnt_parent)) goto out1; /* * Don't move a mount tree containing unbindable mounts to a destination @@ -2533,6 +2532,31 @@ out_type: return ret; } +/* + * Return true if path is reachable from root + * + * namespace_sem or vfsmount_lock is held + */ +bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, + const struct path *root) +{ + while (mnt != root->mnt && mnt_has_parent(mnt)) { + dentry = mnt->mnt_mountpoint; + mnt = mnt->mnt_parent; + } + return mnt == root->mnt && is_subdir(dentry, root->dentry); +} + +int path_is_under(struct path *path1, struct path *path2) +{ + int res; + br_read_lock(vfsmount_lock); + res = is_path_reachable(path1->mnt, path1->dentry, path2); + br_read_unlock(vfsmount_lock); + return res; +} +EXPORT_SYMBOL(path_is_under); + /* * pivot_root Semantics: * Moves the root file system of the current process to the directory put_old, @@ -2561,7 +2585,6 @@ out_type: SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, const char __user *, put_old) { - struct vfsmount *tmp; struct path new, old, parent_path, root_parent, root; int error; @@ -2611,18 +2634,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (!mnt_has_parent(new.mnt)) goto out4; /* not attached */ /* make sure we can reach put_old from new_root */ - tmp = old.mnt; - if (tmp != new.mnt) { - for (;;) { - if (!mnt_has_parent(tmp)) - goto out4; /* already mounted on put_old */ - if (tmp->mnt_parent == new.mnt) - break; - tmp = tmp->mnt_parent; - } - if (!is_subdir(tmp->mnt_mountpoint, new.dentry)) - goto out4; - } else if (!is_subdir(old.dentry, new.dentry)) + if (!is_path_reachable(old.mnt, old.dentry, &new)) goto out4; br_write_lock(vfsmount_lock); detach_mnt(new.mnt, &parent_path); diff --git a/fs/pnode.c b/fs/pnode.c index f1cd958b92e5..4d5a06ea57a2 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -28,21 +28,6 @@ static inline struct vfsmount *next_slave(struct vfsmount *p) return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave); } -/* - * Return true if path is reachable from root - * - * namespace_sem is held, and mnt is attached - */ -static bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, - const struct path *root) -{ - while (mnt != root->mnt && mnt_has_parent(mnt)) { - dentry = mnt->mnt_mountpoint; - mnt = mnt->mnt_parent; - } - return mnt == root->mnt && is_subdir(dentry, root->dentry); -} - static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, struct mnt_namespace *ns, const struct path *root) diff --git a/fs/pnode.h b/fs/pnode.h index 7f0c13ae9484..723399e76134 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -42,4 +42,6 @@ void mnt_set_mountpoint(struct vfsmount *, struct dentry *, void release_mounts(struct list_head *); void umount_tree(struct vfsmount *, int, struct list_head *); struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); +bool is_path_reachable(struct vfsmount *, struct dentry *, + const struct path *root); #endif /* _LINUX_PNODE_H */ -- cgit v1.2.3-70-g09d2 From aafd08dad019ecc858b31fb89064f4de623c64f7 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Wed, 23 Nov 2011 12:27:01 -0500 Subject: vfs: add missing parens in pnode.h macros Signed-off-by: Al Viro --- fs/pnode.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/pnode.h b/fs/pnode.h index 723399e76134..5c234e742193 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -11,11 +11,11 @@ #include #include "mount.h" -#define IS_MNT_SHARED(mnt) (mnt->mnt_flags & MNT_SHARED) -#define IS_MNT_SLAVE(mnt) (mnt->mnt_master) -#define IS_MNT_NEW(mnt) (!mnt->mnt_ns) -#define CLEAR_MNT_SHARED(mnt) (mnt->mnt_flags &= ~MNT_SHARED) -#define IS_MNT_UNBINDABLE(mnt) (mnt->mnt_flags & MNT_UNBINDABLE) +#define IS_MNT_SHARED(mnt) ((mnt)->mnt_flags & MNT_SHARED) +#define IS_MNT_SLAVE(mnt) ((mnt)->mnt_master) +#define IS_MNT_NEW(mnt) (!(mnt)->mnt_ns) +#define CLEAR_MNT_SHARED(mnt) ((mnt)->mnt_flags &= ~MNT_SHARED) +#define IS_MNT_UNBINDABLE(mnt) ((mnt)->mnt_flags & MNT_UNBINDABLE) #define CL_EXPIRE 0x01 #define CL_SLAVE 0x02 -- cgit v1.2.3-70-g09d2 From 4b8b21f4fe16ee15eec5c69ea5fb41b30e428e59 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 19:54:23 -0500 Subject: vfs: spread struct mount - mount group id handling Signed-off-by: Al Viro --- fs/namespace.c | 36 ++++++++++++++++++------------------ fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index fad3b218679d..60d5c15c0879 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -110,7 +110,7 @@ static void mnt_free_id(struct vfsmount *mnt) * * mnt_group_ida is protected by namespace_sem */ -static int mnt_alloc_group_id(struct vfsmount *mnt) +static int mnt_alloc_group_id(struct mount *mnt) { int res; @@ -119,9 +119,9 @@ static int mnt_alloc_group_id(struct vfsmount *mnt) res = ida_get_new_above(&mnt_group_ida, mnt_group_start, - &mnt->mnt_group_id); + &mnt->mnt.mnt_group_id); if (!res) - mnt_group_start = mnt->mnt_group_id + 1; + mnt_group_start = mnt->mnt.mnt_group_id + 1; return res; } @@ -129,13 +129,13 @@ static int mnt_alloc_group_id(struct vfsmount *mnt) /* * Release a peer group ID */ -void mnt_release_group_id(struct vfsmount *mnt) +void mnt_release_group_id(struct mount *mnt) { - int id = mnt->mnt_group_id; + int id = mnt->mnt.mnt_group_id; ida_remove(&mnt_group_ida, id); if (mnt_group_start > id) mnt_group_start = id; - mnt->mnt_group_id = 0; + mnt->mnt.mnt_group_id = 0; } /* @@ -701,7 +701,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, mnt->mnt_group_id = old->mnt_group_id; if ((flag & CL_MAKE_SHARED) && !mnt->mnt_group_id) { - int err = mnt_alloc_group_id(mnt); + int err = mnt_alloc_group_id(real_mount(mnt)); if (err) goto out_free; } @@ -1497,25 +1497,25 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, return 0; } -static void cleanup_group_ids(struct vfsmount *mnt, struct vfsmount *end) +static void cleanup_group_ids(struct mount *mnt, struct mount *end) { struct mount *p; - for (p = real_mount(mnt); &p->mnt != end; p = next_mnt(p, mnt)) { + for (p = mnt; p != end; p = next_mnt(p, &mnt->mnt)) { if (p->mnt.mnt_group_id && !IS_MNT_SHARED(&p->mnt)) - mnt_release_group_id(&p->mnt); + mnt_release_group_id(p); } } -static int invent_group_ids(struct vfsmount *mnt, bool recurse) +static int invent_group_ids(struct mount *mnt, bool recurse) { struct mount *p; - for (p = real_mount(mnt); p; p = recurse ? next_mnt(p, mnt) : NULL) { + for (p = mnt; p; p = recurse ? next_mnt(p, &mnt->mnt) : NULL) { if (!p->mnt.mnt_group_id && !IS_MNT_SHARED(&p->mnt)) { - int err = mnt_alloc_group_id(&p->mnt); + int err = mnt_alloc_group_id(p); if (err) { - cleanup_group_ids(mnt, &p->mnt); + cleanup_group_ids(mnt, p); return err; } } @@ -1597,7 +1597,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, int err; if (IS_MNT_SHARED(dest_mnt)) { - err = invent_group_ids(source_mnt, true); + err = invent_group_ids(real_mount(source_mnt), true); if (err) goto out; } @@ -1630,7 +1630,7 @@ static int attach_recursive_mnt(struct vfsmount *source_mnt, out_cleanup_ids: if (IS_MNT_SHARED(dest_mnt)) - cleanup_group_ids(source_mnt, NULL); + cleanup_group_ids(real_mount(source_mnt), NULL); out: return err; } @@ -1700,7 +1700,7 @@ static int flags_to_propagation_type(int flags) static int do_change_type(struct path *path, int flag) { struct mount *m; - struct vfsmount *mnt = path->mnt; + struct mount *mnt = real_mount(path->mnt); int recurse = flag & MS_REC; int type; int err = 0; @@ -1723,7 +1723,7 @@ static int do_change_type(struct path *path, int flag) } br_write_lock(vfsmount_lock); - for (m = real_mount(mnt); m; m = (recurse ? next_mnt(m, mnt) : NULL)) + for (m = mnt; m; m = (recurse ? next_mnt(m, &mnt->mnt) : NULL)) change_mnt_propagation(&m->mnt, type); br_write_unlock(vfsmount_lock); diff --git a/fs/pnode.c b/fs/pnode.c index ae5b1bda31ba..a824a097b523 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -83,7 +83,7 @@ static int do_make_slave(struct vfsmount *mnt) peer_mnt = NULL; } if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) - mnt_release_group_id(mnt); + mnt_release_group_id(real_mount(mnt)); list_del_init(&mnt->mnt_share); mnt->mnt_group_id = 0; diff --git a/fs/pnode.h b/fs/pnode.h index 5c234e742193..23dfe22139da 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -34,7 +34,7 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, struct list_head *); int propagate_umount(struct list_head *); int propagate_mount_busy(struct vfsmount *, int); -void mnt_release_group_id(struct vfsmount *); +void mnt_release_group_id(struct mount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); unsigned int mnt_get_count(struct vfsmount *mnt); void mnt_set_mountpoint(struct vfsmount *, struct dentry *, -- cgit v1.2.3-70-g09d2 From 0f0afb1dcf01afc44581b3c0da251ac07dfb6e4a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 20:43:10 -0500 Subject: vfs: spread struct mount - change_mnt_propagation/set_mnt_shared Signed-off-by: Al Viro --- fs/namespace.c | 8 ++++---- fs/pnode.c | 12 ++++++------ fs/pnode.h | 8 ++++---- 3 files changed, 14 insertions(+), 14 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 98b49351fbde..c7fa75f0fd92 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -724,7 +724,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, mnt->mnt.mnt_master = old->mnt_master; } if (flag & CL_MAKE_SHARED) - set_mnt_shared(&mnt->mnt); + set_mnt_shared(mnt); /* stick the duplicate mount on the same expiry list * as the original if that was on one */ @@ -1239,7 +1239,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) p->mnt.mnt_parent->mnt_ghosts++; dentry_reset_mounted(p->mnt.mnt_mountpoint); } - change_mnt_propagation(&p->mnt, MS_PRIVATE); + change_mnt_propagation(p, MS_PRIVATE); } list_splice(&tmp_list, kill); } @@ -1608,7 +1608,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, if (IS_MNT_SHARED(dest_mnt)) { for (p = source_mnt; p; p = next_mnt(p, &source_mnt->mnt)) - set_mnt_shared(&p->mnt); + set_mnt_shared(p); } if (parent_path) { detach_mnt(source_mnt, parent_path); @@ -1723,7 +1723,7 @@ static int do_change_type(struct path *path, int flag) br_write_lock(vfsmount_lock); for (m = mnt; m; m = (recurse ? next_mnt(m, &mnt->mnt) : NULL)) - change_mnt_propagation(&m->mnt, type); + change_mnt_propagation(m, type); br_write_unlock(vfsmount_lock); out_unlock: diff --git a/fs/pnode.c b/fs/pnode.c index a824a097b523..4bd3721867a7 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -114,20 +114,20 @@ static int do_make_slave(struct vfsmount *mnt) /* * vfsmount lock must be held for write */ -void change_mnt_propagation(struct vfsmount *mnt, int type) +void change_mnt_propagation(struct mount *mnt, int type) { if (type == MS_SHARED) { set_mnt_shared(mnt); return; } - do_make_slave(mnt); + do_make_slave(&mnt->mnt); if (type != MS_SLAVE) { - list_del_init(&mnt->mnt_slave); - mnt->mnt_master = NULL; + list_del_init(&mnt->mnt.mnt_slave); + mnt->mnt.mnt_master = NULL; if (type == MS_UNBINDABLE) - mnt->mnt_flags |= MNT_UNBINDABLE; + mnt->mnt.mnt_flags |= MNT_UNBINDABLE; else - mnt->mnt_flags &= ~MNT_UNBINDABLE; + mnt->mnt.mnt_flags &= ~MNT_UNBINDABLE; } } diff --git a/fs/pnode.h b/fs/pnode.h index 23dfe22139da..a2ad95435c48 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -23,13 +23,13 @@ #define CL_MAKE_SHARED 0x08 #define CL_PRIVATE 0x10 -static inline void set_mnt_shared(struct vfsmount *mnt) +static inline void set_mnt_shared(struct mount *mnt) { - mnt->mnt_flags &= ~MNT_SHARED_MASK; - mnt->mnt_flags |= MNT_SHARED; + mnt->mnt.mnt_flags &= ~MNT_SHARED_MASK; + mnt->mnt.mnt_flags |= MNT_SHARED; } -void change_mnt_propagation(struct vfsmount *, int); +void change_mnt_propagation(struct mount *, int); int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, struct list_head *); int propagate_umount(struct list_head *); -- cgit v1.2.3-70-g09d2 From cb338d06e9716c92d5a7855e7c67b8f111ced722 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 20:55:08 -0500 Subject: vfs: spread struct mount - clone_mnt/copy_tree result Signed-off-by: Al Viro --- fs/namespace.c | 39 +++++++++++++++++++++------------------ fs/pnode.c | 15 ++++++++------- fs/pnode.h | 2 +- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index c7fa75f0fd92..6051a034db96 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -687,7 +687,7 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void } EXPORT_SYMBOL_GPL(vfs_kern_mount); -static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, +static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root, int flag) { struct super_block *sb = old->mnt_sb; @@ -733,7 +733,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root, list_add(&mnt->mnt.mnt_expire, &old->mnt_expire); } } - return &mnt->mnt; + return mnt; out_free: free_vfsmnt(mnt); @@ -1408,10 +1408,11 @@ static int mount_is_safe(struct path *path) #endif } -struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, +struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, int flag) { - struct vfsmount *res, *p, *q, *r; + struct mount *res, *q; + struct vfsmount *p, *r; struct path path; if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) @@ -1420,7 +1421,7 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, res = q = clone_mnt(mnt, dentry, flag); if (!q) goto Enomem; - q->mnt_mountpoint = mnt->mnt_mountpoint; + q->mnt.mnt_mountpoint = mnt->mnt_mountpoint; p = mnt; list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) { @@ -1435,17 +1436,17 @@ struct vfsmount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, } while (p != s->mnt.mnt_parent) { p = p->mnt_parent; - q = q->mnt_parent; + q = real_mount(q->mnt.mnt_parent); } p = &s->mnt; - path.mnt = q; + path.mnt = &q->mnt; path.dentry = p->mnt_mountpoint; q = clone_mnt(p, p->mnt_root, flag); if (!q) goto Enomem; br_write_lock(vfsmount_lock); - list_add_tail(&q->mnt_list, &res->mnt_list); - attach_mnt(real_mount(q), &path); + list_add_tail(&q->mnt.mnt_list, &res->mnt.mnt_list); + attach_mnt(q, &path); br_write_unlock(vfsmount_lock); } } @@ -1454,7 +1455,7 @@ Enomem: if (res) { LIST_HEAD(umount_list); br_write_lock(vfsmount_lock); - umount_tree(res, 0, &umount_list); + umount_tree(&res->mnt, 0, &umount_list); br_write_unlock(vfsmount_lock); release_mounts(&umount_list); } @@ -1463,11 +1464,11 @@ Enomem: struct vfsmount *collect_mounts(struct path *path) { - struct vfsmount *tree; + struct mount *tree; down_write(&namespace_sem); tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE); up_write(&namespace_sem); - return tree; + return tree ? &tree->mnt : NULL; } void drop_collected_mounts(struct vfsmount *mnt) @@ -1739,7 +1740,7 @@ static int do_loopback(struct path *path, char *old_name, { LIST_HEAD(umount_list); struct path old_path; - struct vfsmount *mnt = NULL; + struct mount *mnt = NULL; int err = mount_is_safe(path); if (err) return err; @@ -1769,10 +1770,10 @@ static int do_loopback(struct path *path, char *old_name, if (!mnt) goto out2; - err = graft_tree(mnt, path); + err = graft_tree(&mnt->mnt, path); if (err) { br_write_lock(vfsmount_lock); - umount_tree(mnt, 0, &umount_list); + umount_tree(&mnt->mnt, 0, &umount_list); br_write_unlock(vfsmount_lock); } out2: @@ -2385,6 +2386,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, struct mnt_namespace *new_ns; struct vfsmount *rootmnt = NULL, *pwdmnt = NULL; struct mount *p, *q; + struct mount *new; new_ns = alloc_mnt_ns(); if (IS_ERR(new_ns)) @@ -2392,13 +2394,14 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, down_write(&namespace_sem); /* First pass: copy the tree topology */ - new_ns->root = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, + new = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, CL_COPY_ALL | CL_EXPIRE); - if (!new_ns->root) { + if (!new) { up_write(&namespace_sem); kfree(new_ns); return ERR_PTR(-ENOMEM); } + new_ns->root = &new->mnt; br_write_lock(vfsmount_lock); list_add_tail(&new_ns->list, &new_ns->root->mnt_list); br_write_unlock(vfsmount_lock); @@ -2409,7 +2412,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, * fs_struct, so tsk->fs->lock is not needed. */ p = real_mount(mnt_ns->root); - q = real_mount(new_ns->root); + q = new; while (p) { q->mnt.mnt_ns = new_ns; __mnt_make_longterm(&q->mnt); diff --git a/fs/pnode.c b/fs/pnode.c index 4bd3721867a7..916c8e87cf4e 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -221,7 +221,8 @@ static struct vfsmount *get_source(struct vfsmount *dest, int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, struct vfsmount *source_mnt, struct list_head *tree_list) { - struct vfsmount *m, *child; + struct vfsmount *m; + struct mount *child; int ret = 0; struct vfsmount *prev_dest_mnt = dest_mnt; struct vfsmount *prev_src_mnt = source_mnt; @@ -245,23 +246,23 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, } if (is_subdir(dest_dentry, m->mnt_root)) { - mnt_set_mountpoint(m, dest_dentry, child); - list_add_tail(&child->mnt_hash, tree_list); + mnt_set_mountpoint(m, dest_dentry, &child->mnt); + list_add_tail(&child->mnt.mnt_hash, tree_list); } else { /* * This can happen if the parent mount was bind mounted * on some subdirectory of a shared/slave mount. */ - list_add_tail(&child->mnt_hash, &tmp_list); + list_add_tail(&child->mnt.mnt_hash, &tmp_list); } prev_dest_mnt = m; - prev_src_mnt = child; + prev_src_mnt = &child->mnt; } out: br_write_lock(vfsmount_lock); while (!list_empty(&tmp_list)) { - child = list_first_entry(&tmp_list, struct vfsmount, mnt_hash); - umount_tree(child, 0, &umount_list); + child = list_first_entry(&tmp_list, struct mount, mnt.mnt_hash); + umount_tree(&child->mnt, 0, &umount_list); } br_write_unlock(vfsmount_lock); release_mounts(&umount_list); diff --git a/fs/pnode.h b/fs/pnode.h index a2ad95435c48..ed8a84d6d78f 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -41,7 +41,7 @@ void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct vfsmount *); void release_mounts(struct list_head *); void umount_tree(struct vfsmount *, int, struct list_head *); -struct vfsmount *copy_tree(struct vfsmount *, struct dentry *, int); +struct mount *copy_tree(struct vfsmount *, struct dentry *, int); bool is_path_reachable(struct vfsmount *, struct dentry *, const struct path *root); #endif /* _LINUX_PNODE_H */ -- cgit v1.2.3-70-g09d2 From 761d5c38eb3d8e2aa7394726dccab245bfe2f41c Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 21:07:43 -0500 Subject: vfs: spread struct mount - umount_tree argument Signed-off-by: Al Viro --- fs/namespace.c | 36 ++++++++++++++++++------------------ fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 20 insertions(+), 20 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 121e0032c9de..5bb40c52b2af 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1217,12 +1217,12 @@ void release_mounts(struct list_head *head) * vfsmount lock must be held for write * namespace_sem must be held for write */ -void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill) +void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) { LIST_HEAD(tmp_list); struct mount *p; - for (p = real_mount(mnt); p; p = next_mnt(p, mnt)) + for (p = mnt; p; p = next_mnt(p, &mnt->mnt)) list_move(&p->mnt_hash, &tmp_list); if (propagate) @@ -1327,7 +1327,7 @@ static int do_umount(struct vfsmount *mnt, int flags) retval = -EBUSY; if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { if (!list_empty(&mnt->mnt_list)) - umount_tree(mnt, 1, &umount_list); + umount_tree(real_mount(mnt), 1, &umount_list); retval = 0; } br_write_unlock(vfsmount_lock); @@ -1455,7 +1455,7 @@ Enomem: if (res) { LIST_HEAD(umount_list); br_write_lock(vfsmount_lock); - umount_tree(&res->mnt, 0, &umount_list); + umount_tree(res, 0, &umount_list); br_write_unlock(vfsmount_lock); release_mounts(&umount_list); } @@ -1476,7 +1476,7 @@ void drop_collected_mounts(struct vfsmount *mnt) LIST_HEAD(umount_list); down_write(&namespace_sem); br_write_lock(vfsmount_lock); - umount_tree(mnt, 0, &umount_list); + umount_tree(real_mount(mnt), 0, &umount_list); br_write_unlock(vfsmount_lock); up_write(&namespace_sem); release_mounts(&umount_list); @@ -1773,7 +1773,7 @@ static int do_loopback(struct path *path, char *old_name, err = graft_tree(&mnt->mnt, path); if (err) { br_write_lock(vfsmount_lock); - umount_tree(&mnt->mnt, 0, &umount_list); + umount_tree(mnt, 0, &umount_list); br_write_unlock(vfsmount_lock); } out2: @@ -2080,7 +2080,7 @@ EXPORT_SYMBOL(mnt_set_expiry); */ void mark_mounts_for_expiry(struct list_head *mounts) { - struct vfsmount *mnt, *next; + struct mount *mnt, *next; LIST_HEAD(graveyard); LIST_HEAD(umounts); @@ -2096,15 +2096,15 @@ void mark_mounts_for_expiry(struct list_head *mounts) * - still marked for expiry (marked on the last call here; marks are * cleared by mntput()) */ - list_for_each_entry_safe(mnt, next, mounts, mnt_expire) { - if (!xchg(&mnt->mnt_expiry_mark, 1) || - propagate_mount_busy(mnt, 1)) + list_for_each_entry_safe(mnt, next, mounts, mnt.mnt_expire) { + if (!xchg(&mnt->mnt.mnt_expiry_mark, 1) || + propagate_mount_busy(&mnt->mnt, 1)) continue; - list_move(&mnt->mnt_expire, &graveyard); + list_move(&mnt->mnt.mnt_expire, &graveyard); } while (!list_empty(&graveyard)) { - mnt = list_first_entry(&graveyard, struct vfsmount, mnt_expire); - touch_mnt_namespace(mnt->mnt_ns); + mnt = list_first_entry(&graveyard, struct mount, mnt.mnt_expire); + touch_mnt_namespace(mnt->mnt.mnt_ns); umount_tree(mnt, 1, &umounts); } br_write_unlock(vfsmount_lock); @@ -2170,14 +2170,14 @@ resume: static void shrink_submounts(struct vfsmount *mnt, struct list_head *umounts) { LIST_HEAD(graveyard); - struct vfsmount *m; + struct mount *m; /* extract submounts of 'mountpoint' from the expiration list */ while (select_submounts(mnt, &graveyard)) { while (!list_empty(&graveyard)) { - m = list_first_entry(&graveyard, struct vfsmount, - mnt_expire); - touch_mnt_namespace(m->mnt_ns); + m = list_first_entry(&graveyard, struct mount, + mnt.mnt_expire); + touch_mnt_namespace(m->mnt.mnt_ns); umount_tree(m, 1, umounts); } } @@ -2750,7 +2750,7 @@ void put_mnt_ns(struct mnt_namespace *ns) return; down_write(&namespace_sem); br_write_lock(vfsmount_lock); - umount_tree(ns->root, 0, &umount_list); + umount_tree(real_mount(ns->root), 0, &umount_list); br_write_unlock(vfsmount_lock); up_write(&namespace_sem); release_mounts(&umount_list); diff --git a/fs/pnode.c b/fs/pnode.c index a2f0f3e0e127..efbe0c0d3f0d 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -262,7 +262,7 @@ out: br_write_lock(vfsmount_lock); while (!list_empty(&tmp_list)) { child = list_first_entry(&tmp_list, struct mount, mnt_hash); - umount_tree(&child->mnt, 0, &umount_list); + umount_tree(child, 0, &umount_list); } br_write_unlock(vfsmount_lock); release_mounts(&umount_list); diff --git a/fs/pnode.h b/fs/pnode.h index ed8a84d6d78f..3f9ab4f4e0e5 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -40,7 +40,7 @@ unsigned int mnt_get_count(struct vfsmount *mnt); void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct vfsmount *); void release_mounts(struct list_head *); -void umount_tree(struct vfsmount *, int, struct list_head *); +void umount_tree(struct mount *, int, struct list_head *); struct mount *copy_tree(struct vfsmount *, struct dentry *, int); bool is_path_reachable(struct vfsmount *, struct dentry *, const struct path *root); -- cgit v1.2.3-70-g09d2 From 87129cc0e3fcd89a1db3e99d62dc710e05749f77 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 21:24:27 -0500 Subject: vfs: spread struct mount - clone_mnt/copy_tree argument Signed-off-by: Al Viro --- fs/namespace.c | 63 ++++++++++++++++++++++++++++++---------------------------- fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 35 insertions(+), 32 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index fa0f30d862c6..211455e2cd17 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -687,17 +687,17 @@ vfs_kern_mount(struct file_system_type *type, int flags, const char *name, void } EXPORT_SYMBOL_GPL(vfs_kern_mount); -static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root, +static struct mount *clone_mnt(struct mount *old, struct dentry *root, int flag) { - struct super_block *sb = old->mnt_sb; - struct mount *mnt = alloc_vfsmnt(old->mnt_devname); + struct super_block *sb = old->mnt.mnt_sb; + struct mount *mnt = alloc_vfsmnt(old->mnt.mnt_devname); if (mnt) { if (flag & (CL_SLAVE | CL_PRIVATE)) mnt->mnt.mnt_group_id = 0; /* not a peer of original */ else - mnt->mnt.mnt_group_id = old->mnt_group_id; + mnt->mnt.mnt_group_id = old->mnt.mnt_group_id; if ((flag & CL_MAKE_SHARED) && !mnt->mnt.mnt_group_id) { int err = mnt_alloc_group_id(mnt); @@ -705,7 +705,7 @@ static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root, goto out_free; } - mnt->mnt.mnt_flags = old->mnt_flags & ~MNT_WRITE_HOLD; + mnt->mnt.mnt_flags = old->mnt.mnt_flags & ~MNT_WRITE_HOLD; atomic_inc(&sb->s_active); mnt->mnt.mnt_sb = sb; mnt->mnt.mnt_root = dget(root); @@ -713,15 +713,15 @@ static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root, mnt->mnt.mnt_parent = &mnt->mnt; if (flag & CL_SLAVE) { - list_add(&mnt->mnt.mnt_slave, &old->mnt_slave_list); - mnt->mnt.mnt_master = old; + list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave_list); + mnt->mnt.mnt_master = &old->mnt; CLEAR_MNT_SHARED(&mnt->mnt); } else if (!(flag & CL_PRIVATE)) { - if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old)) - list_add(&mnt->mnt.mnt_share, &old->mnt_share); - if (IS_MNT_SLAVE(old)) - list_add(&mnt->mnt.mnt_slave, &old->mnt_slave); - mnt->mnt.mnt_master = old->mnt_master; + if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(&old->mnt)) + list_add(&mnt->mnt.mnt_share, &old->mnt.mnt_share); + if (IS_MNT_SLAVE(&old->mnt)) + list_add(&mnt->mnt.mnt_slave, &old->mnt.mnt_slave); + mnt->mnt.mnt_master = old->mnt.mnt_master; } if (flag & CL_MAKE_SHARED) set_mnt_shared(mnt); @@ -729,8 +729,8 @@ static struct mount *clone_mnt(struct vfsmount *old, struct dentry *root, /* stick the duplicate mount on the same expiry list * as the original if that was on one */ if (flag & CL_EXPIRE) { - if (!list_empty(&old->mnt_expire)) - list_add(&mnt->mnt.mnt_expire, &old->mnt_expire); + if (!list_empty(&old->mnt.mnt_expire)) + list_add(&mnt->mnt.mnt_expire, &old->mnt.mnt_expire); } } return mnt; @@ -1408,23 +1408,23 @@ static int mount_is_safe(struct path *path) #endif } -struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, +struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, int flag) { - struct mount *res, *q; - struct vfsmount *p, *r; + struct mount *res, *p, *q; + struct vfsmount *r; struct path path; - if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) + if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(&mnt->mnt)) return NULL; res = q = clone_mnt(mnt, dentry, flag); if (!q) goto Enomem; - q->mnt.mnt_mountpoint = mnt->mnt_mountpoint; + q->mnt.mnt_mountpoint = mnt->mnt.mnt_mountpoint; p = mnt; - list_for_each_entry(r, &mnt->mnt_mounts, mnt_child) { + list_for_each_entry(r, &mnt->mnt.mnt_mounts, mnt_child) { struct mount *s; if (!is_subdir(r->mnt_mountpoint, dentry)) continue; @@ -1434,14 +1434,14 @@ struct mount *copy_tree(struct vfsmount *mnt, struct dentry *dentry, s = skip_mnt_tree(s); continue; } - while (p != s->mnt.mnt_parent) { - p = p->mnt_parent; + while (p != real_mount(s->mnt.mnt_parent)) { + p = real_mount(p->mnt.mnt_parent); q = real_mount(q->mnt.mnt_parent); } - p = &s->mnt; + p = s; path.mnt = &q->mnt; - path.dentry = p->mnt_mountpoint; - q = clone_mnt(p, p->mnt_root, flag); + path.dentry = p->mnt.mnt_mountpoint; + q = clone_mnt(p, p->mnt.mnt_root, flag); if (!q) goto Enomem; br_write_lock(vfsmount_lock); @@ -1466,7 +1466,8 @@ struct vfsmount *collect_mounts(struct path *path) { struct mount *tree; down_write(&namespace_sem); - tree = copy_tree(path->mnt, path->dentry, CL_COPY_ALL | CL_PRIVATE); + tree = copy_tree(real_mount(path->mnt), path->dentry, + CL_COPY_ALL | CL_PRIVATE); up_write(&namespace_sem); return tree ? &tree->mnt : NULL; } @@ -1740,7 +1741,7 @@ static int do_loopback(struct path *path, char *old_name, { LIST_HEAD(umount_list); struct path old_path; - struct mount *mnt = NULL; + struct mount *mnt = NULL, *old; int err = mount_is_safe(path); if (err) return err; @@ -1754,6 +1755,8 @@ static int do_loopback(struct path *path, char *old_name, if (err) goto out; + old = real_mount(old_path.mnt); + err = -EINVAL; if (IS_MNT_UNBINDABLE(old_path.mnt)) goto out2; @@ -1763,9 +1766,9 @@ static int do_loopback(struct path *path, char *old_name, err = -ENOMEM; if (recurse) - mnt = copy_tree(old_path.mnt, old_path.dentry, 0); + mnt = copy_tree(old, old_path.dentry, 0); else - mnt = clone_mnt(old_path.mnt, old_path.dentry, 0); + mnt = clone_mnt(old, old_path.dentry, 0); if (!mnt) goto out2; @@ -2394,7 +2397,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, down_write(&namespace_sem); /* First pass: copy the tree topology */ - new = copy_tree(mnt_ns->root, mnt_ns->root->mnt_root, + new = copy_tree(real_mount(mnt_ns->root), mnt_ns->root->mnt_root, CL_COPY_ALL | CL_EXPIRE); if (!new) { up_write(&namespace_sem); diff --git a/fs/pnode.c b/fs/pnode.c index efbe0c0d3f0d..5d79f38e3e8a 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -239,7 +239,7 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, source = get_source(m, prev_dest_mnt, prev_src_mnt, &type); - if (!(child = copy_tree(source, source->mnt_root, type))) { + if (!(child = copy_tree(real_mount(source), source->mnt_root, type))) { ret = -ENOMEM; list_splice(tree_list, tmp_list.prev); goto out; diff --git a/fs/pnode.h b/fs/pnode.h index 3f9ab4f4e0e5..609ec008d5ce 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -41,7 +41,7 @@ void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct vfsmount *); void release_mounts(struct list_head *); void umount_tree(struct mount *, int, struct list_head *); -struct mount *copy_tree(struct vfsmount *, struct dentry *, int); +struct mount *copy_tree(struct mount *, struct dentry *, int); bool is_path_reachable(struct vfsmount *, struct dentry *, const struct path *root); #endif /* _LINUX_PNODE_H */ -- cgit v1.2.3-70-g09d2 From 44d964d609c7c11b330a3d1caf30767fa13c7be3 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 21:28:22 -0500 Subject: vfs: spread struct mount mnt_set_mountpoint child argument Signed-off-by: Al Viro --- fs/namespace.c | 10 +++++----- fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 211455e2cd17..c11b99af53cf 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -570,10 +570,10 @@ static void detach_mnt(struct mount *mnt, struct path *old_path) * vfsmount lock must be held for write */ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, - struct vfsmount *child_mnt) + struct mount *child_mnt) { - child_mnt->mnt_parent = mntget(mnt); - child_mnt->mnt_mountpoint = dget(dentry); + child_mnt->mnt.mnt_parent = mntget(mnt); + child_mnt->mnt.mnt_mountpoint = dget(dentry); spin_lock(&dentry->d_lock); dentry->d_flags |= DCACHE_MOUNTED; spin_unlock(&dentry->d_lock); @@ -584,7 +584,7 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, */ static void attach_mnt(struct mount *mnt, struct path *path) { - mnt_set_mountpoint(path->mnt, path->dentry, &mnt->mnt); + mnt_set_mountpoint(path->mnt, path->dentry, mnt); list_add_tail(&mnt->mnt_hash, mount_hashtable + hash(path->mnt, path->dentry)); list_add_tail(&mnt->mnt.mnt_child, &path->mnt->mnt_mounts); @@ -1617,7 +1617,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, attach_mnt(source_mnt, path); touch_mnt_namespace(parent_path->mnt->mnt_ns); } else { - mnt_set_mountpoint(dest_mnt, dest_dentry, &source_mnt->mnt); + mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); commit_tree(source_mnt); } diff --git a/fs/pnode.c b/fs/pnode.c index 5d79f38e3e8a..89ea50dc2af3 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -246,7 +246,7 @@ int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, } if (is_subdir(dest_dentry, m->mnt_root)) { - mnt_set_mountpoint(m, dest_dentry, &child->mnt); + mnt_set_mountpoint(m, dest_dentry, child); list_add_tail(&child->mnt_hash, tree_list); } else { /* diff --git a/fs/pnode.h b/fs/pnode.h index 609ec008d5ce..bfd0bbcabf6d 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -38,7 +38,7 @@ void mnt_release_group_id(struct mount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); unsigned int mnt_get_count(struct vfsmount *mnt); void mnt_set_mountpoint(struct vfsmount *, struct dentry *, - struct vfsmount *); + struct mount *); void release_mounts(struct list_head *); void umount_tree(struct mount *, int, struct list_head *); struct mount *copy_tree(struct mount *, struct dentry *, int); -- cgit v1.2.3-70-g09d2 From 1ab597386205f8dc757cf8750465502aeae65154 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 21:35:16 -0500 Subject: vfs: spread struct mount - do_umount/propagate_mount_busy Signed-off-by: Al Viro --- fs/namespace.c | 28 ++++++++++++++-------------- fs/pnode.c | 16 ++++++++-------- fs/pnode.h | 2 +- 3 files changed, 23 insertions(+), 23 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index c11b99af53cf..17927f9eeca4 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1180,7 +1180,7 @@ int may_umount(struct vfsmount *mnt) int ret = 1; down_read(&namespace_sem); br_write_lock(vfsmount_lock); - if (propagate_mount_busy(mnt, 2)) + if (propagate_mount_busy(real_mount(mnt), 2)) ret = 0; br_write_unlock(vfsmount_lock); up_read(&namespace_sem); @@ -1246,13 +1246,13 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) static void shrink_submounts(struct mount *mnt, struct list_head *umounts); -static int do_umount(struct vfsmount *mnt, int flags) +static int do_umount(struct mount *mnt, int flags) { - struct super_block *sb = mnt->mnt_sb; + struct super_block *sb = mnt->mnt.mnt_sb; int retval; LIST_HEAD(umount_list); - retval = security_sb_umount(mnt, flags); + retval = security_sb_umount(&mnt->mnt, flags); if (retval) return retval; @@ -1263,7 +1263,7 @@ static int do_umount(struct vfsmount *mnt, int flags) * (2) the usage count == 1 [parent vfsmount] + 1 [sys_umount] */ if (flags & MNT_EXPIRE) { - if (mnt == current->fs->root.mnt || + if (&mnt->mnt == current->fs->root.mnt || flags & (MNT_FORCE | MNT_DETACH)) return -EINVAL; @@ -1272,13 +1272,13 @@ static int do_umount(struct vfsmount *mnt, int flags) * all race cases, but it's a slowpath. */ br_write_lock(vfsmount_lock); - if (mnt_get_count(mnt) != 2) { + if (mnt_get_count(&mnt->mnt) != 2) { br_write_unlock(vfsmount_lock); return -EBUSY; } br_write_unlock(vfsmount_lock); - if (!xchg(&mnt->mnt_expiry_mark, 1)) + if (!xchg(&mnt->mnt.mnt_expiry_mark, 1)) return -EAGAIN; } @@ -1305,7 +1305,7 @@ static int do_umount(struct vfsmount *mnt, int flags) * /reboot - static binary that would close all descriptors and * call reboot(9). Then init(8) could umount root and exec /reboot. */ - if (mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) { + if (&mnt->mnt == current->fs->root.mnt && !(flags & MNT_DETACH)) { /* * Special case for "unmounting" root ... * we just try to remount it readonly. @@ -1322,12 +1322,12 @@ static int do_umount(struct vfsmount *mnt, int flags) event++; if (!(flags & MNT_DETACH)) - shrink_submounts(real_mount(mnt), &umount_list); + shrink_submounts(mnt, &umount_list); retval = -EBUSY; if (flags & MNT_DETACH || !propagate_mount_busy(mnt, 2)) { - if (!list_empty(&mnt->mnt_list)) - umount_tree(real_mount(mnt), 1, &umount_list); + if (!list_empty(&mnt->mnt.mnt_list)) + umount_tree(mnt, 1, &umount_list); retval = 0; } br_write_unlock(vfsmount_lock); @@ -1369,7 +1369,7 @@ SYSCALL_DEFINE2(umount, char __user *, name, int, flags) if (!capable(CAP_SYS_ADMIN)) goto dput_and_out; - retval = do_umount(path.mnt, flags); + retval = do_umount(real_mount(path.mnt), flags); dput_and_out: /* we mustn't call path_put() as that would clear mnt_expiry_mark */ dput(path.dentry); @@ -2101,7 +2101,7 @@ void mark_mounts_for_expiry(struct list_head *mounts) */ list_for_each_entry_safe(mnt, next, mounts, mnt.mnt_expire) { if (!xchg(&mnt->mnt.mnt_expiry_mark, 1) || - propagate_mount_busy(&mnt->mnt, 1)) + propagate_mount_busy(mnt, 1)) continue; list_move(&mnt->mnt.mnt_expire, &graveyard); } @@ -2148,7 +2148,7 @@ resume: goto repeat; } - if (!propagate_mount_busy(&mnt->mnt, 1)) { + if (!propagate_mount_busy(mnt, 1)) { list_move_tail(&mnt->mnt.mnt_expire, graveyard); found++; } diff --git a/fs/pnode.c b/fs/pnode.c index 89ea50dc2af3..3105cca197ec 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -272,9 +272,9 @@ out: /* * return true if the refcount is greater than count */ -static inline int do_refcount_check(struct vfsmount *mnt, int count) +static inline int do_refcount_check(struct mount *mnt, int count) { - int mycount = mnt_get_count(mnt) - mnt->mnt_ghosts; + int mycount = mnt_get_count(&mnt->mnt) - mnt->mnt.mnt_ghosts; return (mycount > count); } @@ -288,14 +288,14 @@ static inline int do_refcount_check(struct vfsmount *mnt, int count) * * vfsmount lock must be held for write */ -int propagate_mount_busy(struct vfsmount *mnt, int refcnt) +int propagate_mount_busy(struct mount *mnt, int refcnt) { struct vfsmount *m; struct mount *child; - struct vfsmount *parent = mnt->mnt_parent; + struct vfsmount *parent = mnt->mnt.mnt_parent; int ret = 0; - if (mnt == parent) + if (&mnt->mnt == parent) return do_refcount_check(mnt, refcnt); /* @@ -303,14 +303,14 @@ int propagate_mount_busy(struct vfsmount *mnt, int refcnt) * If not, we don't have to go checking for all other * mounts */ - if (!list_empty(&mnt->mnt_mounts) || do_refcount_check(mnt, refcnt)) + if (!list_empty(&mnt->mnt.mnt_mounts) || do_refcount_check(mnt, refcnt)) return 1; for (m = propagation_next(parent, parent); m; m = propagation_next(m, parent)) { - child = __lookup_mnt(m, mnt->mnt_mountpoint, 0); + child = __lookup_mnt(m, mnt->mnt.mnt_mountpoint, 0); if (child && list_empty(&child->mnt.mnt_mounts) && - (ret = do_refcount_check(&child->mnt, 1))) + (ret = do_refcount_check(child, 1))) break; } return ret; diff --git a/fs/pnode.h b/fs/pnode.h index bfd0bbcabf6d..f1d251d3771e 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -33,7 +33,7 @@ void change_mnt_propagation(struct mount *, int); int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, struct list_head *); int propagate_umount(struct list_head *); -int propagate_mount_busy(struct vfsmount *, int); +int propagate_mount_busy(struct mount *, int); void mnt_release_group_id(struct mount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); unsigned int mnt_get_count(struct vfsmount *mnt); -- cgit v1.2.3-70-g09d2 From 643822b41e5e0f133438883b0be574cdaf168a2a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 22:00:28 -0500 Subject: vfs: spread struct mount - is_path_reachable Signed-off-by: Al Viro --- fs/namespace.c | 14 +++++++------- fs/pnode.c | 10 +++++----- fs/pnode.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index ced3aa53fb38..b117d94fcdc1 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -2559,21 +2559,21 @@ out_type: * * namespace_sem or vfsmount_lock is held */ -bool is_path_reachable(struct vfsmount *mnt, struct dentry *dentry, +bool is_path_reachable(struct mount *mnt, struct dentry *dentry, const struct path *root) { - while (mnt != root->mnt && mnt_has_parent(real_mount(mnt))) { - dentry = mnt->mnt_mountpoint; - mnt = mnt->mnt_parent; + while (&mnt->mnt != root->mnt && mnt_has_parent(mnt)) { + dentry = mnt->mnt.mnt_mountpoint; + mnt = real_mount(mnt->mnt.mnt_parent); } - return mnt == root->mnt && is_subdir(dentry, root->dentry); + return &mnt->mnt == root->mnt && is_subdir(dentry, root->dentry); } int path_is_under(struct path *path1, struct path *path2) { int res; br_read_lock(vfsmount_lock); - res = is_path_reachable(path1->mnt, path1->dentry, path2); + res = is_path_reachable(real_mount(path1->mnt), path1->dentry, path2); br_read_unlock(vfsmount_lock); return res; } @@ -2659,7 +2659,7 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, if (!mnt_has_parent(new_mnt)) goto out4; /* not attached */ /* make sure we can reach put_old from new_root */ - if (!is_path_reachable(old.mnt, old.dentry, &new)) + if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new)) goto out4; br_write_lock(vfsmount_lock); detach_mnt(new_mnt, &parent_path); diff --git a/fs/pnode.c b/fs/pnode.c index 3105cca197ec..25f74b53dea6 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -32,15 +32,15 @@ static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, struct mnt_namespace *ns, const struct path *root) { - struct vfsmount *m = mnt; + struct mount *m = real_mount(mnt); do { /* Check the namespace first for optimization */ - if (m->mnt_ns == ns && is_path_reachable(m, m->mnt_root, root)) - return m; + if (m->mnt.mnt_ns == ns && is_path_reachable(m, m->mnt.mnt_root, root)) + return &m->mnt; - m = next_peer(m); - } while (m != mnt); + m = real_mount(next_peer(&m->mnt)); + } while (&m->mnt != mnt); return NULL; } diff --git a/fs/pnode.h b/fs/pnode.h index f1d251d3771e..866b3e292887 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -42,6 +42,6 @@ void mnt_set_mountpoint(struct vfsmount *, struct dentry *, void release_mounts(struct list_head *); void umount_tree(struct mount *, int, struct list_head *); struct mount *copy_tree(struct mount *, struct dentry *, int); -bool is_path_reachable(struct vfsmount *, struct dentry *, +bool is_path_reachable(struct mount *, struct dentry *, const struct path *root); #endif /* _LINUX_PNODE_H */ -- cgit v1.2.3-70-g09d2 From 83adc7532229f1909cf37c429780f02f06fe05ee Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 22:37:54 -0500 Subject: vfs: spread struct mount - work with counters Signed-off-by: Al Viro --- fs/namespace.c | 124 +++++++++++++++++++++++++++++---------------------------- fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 66 insertions(+), 62 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index ec798e77b726..a13165c871c2 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -141,13 +141,13 @@ void mnt_release_group_id(struct mount *mnt) /* * vfsmount lock must be held for read */ -static inline void mnt_add_count(struct vfsmount *mnt, int n) +static inline void mnt_add_count(struct mount *mnt, int n) { #ifdef CONFIG_SMP - this_cpu_add(mnt->mnt_pcp->mnt_count, n); + this_cpu_add(mnt->mnt.mnt_pcp->mnt_count, n); #else preempt_disable(); - mnt->mnt_count += n; + mnt->mnt.mnt_count += n; preempt_enable(); #endif } @@ -155,19 +155,19 @@ static inline void mnt_add_count(struct vfsmount *mnt, int n) /* * vfsmount lock must be held for write */ -unsigned int mnt_get_count(struct vfsmount *mnt) +unsigned int mnt_get_count(struct mount *mnt) { #ifdef CONFIG_SMP unsigned int count = 0; int cpu; for_each_possible_cpu(cpu) { - count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_count; + count += per_cpu_ptr(mnt->mnt.mnt_pcp, cpu)->mnt_count; } return count; #else - return mnt->mnt_count; + return mnt->mnt.mnt_count; #endif } @@ -253,32 +253,32 @@ int __mnt_is_readonly(struct vfsmount *mnt) } EXPORT_SYMBOL_GPL(__mnt_is_readonly); -static inline void mnt_inc_writers(struct vfsmount *mnt) +static inline void mnt_inc_writers(struct mount *mnt) { #ifdef CONFIG_SMP - this_cpu_inc(mnt->mnt_pcp->mnt_writers); + this_cpu_inc(mnt->mnt.mnt_pcp->mnt_writers); #else - mnt->mnt_writers++; + mnt->mnt.mnt_writers++; #endif } -static inline void mnt_dec_writers(struct vfsmount *mnt) +static inline void mnt_dec_writers(struct mount *mnt) { #ifdef CONFIG_SMP - this_cpu_dec(mnt->mnt_pcp->mnt_writers); + this_cpu_dec(mnt->mnt.mnt_pcp->mnt_writers); #else - mnt->mnt_writers--; + mnt->mnt.mnt_writers--; #endif } -static unsigned int mnt_get_writers(struct vfsmount *mnt) +static unsigned int mnt_get_writers(struct mount *mnt) { #ifdef CONFIG_SMP unsigned int count = 0; int cpu; for_each_possible_cpu(cpu) { - count += per_cpu_ptr(mnt->mnt_pcp, cpu)->mnt_writers; + count += per_cpu_ptr(mnt->mnt.mnt_pcp, cpu)->mnt_writers; } return count; @@ -297,7 +297,7 @@ static unsigned int mnt_get_writers(struct vfsmount *mnt) */ /** * mnt_want_write - get write access to a mount - * @mnt: the mount on which to take a write + * @m: the mount on which to take a write * * This tells the low-level filesystem that a write is * about to be performed to it, and makes sure that @@ -305,8 +305,9 @@ static unsigned int mnt_get_writers(struct vfsmount *mnt) * the write operation is finished, mnt_drop_write() * must be called. This is effectively a refcount. */ -int mnt_want_write(struct vfsmount *mnt) +int mnt_want_write(struct vfsmount *m) { + struct mount *mnt = real_mount(m); int ret = 0; preempt_disable(); @@ -317,7 +318,7 @@ int mnt_want_write(struct vfsmount *mnt) * incremented count after it has set MNT_WRITE_HOLD. */ smp_mb(); - while (mnt->mnt_flags & MNT_WRITE_HOLD) + while (mnt->mnt.mnt_flags & MNT_WRITE_HOLD) cpu_relax(); /* * After the slowpath clears MNT_WRITE_HOLD, mnt_is_readonly will @@ -325,7 +326,7 @@ int mnt_want_write(struct vfsmount *mnt) * MNT_WRITE_HOLD is cleared. */ smp_rmb(); - if (__mnt_is_readonly(mnt)) { + if (__mnt_is_readonly(m)) { mnt_dec_writers(mnt); ret = -EROFS; goto out; @@ -354,7 +355,7 @@ int mnt_clone_write(struct vfsmount *mnt) if (__mnt_is_readonly(mnt)) return -EROFS; preempt_disable(); - mnt_inc_writers(mnt); + mnt_inc_writers(real_mount(mnt)); preempt_enable(); return 0; } @@ -388,7 +389,7 @@ EXPORT_SYMBOL_GPL(mnt_want_write_file); void mnt_drop_write(struct vfsmount *mnt) { preempt_disable(); - mnt_dec_writers(mnt); + mnt_dec_writers(real_mount(mnt)); preempt_enable(); } EXPORT_SYMBOL_GPL(mnt_drop_write); @@ -399,12 +400,12 @@ void mnt_drop_write_file(struct file *file) } EXPORT_SYMBOL(mnt_drop_write_file); -static int mnt_make_readonly(struct vfsmount *mnt) +static int mnt_make_readonly(struct mount *mnt) { int ret = 0; br_write_lock(vfsmount_lock); - mnt->mnt_flags |= MNT_WRITE_HOLD; + mnt->mnt.mnt_flags |= MNT_WRITE_HOLD; /* * After storing MNT_WRITE_HOLD, we'll read the counters. This store * should be visible before we do. @@ -430,21 +431,21 @@ static int mnt_make_readonly(struct vfsmount *mnt) if (mnt_get_writers(mnt) > 0) ret = -EBUSY; else - mnt->mnt_flags |= MNT_READONLY; + mnt->mnt.mnt_flags |= MNT_READONLY; /* * MNT_READONLY must become visible before ~MNT_WRITE_HOLD, so writers * that become unheld will see MNT_READONLY. */ smp_wmb(); - mnt->mnt_flags &= ~MNT_WRITE_HOLD; + mnt->mnt.mnt_flags &= ~MNT_WRITE_HOLD; br_write_unlock(vfsmount_lock); return ret; } -static void __mnt_unmake_readonly(struct vfsmount *mnt) +static void __mnt_unmake_readonly(struct mount *mnt) { br_write_lock(vfsmount_lock); - mnt->mnt_flags &= ~MNT_READONLY; + mnt->mnt.mnt_flags &= ~MNT_READONLY; br_write_unlock(vfsmount_lock); } @@ -590,18 +591,18 @@ static void attach_mnt(struct mount *mnt, struct path *path) list_add_tail(&mnt->mnt.mnt_child, &path->mnt->mnt_mounts); } -static inline void __mnt_make_longterm(struct vfsmount *mnt) +static inline void __mnt_make_longterm(struct mount *mnt) { #ifdef CONFIG_SMP - atomic_inc(&mnt->mnt_longterm); + atomic_inc(&mnt->mnt.mnt_longterm); #endif } /* needs vfsmount lock for write */ -static inline void __mnt_make_shortterm(struct vfsmount *mnt) +static inline void __mnt_make_shortterm(struct mount *mnt) { #ifdef CONFIG_SMP - atomic_dec(&mnt->mnt_longterm); + atomic_dec(&mnt->mnt.mnt_longterm); #endif } @@ -611,15 +612,15 @@ static inline void __mnt_make_shortterm(struct vfsmount *mnt) static void commit_tree(struct mount *mnt) { struct mount *parent = mnt->mnt_parent; - struct vfsmount *m; + struct mount *m; LIST_HEAD(head); struct mnt_namespace *n = parent->mnt.mnt_ns; BUG_ON(parent == mnt); list_add_tail(&head, &mnt->mnt.mnt_list); - list_for_each_entry(m, &head, mnt_list) { - m->mnt_ns = n; + list_for_each_entry(m, &head, mnt.mnt_list) { + m->mnt.mnt_ns = n; __mnt_make_longterm(m); } @@ -740,9 +741,10 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, return NULL; } -static inline void mntfree(struct vfsmount *mnt) +static inline void mntfree(struct mount *mnt) { - struct super_block *sb = mnt->mnt_sb; + struct vfsmount *m = &mnt->mnt; + struct super_block *sb = m->mnt_sb; /* * This probably indicates that somebody messed @@ -755,18 +757,19 @@ static inline void mntfree(struct vfsmount *mnt) * so mnt_get_writers() below is safe. */ WARN_ON(mnt_get_writers(mnt)); - fsnotify_vfsmount_delete(mnt); - dput(mnt->mnt_root); - free_vfsmnt(real_mount(mnt)); + fsnotify_vfsmount_delete(m); + dput(m->mnt_root); + free_vfsmnt(mnt); deactivate_super(sb); } -static void mntput_no_expire(struct vfsmount *mnt) +static void mntput_no_expire(struct vfsmount *m) { + struct mount *mnt = real_mount(m); put_again: #ifdef CONFIG_SMP br_read_lock(vfsmount_lock); - if (likely(atomic_read(&mnt->mnt_longterm))) { + if (likely(atomic_read(&mnt->mnt.mnt_longterm))) { mnt_add_count(mnt, -1); br_read_unlock(vfsmount_lock); return; @@ -785,11 +788,11 @@ put_again: return; br_write_lock(vfsmount_lock); #endif - if (unlikely(mnt->mnt_pinned)) { - mnt_add_count(mnt, mnt->mnt_pinned + 1); - mnt->mnt_pinned = 0; + if (unlikely(mnt->mnt.mnt_pinned)) { + mnt_add_count(mnt, mnt->mnt.mnt_pinned + 1); + mnt->mnt.mnt_pinned = 0; br_write_unlock(vfsmount_lock); - acct_auto_close_mnt(mnt); + acct_auto_close_mnt(m); goto put_again; } br_write_unlock(vfsmount_lock); @@ -810,7 +813,7 @@ EXPORT_SYMBOL(mntput); struct vfsmount *mntget(struct vfsmount *mnt) { if (mnt) - mnt_add_count(mnt, 1); + mnt_add_count(real_mount(mnt), 1); return mnt; } EXPORT_SYMBOL(mntget); @@ -827,7 +830,7 @@ void mnt_unpin(struct vfsmount *mnt) { br_write_lock(vfsmount_lock); if (mnt->mnt_pinned) { - mnt_add_count(mnt, 1); + mnt_add_count(real_mount(mnt), 1); mnt->mnt_pinned--; } br_write_unlock(vfsmount_lock); @@ -1150,7 +1153,7 @@ int may_umount_tree(struct vfsmount *mnt) /* write lock needed for mnt_get_count */ br_write_lock(vfsmount_lock); for (p = real_mount(mnt); p; p = next_mnt(p, mnt)) { - actual_refs += mnt_get_count(&p->mnt); + actual_refs += mnt_get_count(p); minimum_refs += 2; } br_write_unlock(vfsmount_lock); @@ -1234,7 +1237,7 @@ void umount_tree(struct mount *mnt, int propagate, struct list_head *kill) list_del_init(&p->mnt.mnt_list); __touch_mnt_namespace(p->mnt.mnt_ns); p->mnt.mnt_ns = NULL; - __mnt_make_shortterm(&p->mnt); + __mnt_make_shortterm(p); list_del_init(&p->mnt.mnt_child); if (mnt_has_parent(p)) { p->mnt_parent->mnt.mnt_ghosts++; @@ -1273,7 +1276,7 @@ static int do_umount(struct mount *mnt, int flags) * all race cases, but it's a slowpath. */ br_write_lock(vfsmount_lock); - if (mnt_get_count(&mnt->mnt) != 2) { + if (mnt_get_count(mnt) != 2) { br_write_unlock(vfsmount_lock); return -EBUSY; } @@ -1798,9 +1801,9 @@ static int change_mount_flags(struct vfsmount *mnt, int ms_flags) return 0; if (readonly_request) - error = mnt_make_readonly(mnt); + error = mnt_make_readonly(real_mount(mnt)); else - __mnt_unmake_readonly(mnt); + __mnt_unmake_readonly(real_mount(mnt)); return error; } @@ -2034,7 +2037,7 @@ int finish_automount(struct vfsmount *m, struct path *path) /* The new mount record should have at least 2 refs to prevent it being * expired before we get a chance to add it */ - BUG_ON(mnt_get_count(m) < 2); + BUG_ON(mnt_get_count(real_mount(m)) < 2); if (m->mnt_sb == path->mnt->mnt_sb && m->mnt_root == path->dentry) { @@ -2365,16 +2368,17 @@ static struct mnt_namespace *alloc_mnt_ns(void) void mnt_make_longterm(struct vfsmount *mnt) { - __mnt_make_longterm(mnt); + __mnt_make_longterm(real_mount(mnt)); } -void mnt_make_shortterm(struct vfsmount *mnt) +void mnt_make_shortterm(struct vfsmount *m) { #ifdef CONFIG_SMP - if (atomic_add_unless(&mnt->mnt_longterm, -1, 1)) + struct mount *mnt = real_mount(m); + if (atomic_add_unless(&mnt->mnt.mnt_longterm, -1, 1)) return; br_write_lock(vfsmount_lock); - atomic_dec(&mnt->mnt_longterm); + atomic_dec(&mnt->mnt.mnt_longterm); br_write_unlock(vfsmount_lock); #endif } @@ -2418,17 +2422,17 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, q = new; while (p) { q->mnt.mnt_ns = new_ns; - __mnt_make_longterm(&q->mnt); + __mnt_make_longterm(q); if (fs) { if (&p->mnt == fs->root.mnt) { fs->root.mnt = mntget(&q->mnt); - __mnt_make_longterm(&q->mnt); + __mnt_make_longterm(q); mnt_make_shortterm(&p->mnt); rootmnt = &p->mnt; } if (&p->mnt == fs->pwd.mnt) { fs->pwd.mnt = mntget(&q->mnt); - __mnt_make_longterm(&q->mnt); + __mnt_make_longterm(q); mnt_make_shortterm(&p->mnt); pwdmnt = &p->mnt; } @@ -2474,7 +2478,7 @@ static struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt) new_ns = alloc_mnt_ns(); if (!IS_ERR(new_ns)) { mnt->mnt_ns = new_ns; - __mnt_make_longterm(mnt); + __mnt_make_longterm(real_mount(mnt)); new_ns->root = mnt; list_add(&new_ns->list, &new_ns->root->mnt_list); } else { diff --git a/fs/pnode.c b/fs/pnode.c index bd280200bd37..50fdb29eebfe 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -274,7 +274,7 @@ out: */ static inline int do_refcount_check(struct mount *mnt, int count) { - int mycount = mnt_get_count(&mnt->mnt) - mnt->mnt.mnt_ghosts; + int mycount = mnt_get_count(mnt) - mnt->mnt.mnt_ghosts; return (mycount > count); } diff --git a/fs/pnode.h b/fs/pnode.h index 866b3e292887..0a7a919d5efd 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -36,7 +36,7 @@ int propagate_umount(struct list_head *); int propagate_mount_busy(struct mount *, int); void mnt_release_group_id(struct mount *); int get_dominating_id(struct vfsmount *mnt, const struct path *root); -unsigned int mnt_get_count(struct vfsmount *mnt); +unsigned int mnt_get_count(struct mount *mnt); void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct mount *); void release_mounts(struct list_head *); -- cgit v1.2.3-70-g09d2 From 6fc7871fed915914ef441efbe0f9a7c3d0f3bff1 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 23:35:54 -0500 Subject: vfs: spread struct mount - get_dominating_id / do_make_slave next pile of horrors, similar to mnt_parent one; this time it's mnt_master. Signed-off-by: Al Viro --- fs/namespace.c | 2 +- fs/pnode.c | 58 +++++++++++++++++++++++++++++----------------------------- fs/pnode.h | 2 +- 3 files changed, 31 insertions(+), 31 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 9ceb03fe176f..65d011fe982f 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1053,7 +1053,7 @@ static int show_mountinfo(struct seq_file *m, void *v) seq_printf(m, " shared:%i", mnt->mnt_group_id); if (IS_MNT_SLAVE(mnt)) { int master = mnt->mnt_master->mnt_group_id; - int dom = get_dominating_id(mnt, &p->root); + int dom = get_dominating_id(r, &p->root); seq_printf(m, " master:%i", master); if (dom && dom != master) seq_printf(m, " propagate_from:%i", dom); diff --git a/fs/pnode.c b/fs/pnode.c index 8cd90d2ec05e..29e366dec024 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -28,19 +28,19 @@ static inline struct vfsmount *next_slave(struct vfsmount *p) return list_entry(p->mnt_slave.next, struct vfsmount, mnt_slave); } -static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, - struct mnt_namespace *ns, - const struct path *root) +static struct mount *get_peer_under_root(struct mount *mnt, + struct mnt_namespace *ns, + const struct path *root) { - struct mount *m = real_mount(mnt); + struct mount *m = mnt; do { /* Check the namespace first for optimization */ if (m->mnt.mnt_ns == ns && is_path_reachable(m, m->mnt.mnt_root, root)) - return &m->mnt; + return m; m = real_mount(next_peer(&m->mnt)); - } while (&m->mnt != mnt); + } while (m != mnt); return NULL; } @@ -51,22 +51,22 @@ static struct vfsmount *get_peer_under_root(struct vfsmount *mnt, * * Caller must hold namespace_sem */ -int get_dominating_id(struct vfsmount *mnt, const struct path *root) +int get_dominating_id(struct mount *mnt, const struct path *root) { - struct vfsmount *m; + struct mount *m; - for (m = mnt->mnt_master; m != NULL; m = m->mnt_master) { - struct vfsmount *d = get_peer_under_root(m, mnt->mnt_ns, root); + for (m = real_mount(mnt->mnt.mnt_master); m != NULL; m = real_mount(m->mnt.mnt_master)) { + struct mount *d = get_peer_under_root(m, mnt->mnt.mnt_ns, root); if (d) - return d->mnt_group_id; + return d->mnt.mnt_group_id; } return 0; } -static int do_make_slave(struct vfsmount *mnt) +static int do_make_slave(struct mount *mnt) { - struct vfsmount *peer_mnt = mnt, *master = mnt->mnt_master; + struct mount *peer_mnt = mnt, *master = real_mount(mnt->mnt.mnt_master); struct vfsmount *slave_mnt; /* @@ -74,31 +74,31 @@ static int do_make_slave(struct vfsmount *mnt) * same root dentry. If none is available then * slave it to anything that is available. */ - while ((peer_mnt = next_peer(peer_mnt)) != mnt && - peer_mnt->mnt_root != mnt->mnt_root) ; + while ((peer_mnt = real_mount(next_peer(&peer_mnt->mnt))) != mnt && + peer_mnt->mnt.mnt_root != mnt->mnt.mnt_root) ; if (peer_mnt == mnt) { - peer_mnt = next_peer(mnt); + peer_mnt = real_mount(next_peer(&mnt->mnt)); if (peer_mnt == mnt) peer_mnt = NULL; } - if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) - mnt_release_group_id(real_mount(mnt)); + if (IS_MNT_SHARED(&mnt->mnt) && list_empty(&mnt->mnt.mnt_share)) + mnt_release_group_id(mnt); - list_del_init(&mnt->mnt_share); - mnt->mnt_group_id = 0; + list_del_init(&mnt->mnt.mnt_share); + mnt->mnt.mnt_group_id = 0; if (peer_mnt) master = peer_mnt; if (master) { - list_for_each_entry(slave_mnt, &mnt->mnt_slave_list, mnt_slave) - slave_mnt->mnt_master = master; - list_move(&mnt->mnt_slave, &master->mnt_slave_list); - list_splice(&mnt->mnt_slave_list, master->mnt_slave_list.prev); - INIT_LIST_HEAD(&mnt->mnt_slave_list); + list_for_each_entry(slave_mnt, &mnt->mnt.mnt_slave_list, mnt_slave) + slave_mnt->mnt_master = &master->mnt; + list_move(&mnt->mnt.mnt_slave, &master->mnt.mnt_slave_list); + list_splice(&mnt->mnt.mnt_slave_list, master->mnt.mnt_slave_list.prev); + INIT_LIST_HEAD(&mnt->mnt.mnt_slave_list); } else { - struct list_head *p = &mnt->mnt_slave_list; + struct list_head *p = &mnt->mnt.mnt_slave_list; while (!list_empty(p)) { slave_mnt = list_first_entry(p, struct vfsmount, mnt_slave); @@ -106,8 +106,8 @@ static int do_make_slave(struct vfsmount *mnt) slave_mnt->mnt_master = NULL; } } - mnt->mnt_master = master; - CLEAR_MNT_SHARED(mnt); + mnt->mnt.mnt_master = &master->mnt; + CLEAR_MNT_SHARED(&mnt->mnt); return 0; } @@ -120,7 +120,7 @@ void change_mnt_propagation(struct mount *mnt, int type) set_mnt_shared(mnt); return; } - do_make_slave(&mnt->mnt); + do_make_slave(mnt); if (type != MS_SLAVE) { list_del_init(&mnt->mnt.mnt_slave); mnt->mnt.mnt_master = NULL; diff --git a/fs/pnode.h b/fs/pnode.h index 0a7a919d5efd..33f1e3cb3cd2 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -35,7 +35,7 @@ int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, int propagate_umount(struct list_head *); int propagate_mount_busy(struct mount *, int); void mnt_release_group_id(struct mount *); -int get_dominating_id(struct vfsmount *mnt, const struct path *root); +int get_dominating_id(struct mount *mnt, const struct path *root); unsigned int mnt_get_count(struct mount *mnt); void mnt_set_mountpoint(struct vfsmount *, struct dentry *, struct mount *); -- cgit v1.2.3-70-g09d2 From a8d56d8e4fa0cb9a023834363f8d79415d277a1d Mon Sep 17 00:00:00 2001 From: Al Viro Date: Thu, 24 Nov 2011 23:59:29 -0500 Subject: vfs: spread struct mount - propagate_mnt() Signed-off-by: Al Viro --- fs/namespace.c | 12 ++++++------ fs/pnode.c | 12 ++++++------ fs/pnode.h | 2 +- 3 files changed, 13 insertions(+), 13 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 65d011fe982f..8432344333da 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -1595,23 +1595,23 @@ static int attach_recursive_mnt(struct mount *source_mnt, struct path *path, struct path *parent_path) { LIST_HEAD(tree_list); - struct vfsmount *dest_mnt = path->mnt; + struct mount *dest_mnt = real_mount(path->mnt); struct dentry *dest_dentry = path->dentry; struct mount *child, *p; int err; - if (IS_MNT_SHARED(dest_mnt)) { + if (IS_MNT_SHARED(&dest_mnt->mnt)) { err = invent_group_ids(source_mnt, true); if (err) goto out; } - err = propagate_mnt(dest_mnt, dest_dentry, &source_mnt->mnt, &tree_list); + err = propagate_mnt(dest_mnt, dest_dentry, source_mnt, &tree_list); if (err) goto out_cleanup_ids; br_write_lock(vfsmount_lock); - if (IS_MNT_SHARED(dest_mnt)) { + if (IS_MNT_SHARED(&dest_mnt->mnt)) { for (p = source_mnt; p; p = next_mnt(p, &source_mnt->mnt)) set_mnt_shared(p); } @@ -1620,7 +1620,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, attach_mnt(source_mnt, path); touch_mnt_namespace(parent_path->mnt->mnt_ns); } else { - mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); + mnt_set_mountpoint(&dest_mnt->mnt, dest_dentry, source_mnt); commit_tree(source_mnt); } @@ -1633,7 +1633,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, return 0; out_cleanup_ids: - if (IS_MNT_SHARED(dest_mnt)) + if (IS_MNT_SHARED(&dest_mnt->mnt)) cleanup_group_ids(source_mnt, NULL); out: return err; diff --git a/fs/pnode.c b/fs/pnode.c index f86cd4bc31ce..6519b3b4eb15 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -217,18 +217,18 @@ static struct mount *get_source(struct mount *dest, * @source_mnt: source mount. * @tree_list : list of heads of trees to be attached. */ -int propagate_mnt(struct vfsmount *dest_mnt, struct dentry *dest_dentry, - struct vfsmount *source_mnt, struct list_head *tree_list) +int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, + struct mount *source_mnt, struct list_head *tree_list) { struct mount *m, *child; int ret = 0; - struct mount *prev_dest_mnt = real_mount(dest_mnt); - struct mount *prev_src_mnt = real_mount(source_mnt); + struct mount *prev_dest_mnt = dest_mnt; + struct mount *prev_src_mnt = source_mnt; LIST_HEAD(tmp_list); LIST_HEAD(umount_list); - for (m = propagation_next(real_mount(dest_mnt), real_mount(dest_mnt)); m; - m = propagation_next(m, real_mount(dest_mnt))) { + for (m = propagation_next(dest_mnt, dest_mnt); m; + m = propagation_next(m, dest_mnt)) { int type; struct mount *source; diff --git a/fs/pnode.h b/fs/pnode.h index 33f1e3cb3cd2..55546a2f9b51 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -30,7 +30,7 @@ static inline void set_mnt_shared(struct mount *mnt) } void change_mnt_propagation(struct mount *, int); -int propagate_mnt(struct vfsmount *, struct dentry *, struct vfsmount *, +int propagate_mnt(struct mount *, struct dentry *, struct mount *, struct list_head *); int propagate_umount(struct list_head *); int propagate_mount_busy(struct mount *, int); -- cgit v1.2.3-70-g09d2 From 14cf1fa8f54353d9caf6174c1e4280c8c4dcfd7a Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 25 Nov 2011 00:01:17 -0500 Subject: vfs: spread struct mount - remaining argument of mnt_set_mountpoint() Signed-off-by: Al Viro --- fs/namespace.c | 8 ++++---- fs/pnode.c | 2 +- fs/pnode.h | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index 8432344333da..ee42e671afdc 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -570,10 +570,10 @@ static void detach_mnt(struct mount *mnt, struct path *old_path) /* * vfsmount lock must be held for write */ -void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, +void mnt_set_mountpoint(struct mount *mnt, struct dentry *dentry, struct mount *child_mnt) { - child_mnt->mnt_parent = real_mount(mntget(mnt)); + child_mnt->mnt_parent = real_mount(mntget(&mnt->mnt)); child_mnt->mnt_mountpoint = dget(dentry); spin_lock(&dentry->d_lock); dentry->d_flags |= DCACHE_MOUNTED; @@ -585,7 +585,7 @@ void mnt_set_mountpoint(struct vfsmount *mnt, struct dentry *dentry, */ static void attach_mnt(struct mount *mnt, struct path *path) { - mnt_set_mountpoint(path->mnt, path->dentry, mnt); + mnt_set_mountpoint(real_mount(path->mnt), path->dentry, mnt); list_add_tail(&mnt->mnt_hash, mount_hashtable + hash(path->mnt, path->dentry)); list_add_tail(&mnt->mnt_child, &real_mount(path->mnt)->mnt_mounts); @@ -1620,7 +1620,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, attach_mnt(source_mnt, path); touch_mnt_namespace(parent_path->mnt->mnt_ns); } else { - mnt_set_mountpoint(&dest_mnt->mnt, dest_dentry, source_mnt); + mnt_set_mountpoint(dest_mnt, dest_dentry, source_mnt); commit_tree(source_mnt); } diff --git a/fs/pnode.c b/fs/pnode.c index 6519b3b4eb15..0e1de28b1b2e 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -244,7 +244,7 @@ int propagate_mnt(struct mount *dest_mnt, struct dentry *dest_dentry, } if (is_subdir(dest_dentry, m->mnt.mnt_root)) { - mnt_set_mountpoint(&m->mnt, dest_dentry, child); + mnt_set_mountpoint(m, dest_dentry, child); list_add_tail(&child->mnt_hash, tree_list); } else { /* diff --git a/fs/pnode.h b/fs/pnode.h index 55546a2f9b51..54deeda0cdb8 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -37,7 +37,7 @@ int propagate_mount_busy(struct mount *, int); void mnt_release_group_id(struct mount *); int get_dominating_id(struct mount *mnt, const struct path *root); unsigned int mnt_get_count(struct mount *mnt); -void mnt_set_mountpoint(struct vfsmount *, struct dentry *, +void mnt_set_mountpoint(struct mount *, struct dentry *, struct mount *); void release_mounts(struct list_head *); void umount_tree(struct mount *, int, struct list_head *); -- cgit v1.2.3-70-g09d2 From fc7be130c7e91cf693d4bc2d9b11f08a5a4893d0 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 25 Nov 2011 01:05:37 -0500 Subject: vfs: switch pnode.h macros to struct mount * Signed-off-by: Al Viro --- fs/namespace.c | 42 +++++++++++++++++++++--------------------- fs/pnode.c | 6 +++--- fs/pnode.h | 10 +++++----- 3 files changed, 29 insertions(+), 29 deletions(-) (limited to 'fs/pnode.h') diff --git a/fs/namespace.c b/fs/namespace.c index c7b8dbc88fe5..bbe24defcac7 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -716,9 +716,9 @@ static struct mount *clone_mnt(struct mount *old, struct dentry *root, if (flag & CL_SLAVE) { list_add(&mnt->mnt_slave, &old->mnt_slave_list); mnt->mnt_master = old; - CLEAR_MNT_SHARED(&mnt->mnt); + CLEAR_MNT_SHARED(mnt); } else if (!(flag & CL_PRIVATE)) { - if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(&old->mnt)) + if ((flag & CL_MAKE_SHARED) || IS_MNT_SHARED(old)) list_add(&mnt->mnt_share, &old->mnt_share); if (IS_MNT_SLAVE(old)) list_add(&mnt->mnt_slave, &old->mnt_slave); @@ -1050,7 +1050,7 @@ static int show_mountinfo(struct seq_file *m, void *v) show_mnt_opts(m, mnt); /* Tagged fields ("foo:X" or "bar") */ - if (IS_MNT_SHARED(mnt)) + if (IS_MNT_SHARED(r)) seq_printf(m, " shared:%i", r->mnt_group_id); if (IS_MNT_SLAVE(r)) { int master = r->mnt_master->mnt_group_id; @@ -1059,7 +1059,7 @@ static int show_mountinfo(struct seq_file *m, void *v) if (dom && dom != master) seq_printf(m, " propagate_from:%i", dom); } - if (IS_MNT_UNBINDABLE(mnt)) + if (IS_MNT_UNBINDABLE(r)) seq_puts(m, " unbindable"); /* Filesystem specific data */ @@ -1421,7 +1421,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, struct mount *res, *p, *q, *r; struct path path; - if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(&mnt->mnt)) + if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(mnt)) return NULL; res = q = clone_mnt(mnt, dentry, flag); @@ -1436,7 +1436,7 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, continue; for (s = r; s; s = next_mnt(s, &r->mnt)) { - if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(&s->mnt)) { + if (!(flag & CL_COPY_ALL) && IS_MNT_UNBINDABLE(s)) { s = skip_mnt_tree(s); continue; } @@ -1509,7 +1509,7 @@ static void cleanup_group_ids(struct mount *mnt, struct mount *end) struct mount *p; for (p = mnt; p != end; p = next_mnt(p, &mnt->mnt)) { - if (p->mnt_group_id && !IS_MNT_SHARED(&p->mnt)) + if (p->mnt_group_id && !IS_MNT_SHARED(p)) mnt_release_group_id(p); } } @@ -1519,7 +1519,7 @@ static int invent_group_ids(struct mount *mnt, bool recurse) struct mount *p; for (p = mnt; p; p = recurse ? next_mnt(p, &mnt->mnt) : NULL) { - if (!p->mnt_group_id && !IS_MNT_SHARED(&p->mnt)) { + if (!p->mnt_group_id && !IS_MNT_SHARED(p)) { int err = mnt_alloc_group_id(p); if (err) { cleanup_group_ids(mnt, p); @@ -1603,7 +1603,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, struct mount *child, *p; int err; - if (IS_MNT_SHARED(&dest_mnt->mnt)) { + if (IS_MNT_SHARED(dest_mnt)) { err = invent_group_ids(source_mnt, true); if (err) goto out; @@ -1614,7 +1614,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, br_write_lock(vfsmount_lock); - if (IS_MNT_SHARED(&dest_mnt->mnt)) { + if (IS_MNT_SHARED(dest_mnt)) { for (p = source_mnt; p; p = next_mnt(p, &source_mnt->mnt)) set_mnt_shared(p); } @@ -1636,7 +1636,7 @@ static int attach_recursive_mnt(struct mount *source_mnt, return 0; out_cleanup_ids: - if (IS_MNT_SHARED(&dest_mnt->mnt)) + if (IS_MNT_SHARED(dest_mnt)) cleanup_group_ids(source_mnt, NULL); out: return err; @@ -1764,7 +1764,7 @@ static int do_loopback(struct path *path, char *old_name, old = real_mount(old_path.mnt); err = -EINVAL; - if (IS_MNT_UNBINDABLE(old_path.mnt)) + if (IS_MNT_UNBINDABLE(old)) goto out2; if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) @@ -1859,7 +1859,7 @@ static inline int tree_contains_unbindable(struct mount *mnt) { struct mount *p; for (p = mnt; p; p = next_mnt(p, &mnt->mnt)) { - if (IS_MNT_UNBINDABLE(&p->mnt)) + if (IS_MNT_UNBINDABLE(p)) return 1; } return 0; @@ -1884,9 +1884,10 @@ static int do_move_mount(struct path *path, char *old_name) goto out; old = real_mount(old_path.mnt); + p = real_mount(path->mnt); err = -EINVAL; - if (!check_mnt(real_mount(path->mnt)) || !check_mnt(old)) + if (!check_mnt(p) || !check_mnt(old)) goto out1; if (d_unlinked(path->dentry)) @@ -1905,17 +1906,16 @@ static int do_move_mount(struct path *path, char *old_name) /* * Don't move a mount residing in a shared parent. */ - if (IS_MNT_SHARED(&old->mnt_parent->mnt)) + if (IS_MNT_SHARED(old->mnt_parent)) goto out1; /* * Don't move a mount tree containing unbindable mounts to a destination * mount which is shared. */ - if (IS_MNT_SHARED(path->mnt) && - tree_contains_unbindable(old)) + if (IS_MNT_SHARED(p) && tree_contains_unbindable(old)) goto out1; err = -ELOOP; - for (p = real_mount(path->mnt); mnt_has_parent(p); p = p->mnt_parent) + for (; mnt_has_parent(p); p = p->mnt_parent) if (p == old) goto out1; @@ -2643,9 +2643,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root, error = -EINVAL; new_mnt = real_mount(new.mnt); root_mnt = real_mount(root.mnt); - if (IS_MNT_SHARED(old.mnt) || - IS_MNT_SHARED(&new_mnt->mnt_parent->mnt) || - IS_MNT_SHARED(&root_mnt->mnt_parent->mnt)) + if (IS_MNT_SHARED(real_mount(old.mnt)) || + IS_MNT_SHARED(new_mnt->mnt_parent) || + IS_MNT_SHARED(root_mnt->mnt_parent)) goto out4; if (!check_mnt(root_mnt) || !check_mnt(new_mnt)) goto out4; diff --git a/fs/pnode.c b/fs/pnode.c index a40abf20f35e..ab5fa9e1a79a 100644 --- a/fs/pnode.c +++ b/fs/pnode.c @@ -82,7 +82,7 @@ static int do_make_slave(struct mount *mnt) if (peer_mnt == mnt) peer_mnt = NULL; } - if (IS_MNT_SHARED(&mnt->mnt) && list_empty(&mnt->mnt_share)) + if (IS_MNT_SHARED(mnt) && list_empty(&mnt->mnt_share)) mnt_release_group_id(mnt); list_del_init(&mnt->mnt_share); @@ -107,7 +107,7 @@ static int do_make_slave(struct mount *mnt) } } mnt->mnt_master = master; - CLEAR_MNT_SHARED(&mnt->mnt); + CLEAR_MNT_SHARED(mnt); return 0; } @@ -199,7 +199,7 @@ static struct mount *get_source(struct mount *dest, /* slave of the earlier, then */ *type = CL_SLAVE; /* beginning of peer group among the slaves? */ - if (IS_MNT_SHARED(&dest->mnt)) + if (IS_MNT_SHARED(dest)) *type |= CL_MAKE_SHARED; return last_src; } diff --git a/fs/pnode.h b/fs/pnode.h index 54deeda0cdb8..65c60979d541 100644 --- a/fs/pnode.h +++ b/fs/pnode.h @@ -11,11 +11,11 @@ #include #include "mount.h" -#define IS_MNT_SHARED(mnt) ((mnt)->mnt_flags & MNT_SHARED) -#define IS_MNT_SLAVE(mnt) ((mnt)->mnt_master) -#define IS_MNT_NEW(mnt) (!(mnt)->mnt_ns) -#define CLEAR_MNT_SHARED(mnt) ((mnt)->mnt_flags &= ~MNT_SHARED) -#define IS_MNT_UNBINDABLE(mnt) ((mnt)->mnt_flags & MNT_UNBINDABLE) +#define IS_MNT_SHARED(m) ((m)->mnt.mnt_flags & MNT_SHARED) +#define IS_MNT_SLAVE(m) ((m)->mnt_master) +#define IS_MNT_NEW(m) (!(m)->mnt_ns) +#define CLEAR_MNT_SHARED(m) ((m)->mnt.mnt_flags &= ~MNT_SHARED) +#define IS_MNT_UNBINDABLE(m) ((m)->mnt.mnt_flags & MNT_UNBINDABLE) #define CL_EXPIRE 0x01 #define CL_SLAVE 0x02 -- cgit v1.2.3-70-g09d2