CL_EXPIRE); 
CL_COPY_ALL | CL_EXPIRE); 
int copy_namespace(int flags, struct task_struct *tsk){	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;	atomic_set(&new_ns->count, 1);	INIT_LIST_HEAD(&new_ns->list);	init_waitqueue_head(&new_ns->poll);	new_ns->event = 0;	down_write(&namespace_sem);	/* First pass: copy the tree topology */	new_ns->root = copy_tree(namespace->root, namespace->root->mnt_root,					CL_EXPIRE);	if (!new_ns->root) {		up_write(&namespace_sem);		kfree(new_ns);		goto out;	}	spin_lock(&vfsmount_lock);	list_add_tail(&new_ns->list, &new_ns->root->mnt_list);	spin_unlock(&vfsmount_lock);	/*	 * Second pass: switch the tsk->fs->* elements and mark new vfsmounts	 * as belonging to new namespace.  We have already acquired a private	 * fs_struct, so tsk->fs->lock is not needed.	 */	p = namespace->root;	q = new_ns->root;	while (p) {		q->mnt_namespace = new_ns;		if (fs) {			if (p == fs->rootmnt) {				rootmnt = p;				fs->rootmnt = mntget(q);			}			if (p == fs->pwdmnt) {				pwdmnt = p;				fs->pwdmnt = mntget(q);			}			if (p == fs->altrootmnt) {				altrootmnt = p;				fs->altrootmnt = mntget(q);			}		}		p = next_mnt(p, namespace->root);		q = next_mnt(q, new_ns->root);	}	up_write(&namespace_sem);	tsk->namespace = new_ns;	if (rootmnt)		mntput(rootmnt);	if (pwdmnt)		mntput(pwdmnt);	if (altrootmnt)		mntput(altrootmnt);	put_namespace(namespace);	return 0;out:	put_namespace(namespace);	return -ENOMEM;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/9676f0c6389b62bd6b24d77d4b3abdbcfa32d0f2/namespace.c/clean/fs/namespace.c