new helper: mount_subtree()
[pandora-kernel.git] / fs / namespace.c
index b4febb2..50ee303 100644 (file)
@@ -1109,6 +1109,7 @@ static int show_vfsstat(struct seq_file *m, void *v)
 
        /* device */
        if (mnt->mnt_sb->s_op->show_devname) {
+               seq_puts(m, "device ");
                err = mnt->mnt_sb->s_op->show_devname(m, mnt);
        } else {
                if (mnt->mnt_devname) {
@@ -2482,11 +2483,41 @@ struct mnt_namespace *create_mnt_ns(struct vfsmount *mnt)
                __mnt_make_longterm(mnt);
                new_ns->root = mnt;
                list_add(&new_ns->list, &new_ns->root->mnt_list);
+       } else {
+               mntput(mnt);
        }
        return new_ns;
 }
 EXPORT_SYMBOL(create_mnt_ns);
 
+struct dentry *mount_subtree(struct vfsmount *mnt, const char *name)
+{
+       struct mnt_namespace *ns;
+       struct path path;
+       int err;
+
+       ns = create_mnt_ns(mnt);
+       if (IS_ERR(ns))
+               return ERR_CAST(ns);
+
+       err = vfs_path_lookup(mnt->mnt_root, mnt,
+                       name, LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT, &path);
+
+       put_mnt_ns(ns);
+
+       if (err)
+               return ERR_PTR(err);
+
+       /* trade a vfsmount reference for active sb one */
+       atomic_inc(&path.mnt->mnt_sb->s_active);
+       mntput(path.mnt);
+       /* lock the sucker */
+       down_write(&path.mnt->mnt_sb->s_umount);
+       /* ... and return the root of (sub)tree on it */
+       return path.dentry;
+}
+EXPORT_SYMBOL(mount_subtree);
+
 SYSCALL_DEFINE5(mount, char __user *, dev_name, char __user *, dir_name,
                char __user *, type, unsigned long, flags, void __user *, data)
 {