[PATCH] s390: fix compile with VIRT_CPU_ACCOUNTING=n
[pandora-kernel.git] / fs / namespace.c
index 8bc15b3..058a448 100644 (file)
@@ -48,6 +48,10 @@ static int hash_mask __read_mostly, hash_bits __read_mostly;
 static kmem_cache_t *mnt_cache;
 static struct rw_semaphore namespace_sem;
 
+/* /sys/fs */
+decl_subsys(fs, NULL, NULL);
+EXPORT_SYMBOL_GPL(fs_subsys);
+
 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 {
        unsigned long tmp = ((unsigned long)mnt / L1_CACHE_BYTES);
@@ -490,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);
        }
 }
@@ -1321,27 +1325,17 @@ 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;
@@ -1392,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)
@@ -1401,12 +1393,40 @@ int copy_namespace(int flags, struct task_struct *tsk)
        if (altrootmnt)
                mntput(altrootmnt);
 
-       put_namespace(namespace);
-       return 0;
+out:
+       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,
@@ -1725,6 +1745,7 @@ void __init mnt_init(unsigned long mempages)
                i--;
        } while (i);
        sysfs_init();
+       subsystem_register(&fs_subsys);
        init_rootfs();
        init_mount_tree();
 }