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,  | 
