}
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;
list_add(&mnt->mnt.mnt_expire, &old->mnt_expire);
}
}
- return &mnt->mnt;
+ return mnt;
out_free:
free_vfsmnt(mnt);
#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))
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) {
}
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);
}
}
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);
}
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)
{
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;
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:
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))
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);
* 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);
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;
}
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);