[XFS] Fix merge failures
[pandora-kernel.git] / fs / filesystems.c
index 7a4f61a..d0e20ce 100644 (file)
@@ -8,6 +8,8 @@
 
 #include <linux/syscalls.h>
 #include <linux/fs.h>
+#include <linux/proc_fs.h>
+#include <linux/seq_file.h>
 #include <linux/slab.h>
 #include <linux/kmod.h>
 #include <linux/init.h>
@@ -41,11 +43,12 @@ void put_filesystem(struct file_system_type *fs)
        module_put(fs->owner);
 }
 
-static struct file_system_type **find_filesystem(const char *name)
+static struct file_system_type **find_filesystem(const char *name, unsigned len)
 {
        struct file_system_type **p;
        for (p=&file_systems; *p; p=&(*p)->next)
-               if (strcmp((*p)->name,name) == 0)
+               if (strlen((*p)->name) == len &&
+                   strncmp((*p)->name, name, len) == 0)
                        break;
        return p;
 }
@@ -68,11 +71,12 @@ int register_filesystem(struct file_system_type * fs)
        int res = 0;
        struct file_system_type ** p;
 
+       BUG_ON(strchr(fs->name, '.'));
        if (fs->next)
                return -EBUSY;
        INIT_LIST_HEAD(&fs->fs_supers);
        write_lock(&file_systems_lock);
-       p = find_filesystem(fs->name);
+       p = find_filesystem(fs->name, strlen(fs->name));
        if (*p)
                res = -EBUSY;
        else
@@ -212,22 +216,66 @@ int get_filesystem_list(char * buf)
        return len;
 }
 
+#ifdef CONFIG_PROC_FS
+static int filesystems_proc_show(struct seq_file *m, void *v)
+{
+       struct file_system_type * tmp;
+
+       read_lock(&file_systems_lock);
+       tmp = file_systems;
+       while (tmp) {
+               seq_printf(m, "%s\t%s\n",
+                       (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
+                       tmp->name);
+               tmp = tmp->next;
+       }
+       read_unlock(&file_systems_lock);
+       return 0;
+}
+
+static int filesystems_proc_open(struct inode *inode, struct file *file)
+{
+       return single_open(file, filesystems_proc_show, NULL);
+}
+
+static const struct file_operations filesystems_proc_fops = {
+       .open           = filesystems_proc_open,
+       .read           = seq_read,
+       .llseek         = seq_lseek,
+       .release        = single_release,
+};
+
+static int __init proc_filesystems_init(void)
+{
+       proc_create("filesystems", 0, NULL, &filesystems_proc_fops);
+       return 0;
+}
+module_init(proc_filesystems_init);
+#endif
+
 struct file_system_type *get_fs_type(const char *name)
 {
        struct file_system_type *fs;
+       const char *dot = strchr(name, '.');
+       unsigned len = dot ? dot - name : strlen(name);
 
        read_lock(&file_systems_lock);
-       fs = *(find_filesystem(name));
+       fs = *(find_filesystem(name, len));
        if (fs && !try_module_get(fs->owner))
                fs = NULL;
        read_unlock(&file_systems_lock);
-       if (!fs && (request_module("%s", name) == 0)) {
+       if (!fs && (request_module("%.*s", len, name) == 0)) {
                read_lock(&file_systems_lock);
-               fs = *(find_filesystem(name));
+               fs = *(find_filesystem(name, len));
                if (fs && !try_module_get(fs->owner))
                        fs = NULL;
                read_unlock(&file_systems_lock);
        }
+
+       if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
+               put_filesystem(fs);
+               fs = NULL;
+       }
        return fs;
 }