]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/namespace.c
timerfd: wire the new timerfd API to the x86 family
[linux-2.6-omap-h63xx.git] / fs / namespace.c
index c811a94e4c88066c929d6924633e6099efde3114..61bf376e29e85bfda2456cb929c0a0eeb38af1b3 100644 (file)
@@ -28,6 +28,7 @@
 #include <asm/uaccess.h>
 #include <asm/unistd.h>
 #include "pnode.h"
+#include "internal.h"
 
 /* spinlock for vfsmount related operations, inplace of dcache_lock */
 __cacheline_aligned_in_smp DEFINE_SPINLOCK(vfsmount_lock);
@@ -40,8 +41,8 @@ static struct kmem_cache *mnt_cache __read_mostly;
 static struct rw_semaphore namespace_sem;
 
 /* /sys/fs */
-decl_subsys(fs, NULL, NULL);
-EXPORT_SYMBOL_GPL(fs_subsys);
+struct kobject *fs_kobj;
+EXPORT_SYMBOL_GPL(fs_kobj);
 
 static inline unsigned long hash(struct vfsmount *mnt, struct dentry *dentry)
 {
@@ -245,7 +246,7 @@ static struct vfsmount *clone_mnt(struct vfsmount *old, struct dentry *root,
                        list_add(&mnt->mnt_slave, &old->mnt_slave_list);
                        mnt->mnt_master = old;
                        CLEAR_MNT_SHARED(mnt);
-               } else {
+               } else if (!(flag & CL_PRIVATE)) {
                        if ((flag & CL_PROPAGATION) || IS_MNT_SHARED(old))
                                list_add(&mnt->mnt_share, &old->mnt_share);
                        if (IS_MNT_SLAVE(old))
@@ -745,6 +746,26 @@ Enomem:
        return NULL;
 }
 
+struct vfsmount *collect_mounts(struct vfsmount *mnt, struct dentry *dentry)
+{
+       struct vfsmount *tree;
+       down_read(&namespace_sem);
+       tree = copy_tree(mnt, dentry, CL_COPY_ALL | CL_PRIVATE);
+       up_read(&namespace_sem);
+       return tree;
+}
+
+void drop_collected_mounts(struct vfsmount *mnt)
+{
+       LIST_HEAD(umount_list);
+       down_read(&namespace_sem);
+       spin_lock(&vfsmount_lock);
+       umount_tree(mnt, 0, &umount_list);
+       spin_unlock(&vfsmount_lock);
+       up_read(&namespace_sem);
+       release_mounts(&umount_list);
+}
+
 /*
  *  @source_mnt : mount tree to be attached
  *  @nd         : place the mount tree @source_mnt is attached
@@ -1410,7 +1431,7 @@ long do_mount(char *dev_name, char *dir_name, char *type_page,
                mnt_flags |= MNT_RELATIME;
 
        flags &= ~(MS_NOSUID | MS_NOEXEC | MS_NODEV | MS_ACTIVE |
-                  MS_NOATIME | MS_NODIRATIME | MS_RELATIME);
+                  MS_NOATIME | MS_NODIRATIME | MS_RELATIME| MS_KERNMOUNT);
 
        /* ... and get the mountpoint */
        retval = path_lookup(dir_name, LOOKUP_FOLLOW, &nd);
@@ -1451,7 +1472,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
 
        new_ns = kmalloc(sizeof(struct mnt_namespace), GFP_KERNEL);
        if (!new_ns)
-               return NULL;
+               return ERR_PTR(-ENOMEM);
 
        atomic_set(&new_ns->count, 1);
        INIT_LIST_HEAD(&new_ns->list);
@@ -1465,7 +1486,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        if (!new_ns->root) {
                up_write(&namespace_sem);
                kfree(new_ns);
-               return NULL;
+               return ERR_PTR(-ENOMEM);;
        }
        spin_lock(&vfsmount_lock);
        list_add_tail(&new_ns->list, &new_ns->root->mnt_list);
@@ -1509,7 +1530,7 @@ static struct mnt_namespace *dup_mnt_ns(struct mnt_namespace *mnt_ns,
        return new_ns;
 }
 
-struct mnt_namespace *copy_mnt_ns(int flags, struct mnt_namespace *ns,
+struct mnt_namespace *copy_mnt_ns(unsigned long flags, struct mnt_namespace *ns,
                struct fs_struct *new_fs)
 {
        struct mnt_namespace *new_ns;
@@ -1790,7 +1811,7 @@ static void __init init_mount_tree(void)
        set_fs_root(current->fs, ns->root, ns->root->mnt_root);
 }
 
-void __init mnt_init(unsigned long mempages)
+void __init mnt_init(void)
 {
        struct list_head *d;
        unsigned int nr_hash;
@@ -1800,7 +1821,7 @@ void __init mnt_init(unsigned long mempages)
        init_rwsem(&namespace_sem);
 
        mnt_cache = kmem_cache_create("mnt_cache", sizeof(struct vfsmount),
-                       0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL, NULL);
+                       0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, NULL);
 
        mount_hashtable = (struct list_head *)__get_free_page(GFP_ATOMIC);
 
@@ -1840,10 +1861,9 @@ void __init mnt_init(unsigned long mempages)
        if (err)
                printk(KERN_WARNING "%s: sysfs_init error: %d\n",
                        __FUNCTION__, err);
-       err = subsystem_register(&fs_subsys);
-       if (err)
-               printk(KERN_WARNING "%s: subsystem_register error: %d\n",
-                       __FUNCTION__, err);
+       fs_kobj = kobject_create_and_add("fs", NULL);
+       if (!fs_kobj)
+               printk(KERN_WARNING "%s: kobj create error\n", __FUNCTION__);
        init_rootfs();
        init_mount_tree();
 }