Commit 7f2da1e7 authored by Al Viro's avatar Al Viro
Browse files

[PATCH] kill altroot



long overdue...

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent 8bb79224
Loading
Loading
Loading
Loading
+2 −87
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@
#include <linux/file.h>
#include <linux/fcntl.h>
#include <linux/device_cgroup.h>
#include <asm/namei.h>
#include <asm/uaccess.h>

#define ACC_MODE(x) ("\000\004\002\006"[(x)&O_ACCMODE])
@@ -562,27 +561,16 @@ out_unlock:
	return result;
}

static int __emul_lookup_dentry(const char *, struct nameidata *);

/* SMP-safe */
static __always_inline int
static __always_inline void
walk_init_root(const char *name, struct nameidata *nd)
{
	struct fs_struct *fs = current->fs;

	read_lock(&fs->lock);
	if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
		nd->path = fs->altroot;
		path_get(&fs->altroot);
		read_unlock(&fs->lock);
		if (__emul_lookup_dentry(name,nd))
			return 0;
		read_lock(&fs->lock);
	}
	nd->path = fs->root;
	path_get(&fs->root);
	read_unlock(&fs->lock);
	return 1;
}

/*
@@ -623,12 +611,9 @@ static __always_inline int __vfs_follow_link(struct nameidata *nd, const char *l

	if (*link == '/') {
		path_put(&nd->path);
		if (!walk_init_root(link, nd))
			/* weird __emul_prefix() stuff did it */
			goto out;
		walk_init_root(link, nd);
	}
	res = link_path_walk(link, nd);
out:
	if (nd->depth || res || nd->last_type!=LAST_NORM)
		return res;
	/*
@@ -1077,67 +1062,6 @@ static int path_walk(const char *name, struct nameidata *nd)
	return link_path_walk(name, nd);
}

/* 
 * SMP-safe: Returns 1 and nd will have valid dentry and mnt, if
 * everything is done. Returns 0 and drops input nd, if lookup failed;
 */
static int __emul_lookup_dentry(const char *name, struct nameidata *nd)
{
	if (path_walk(name, nd))
		return 0;		/* something went wrong... */

	if (!nd->path.dentry->d_inode ||
	    S_ISDIR(nd->path.dentry->d_inode->i_mode)) {
		struct path old_path = nd->path;
		struct qstr last = nd->last;
		int last_type = nd->last_type;
		struct fs_struct *fs = current->fs;

		/*
		 * NAME was not found in alternate root or it's a directory.
		 * Try to find it in the normal root:
		 */
		nd->last_type = LAST_ROOT;
		read_lock(&fs->lock);
		nd->path = fs->root;
		path_get(&fs->root);
		read_unlock(&fs->lock);
		if (path_walk(name, nd) == 0) {
			if (nd->path.dentry->d_inode) {
				path_put(&old_path);
				return 1;
			}
			path_put(&nd->path);
		}
		nd->path = old_path;
		nd->last = last;
		nd->last_type = last_type;
	}
	return 1;
}

void set_fs_altroot(void)
{
	char *emul = __emul_prefix();
	struct nameidata nd;
	struct path path = {}, old_path;
	int err;
	struct fs_struct *fs = current->fs;

	if (!emul)
		goto set_it;
	err = path_lookup(emul, LOOKUP_FOLLOW|LOOKUP_DIRECTORY|LOOKUP_NOALT, &nd);
	if (!err)
		path = nd.path;
set_it:
	write_lock(&fs->lock);
	old_path = fs->altroot;
	fs->altroot = path;
	write_unlock(&fs->lock);
	if (old_path.dentry)
		path_put(&old_path);
}

/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
static int do_path_lookup(int dfd, const char *name,
				unsigned int flags, struct nameidata *nd)
@@ -1153,14 +1077,6 @@ static int do_path_lookup(int dfd, const char *name,

	if (*name=='/') {
		read_lock(&fs->lock);
		if (fs->altroot.dentry && !(nd->flags & LOOKUP_NOALT)) {
			nd->path = fs->altroot;
			path_get(&fs->altroot);
			read_unlock(&fs->lock);
			if (__emul_lookup_dentry(name,nd))
				goto out; /* found in altroot */
			read_lock(&fs->lock);
		}
		nd->path = fs->root;
		path_get(&fs->root);
		read_unlock(&fs->lock);
@@ -1194,7 +1110,6 @@ static int do_path_lookup(int dfd, const char *name,
	}

	retval = path_walk(name, nd);
out:
	if (unlikely(!retval && !audit_dummy_context() && nd->path.dentry &&
				nd->path.dentry->d_inode))
		audit_inode(name, nd->path.dentry);
+1 −7
Original line number Diff line number Diff line
@@ -1972,7 +1972,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
		struct fs_struct *fs)
{
	struct mnt_namespace *new_ns;
	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL, *altrootmnt = NULL;
	struct vfsmount *rootmnt = NULL, *pwdmnt = NULL;
	struct vfsmount *p, *q;

	new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
@@ -2015,10 +2015,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
				pwdmnt = p;
				fs->pwd.mnt = mntget(q);
			}
			if (p == fs->altroot.mnt) {
				altrootmnt = p;
				fs->altroot.mnt = mntget(q);
			}
		}
		p = next_mnt(p, mnt_ns->root);
		q = next_mnt(q, new_ns->root);
@@ -2029,8 +2025,6 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
		mntput(rootmnt);
	if (pwdmnt)
		mntput(pwdmnt);
	if (altrootmnt)
		mntput(altrootmnt);

	return new_ns;
}
+1 −2
Original line number Diff line number Diff line
@@ -548,7 +548,7 @@ asmlinkage long sys_chroot(const char __user * filename)
	struct nameidata nd;
	int error;

	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd);
	error = __user_walk(filename, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &nd);
	if (error)
		goto out;

@@ -561,7 +561,6 @@ asmlinkage long sys_chroot(const char __user * filename)
		goto dput_and_out;

	set_fs_root(current->fs, &nd.path);
	set_fs_altroot();
	error = 0;
dput_and_out:
	path_put(&nd.path);

include/asm-alpha/namei.h

deleted100644 → 0
+0 −17
Original line number Diff line number Diff line
/* $Id: namei.h,v 1.1 1996/12/13 14:48:21 jj Exp $
 * linux/include/asm-alpha/namei.h
 *
 * Included from linux/fs/namei.c
 */

#ifndef __ALPHA_NAMEI_H
#define __ALPHA_NAMEI_H

/* This dummy routine maybe changed to something useful
 * for /usr/gnemul/ emulation stuff.
 * Look at asm-sparc/namei.h for details.
 */

#define __emul_prefix() NULL

#endif /* __ALPHA_NAMEI_H */

include/asm-arm/namei.h

deleted100644 → 0
+0 −25
Original line number Diff line number Diff line
/* 
 * linux/include/asm-arm/namei.h
 *
 * Routines to handle famous /usr/gnemul
 * Derived from the Sparc version of this file
 *
 * Included from linux/fs/namei.c
 */

#ifndef __ASMARM_NAMEI_H
#define __ASMARM_NAMEI_H

#define ARM_BSD_EMUL "usr/gnemul/bsd/"

static inline char *__emul_prefix(void)
{
	switch (current->personality) {
	case PER_BSD:
		return ARM_BSD_EMUL;
	default:
		return NULL;
	}
}

#endif /* __ASMARM_NAMEI_H */
Loading