#include <linux/mount.h>
#include <linux/vserver/namespace.h>
#include <linux/vserver/xid.h>
-
#include <asm/uaccess.h>
#include <asm/unistd.h>
struct dentry *root, *point;
int ret;
- if (!mnt)
- return 1;
if (mnt == mnt->mnt_namespace->root)
return 1;
{ MNT_NOEXEC, ",noexec" },
{ 0, NULL }
};
-
struct proc_fs_info *fs_infop;
- unsigned long s_flags = mnt->mnt_sb->s_flags;
- int mnt_flags = mnt->mnt_flags;
if (vx_flags(VXF_HIDE_MOUNT, 0))
return 0;
}
/*
- * Moves the current root to put_root, and sets root/cwd of all processes
- * which had them on the old root to new_root.
+ * pivot_root Semantics:
+ * Moves the root file system of the current process to the directory put_old,
+ * makes new_root as the new root file system of the current process, and sets
+ * root/cwd of all processes which had them on the current root to new_root.
*
- * Note:
+ * Restrictions:
+ * The new_root and put_old must be directories, and must not be on the
+ * same file system as the current process root. The put_old must be
+ * underneath new_root, i.e. adding a non-zero number of /.. to the string
+ * pointed to by put_old must yield the same directory as new_root. No other
+ * file system may be mounted on put_old. After all, new_root is a mountpoint.
+ *
+ * Notes:
* - we don't move root/cwd if they are not at the root (reason: if something
* cared enough to change them, it's probably wrong to force them elsewhere)
* - it's okay to pick a root that isn't the root of a file system, e.g.
goto out2;
error = -EBUSY;
if (new_nd.mnt == user_nd.mnt || old_nd.mnt == user_nd.mnt)
- goto out2; /* loop */
+ goto out2; /* loop, on the same file system */
error = -EINVAL;
if (user_nd.mnt->mnt_root != user_nd.dentry)
- goto out2;
+ goto out2; /* not a mountpoint */
if (new_nd.mnt->mnt_root != new_nd.dentry)
goto out2; /* not a mountpoint */
tmp = old_nd.mnt; /* make sure we can reach put_old from new_root */
if (tmp != new_nd.mnt) {
for (;;) {
if (tmp->mnt_parent == tmp)
- goto out3;
+ goto out3; /* already mounted on put_old */
if (tmp->mnt_parent == new_nd.mnt)
break;
tmp = tmp->mnt_parent;
goto out3;
detach_mnt(new_nd.mnt, &parent_nd);
detach_mnt(user_nd.mnt, &root_parent);
- attach_mnt(user_nd.mnt, &old_nd);
- attach_mnt(new_nd.mnt, &root_parent);
+ attach_mnt(user_nd.mnt, &old_nd); /* mount old root on put_old */
+ attach_mnt(new_nd.mnt, &root_parent); /* mount new_root on / */
spin_unlock(&vfsmount_lock);
chroot_fs_refs(&user_nd, &new_nd);
security_sb_post_pivotroot(&user_nd, &new_nd);
void __init mnt_init(unsigned long mempages)
{
struct list_head *d;
- unsigned long order;
unsigned int nr_hash;
int i;
mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
0, SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
- order = 0;
mount_hashtable = (struct list_head *)
- __get_free_pages(GFP_ATOMIC, order);
+ __get_free_page(GFP_ATOMIC);
if (!mount_hashtable)
panic("Failed to allocate mount hash table\n");
* We don't guarantee that "sizeof(struct list_head)" is necessarily
* a power-of-two.
*/
- nr_hash = (1UL << order) * PAGE_SIZE / sizeof(struct list_head);
+ nr_hash = PAGE_SIZE / sizeof(struct list_head);
hash_bits = 0;
do {
hash_bits++;
nr_hash = 1UL << hash_bits;
hash_mask = nr_hash-1;
- printk("Mount-cache hash table entries: %d (order: %ld, %ld bytes)\n",
- nr_hash, order, (PAGE_SIZE << order));
+ printk("Mount-cache hash table entries: %d\n", nr_hash);
/* And initialize the newly allocated array */
d = mount_hashtable;