vserver 2.0 rc7
[linux-2.6.git] / fs / namespace.c
index c1fcd74..8192e0e 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/mount.h>
 #include <linux/vserver/namespace.h>
 #include <linux/vserver/xid.h>
-
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 
@@ -225,8 +224,6 @@ static int mnt_is_reachable(struct vfsmount *mnt)
        struct dentry *root, *point;
        int ret;
 
-       if (!mnt)
-               return 1;
        if (mnt == mnt->mnt_namespace->root)
                return 1;
 
@@ -269,10 +266,7 @@ static int show_vfsmnt(struct seq_file *m, void *v)
                { 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;
@@ -1347,10 +1341,19 @@ static void chroot_fs_refs(struct nameidata *old_nd, struct nameidata *new_nd)
 }
 
 /*
- * 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.
@@ -1405,10 +1408,10 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
                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 */
@@ -1416,7 +1419,7 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
        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;
@@ -1427,8 +1430,8 @@ asmlinkage long sys_pivot_root(const char __user *new_root, const char __user *p
                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);
@@ -1484,16 +1487,14 @@ static void __init init_mount_tree(void)
 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");
@@ -1503,7 +1504,7 @@ void __init mnt_init(unsigned long mempages)
         * 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++;
@@ -1517,8 +1518,7 @@ void __init mnt_init(unsigned long mempages)
        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;