diff options
| author | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 20:30:36 +0300 | 
|---|---|---|
| committer | Adrian Bunk <bunk@r063144.stusta.swh.mhn.de> | 2006-03-20 20:30:36 +0300 | 
| commit | 0f76ee451484d02c7405d92e7bceb39b415abb01 (patch) | |
| tree | 9722f84281f786ba48971dde057f5171a49969e4 /fs/namespace.c | |
| parent | 01d206a7c1167639f6ca6dac22140fbdca017558 (diff) | |
| parent | 7705a8792b0fc82fd7d4dd923724606bbfd9fb20 (diff) | |
| download | linux-0f76ee451484d02c7405d92e7bceb39b415abb01.tar.xz | |
Merge with git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
Diffstat (limited to 'fs/namespace.c')
| -rw-r--r-- | fs/namespace.c | 61 | 
1 files changed, 38 insertions, 23 deletions
diff --git a/fs/namespace.c b/fs/namespace.c index ce97becff461..39c81a8d6316 100644 --- a/fs/namespace.c +++ b/fs/namespace.c @@ -494,7 +494,7 @@ void umount_tree(struct vfsmount *mnt, int propagate, struct list_head *kill)  		p->mnt_namespace = NULL;  		list_del_init(&p->mnt_child);  		if (p->mnt_parent != p) -			mnt->mnt_mountpoint->d_mounted--; +			p->mnt_mountpoint->d_mounted--;  		change_mnt_propagation(p, MS_PRIVATE);  	}  } @@ -1325,30 +1325,20 @@ dput_out:  	return retval;  } -int copy_namespace(int flags, struct task_struct *tsk) +/* + * Allocate a new namespace structure and populate it with contents + * copied from the namespace of the passed in task structure. + */ +struct namespace *dup_namespace(struct task_struct *tsk, struct fs_struct *fs)  {  	struct namespace *namespace = tsk->namespace;  	struct namespace *new_ns;  	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL; -	struct fs_struct *fs = tsk->fs;  	struct vfsmount *p, *q; -	if (!namespace) -		return 0; - -	get_namespace(namespace); - -	if (!(flags & CLONE_NEWNS)) -		return 0; - -	if (!capable(CAP_SYS_ADMIN)) { -		put_namespace(namespace); -		return -EPERM; -	} -  	new_ns = kmalloc(sizeof(struct namespace), GFP_KERNEL);  	if (!new_ns) -		goto out; +		return NULL;  	atomic_set(&new_ns->count, 1);  	INIT_LIST_HEAD(&new_ns->list); @@ -1362,7 +1352,7 @@ int copy_namespace(int flags, struct task_struct *tsk)  	if (!new_ns->root) {  		up_write(&namespace_sem);  		kfree(new_ns); -		goto out; +		return NULL;  	}  	spin_lock(&vfsmount_lock);  	list_add_tail(&new_ns->list, &new_ns->root->mnt_list); @@ -1396,8 +1386,6 @@ int copy_namespace(int flags, struct task_struct *tsk)  	}  	up_write(&namespace_sem); -	tsk->namespace = new_ns; -  	if (rootmnt)  		mntput(rootmnt);  	if (pwdmnt) @@ -1405,12 +1393,39 @@ int copy_namespace(int flags, struct task_struct *tsk)  	if (altrootmnt)  		mntput(altrootmnt); -	put_namespace(namespace); -	return 0; +	return new_ns; +} + +int copy_namespace(int flags, struct task_struct *tsk) +{ +	struct namespace *namespace = tsk->namespace; +	struct namespace *new_ns; +	int err = 0; + +	if (!namespace) +		return 0; + +	get_namespace(namespace); + +	if (!(flags & CLONE_NEWNS)) +		return 0; + +	if (!capable(CAP_SYS_ADMIN)) { +		err = -EPERM; +		goto out; +	} + +	new_ns = dup_namespace(tsk, tsk->fs); +	if (!new_ns) { +		err = -ENOMEM; +		goto out; +	} + +	tsk->namespace = new_ns;  out:  	put_namespace(namespace); -	return -ENOMEM; +	return err;  }  asmlinkage long sys_mount(char __user * dev_name, char __user * dir_name,  | 
