diff options
Diffstat (limited to 'fs/namespace.c')
-rw-r--r-- | fs/namespace.c | 41 |
1 files changed, 16 insertions, 25 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index fd999cab7b5..b696e3a0d18 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -377,6 +377,10 @@ static int show_vfsmnt(struct seq_file *m, void *v) seq_path(m, mnt, mnt->mnt_root, " \t\n\\"); seq_putc(m, ' '); mangle(m, mnt->mnt_sb->s_type->name); + if (mnt->mnt_sb->s_subtype && mnt->mnt_sb->s_subtype[0]) { + seq_putc(m, '.'); + mangle(m, mnt->mnt_sb->s_subtype); + } seq_puts(m, mnt->mnt_sb->s_flags & MS_RDONLY ? " ro" : " rw"); for (fs_infop = fs_info; fs_infop->flag; fs_infop++) { if (mnt->mnt_sb->s_flags & fs_infop->flag) @@ -495,7 +499,7 @@ void release_mounts(struct list_head *head) { struct vfsmount *mnt; while (!list_empty(head)) { - mnt = list_entry(head->next, struct vfsmount, mnt_hash); + mnt = list_first_entry(head, struct vfsmount, mnt_hash); list_del_init(&mnt->mnt_hash); if (mnt->mnt_parent != mnt) { struct dentry *dentry; @@ -882,6 +886,9 @@ static int do_change_type(struct nameidata *nd, int flag) int recurse = flag & MS_REC; int type = flag & ~MS_REC; + if (!capable(CAP_SYS_ADMIN)) + return -EPERM; + if (nd->dentry != nd->mnt->mnt_root) return -EINVAL; @@ -1173,7 +1180,7 @@ static void expire_mount_list(struct list_head *graveyard, struct list_head *mou while (!list_empty(graveyard)) { LIST_HEAD(umounts); - mnt = list_entry(graveyard->next, struct vfsmount, mnt_expire); + mnt = list_first_entry(graveyard, struct vfsmount, mnt_expire); list_del_init(&mnt->mnt_expire); /* don't do anything if the namespace is dead - all the @@ -1441,10 +1448,9 @@ dput_out: * Allocate a new namespace structure and populate it with contents * copied from the namespace of the passed in task structure. */ -struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, +static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns, struct fs_struct *fs) { - struct mnt_namespace *mnt_ns = tsk->nsproxy->mnt_ns; struct mnt_namespace *new_ns; struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; struct vfsmount *p, *q; @@ -1509,36 +1515,21 @@ struct mnt_namespace *dup_mnt_ns(struct task_struct *tsk, return new_ns; } -int copy_mnt_ns(int flags, struct task_struct *tsk) +struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns, + struct fs_struct *new_fs) { - struct mnt_namespace *ns = tsk->nsproxy->mnt_ns; struct mnt_namespace *new_ns; - int err = 0; - - if (!ns) - return 0; + BUG_ON(!ns); get_mnt_ns(ns); if (!(flags & CLONE_NEWNS)) - return 0; + return ns; - if (!capable(CAP_SYS_ADMIN)) { - err = -EPERM; - goto out; - } - - new_ns = dup_mnt_ns(tsk, tsk->fs); - if (!new_ns) { - err = -ENOMEM; - goto out; - } + new_ns = dup_mnt_ns(ns, new_fs); - tsk->nsproxy->mnt_ns = new_ns; - -out: put_mnt_ns(ns); - return err; + return new_ns; } asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name, |