]> git.neil.brown.name Git - history.git/commitdiff
[PATCH] moving stuff to fs/filesystems.c
authorAlexander Viro <viro@math.psu.edu>
Mon, 18 Mar 2002 02:42:06 +0000 (18:42 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Mon, 18 Mar 2002 02:42:06 +0000 (18:42 -0800)
file_system_typer-related code moved from fs/super.c to
fs/filesystems.c

fs/filesystems.c
fs/super.c

index 76eda773d051da2a528f34a97f9ba96713dffdba..9d924215e12c3785f98748e161320295d1a08b6f 100644 (file)
@@ -6,7 +6,226 @@
  *  table of configured filesystems
  */
 
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/kmod.h>
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+/*
+ * Handling of filesystem drivers list.
+ * Rules:
+ *     Inclusion to/removals from/scanning of list are protected by spinlock.
+ *     During the unload module must call unregister_filesystem().
+ *     We can access the fields of list element if:
+ *             1) spinlock is held or
+ *             2) we hold the reference to the module.
+ *     The latter can be guaranteed by call of try_inc_mod_count(); if it
+ *     returned 0 we must skip the element, otherwise we got the reference.
+ *     Once the reference is obtained we can drop the spinlock.
+ */
+
+static struct file_system_type *file_systems;
+static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
+
+/* WARNING: This can be used only if we _already_ own a reference */
+void get_filesystem(struct file_system_type *fs)
+{
+       if (fs->owner)
+               __MOD_INC_USE_COUNT(fs->owner);
+}
+
+void put_filesystem(struct file_system_type *fs)
+{
+       if (fs->owner)
+               __MOD_DEC_USE_COUNT(fs->owner);
+}
+
+static struct file_system_type **find_filesystem(const char *name)
+{
+       struct file_system_type **p;
+       for (p=&file_systems; *p; p=&(*p)->next)
+               if (strcmp((*p)->name,name) == 0)
+                       break;
+       return p;
+}
+
+/**
+ *     register_filesystem - register a new filesystem
+ *     @fs: the file system structure
+ *
+ *     Adds the file system passed to the list of file systems the kernel
+ *     is aware of for mount and other syscalls. Returns 0 on success,
+ *     or a negative errno code on an error.
+ *
+ *     The &struct file_system_type that is passed is linked into the kernel 
+ *     structures and must not be freed until the file system has been
+ *     unregistered.
+ */
+int register_filesystem(struct file_system_type * fs)
+{
+       int res = 0;
+       struct file_system_type ** p;
+
+       if (!fs)
+               return -EINVAL;
+       if (fs->next)
+               return -EBUSY;
+       INIT_LIST_HEAD(&fs->fs_supers);
+       write_lock(&file_systems_lock);
+       p = find_filesystem(fs->name);
+       if (*p)
+               res = -EBUSY;
+       else
+               *p = fs;
+       write_unlock(&file_systems_lock);
+       return res;
+}
+
+/**
+ *     unregister_filesystem - unregister a file system
+ *     @fs: filesystem to unregister
+ *
+ *     Remove a file system that was previously successfully registered
+ *     with the kernel. An error is returned if the file system is not found.
+ *     Zero is returned on a success.
+ *     
+ *     Once this function has returned the &struct file_system_type structure
+ *     may be freed or reused.
+ */
+int unregister_filesystem(struct file_system_type * fs)
+{
+       struct file_system_type ** tmp;
+
+       write_lock(&file_systems_lock);
+       tmp = &file_systems;
+       while (*tmp) {
+               if (fs == *tmp) {
+                       *tmp = fs->next;
+                       fs->next = NULL;
+                       write_unlock(&file_systems_lock);
+                       return 0;
+               }
+               tmp = &(*tmp)->next;
+       }
+       write_unlock(&file_systems_lock);
+       return -EINVAL;
+}
+
+static int fs_index(const char * __name)
+{
+       struct file_system_type * tmp;
+       char * name;
+       int err, index;
+
+       name = getname(__name);
+       err = PTR_ERR(name);
+       if (IS_ERR(name))
+               return err;
+
+       err = -EINVAL;
+       read_lock(&file_systems_lock);
+       for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
+               if (strcmp(tmp->name,name) == 0) {
+                       err = index;
+                       break;
+               }
+       }
+       read_unlock(&file_systems_lock);
+       putname(name);
+       return err;
+}
+
+static int fs_name(unsigned int index, char * buf)
+{
+       struct file_system_type * tmp;
+       int len, res;
+
+       read_lock(&file_systems_lock);
+       for (tmp = file_systems; tmp; tmp = tmp->next, index--)
+               if (index <= 0 && try_inc_mod_count(tmp->owner))
+                               break;
+       read_unlock(&file_systems_lock);
+       if (!tmp)
+               return -EINVAL;
+
+       /* OK, we got the reference, so we can safely block */
+       len = strlen(tmp->name) + 1;
+       res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
+       put_filesystem(tmp);
+       return res;
+}
+
+static int fs_maxindex(void)
+{
+       struct file_system_type * tmp;
+       int index;
+
+       read_lock(&file_systems_lock);
+       for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
+               ;
+       read_unlock(&file_systems_lock);
+       return index;
+}
+
 /*
- * Code will move here from fs/super.c and yes, it will be fs type handling
- * stuff.
+ * Whee.. Weird sysv syscall. 
  */
+asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2)
+{
+       int retval = -EINVAL;
+
+       switch (option) {
+               case 1:
+                       retval = fs_index((const char *) arg1);
+                       break;
+
+               case 2:
+                       retval = fs_name(arg1, (char *) arg2);
+                       break;
+
+               case 3:
+                       retval = fs_maxindex();
+                       break;
+       }
+       return retval;
+}
+
+int get_filesystem_list(char * buf)
+{
+       int len = 0;
+       struct file_system_type * tmp;
+
+       read_lock(&file_systems_lock);
+       tmp = file_systems;
+       while (tmp && len < PAGE_SIZE - 80) {
+               len += sprintf(buf+len, "%s\t%s\n",
+                       (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
+                       tmp->name);
+               tmp = tmp->next;
+       }
+       read_unlock(&file_systems_lock);
+       return len;
+}
+
+struct file_system_type *get_fs_type(const char *name)
+{
+       struct file_system_type *fs;
+
+       read_lock(&file_systems_lock);
+       fs = *(find_filesystem(name));
+       if (fs && !try_inc_mod_count(fs->owner))
+               fs = NULL;
+       read_unlock(&file_systems_lock);
+       if (!fs && (request_module(name) == 0)) {
+               read_lock(&file_systems_lock);
+               fs = *(find_filesystem(name));
+               if (fs && !try_inc_mod_count(fs->owner))
+                       fs = NULL;
+               read_unlock(&file_systems_lock);
+       }
+       return fs;
+}
index 66a6274d1b718dddcf84f3bf324c9e49f65adfd8..1a2d66737e087876d8b041206102a21365c7cbcb 100644 (file)
 #include <linux/locks.h>
 #include <linux/smp_lock.h>
 #include <linux/devfs_fs_kernel.h>
-#include <linux/major.h>
 #include <linux/acct.h>
-
 #include <asm/uaccess.h>
 
-#include <linux/kmod.h>
-#define __NO_VERSION__
-#include <linux/module.h>
+void get_filesystem(struct file_system_type *fs);
+void put_filesystem(struct file_system_type *fs);
+struct file_system_type *get_fs_type(const char *name);
 
 LIST_HEAD(super_blocks);
 spinlock_t sb_lock = SPIN_LOCK_UNLOCKED;
 
-/*
- * Handling of filesystem drivers list.
- * Rules:
- *     Inclusion to/removals from/scanning of list are protected by spinlock.
- *     During the unload module must call unregister_filesystem().
- *     We can access the fields of list element if:
- *             1) spinlock is held or
- *             2) we hold the reference to the module.
- *     The latter can be guaranteed by call of try_inc_mod_count(); if it
- *     returned 0 we must skip the element, otherwise we got the reference.
- *     Once the reference is obtained we can drop the spinlock.
- */
-
-static struct file_system_type *file_systems;
-static rwlock_t file_systems_lock = RW_LOCK_UNLOCKED;
-
-/* WARNING: This can be used only if we _already_ own a reference */
-static void get_filesystem(struct file_system_type *fs)
-{
-       if (fs->owner)
-               __MOD_INC_USE_COUNT(fs->owner);
-}
-
-static void put_filesystem(struct file_system_type *fs)
-{
-       if (fs->owner)
-               __MOD_DEC_USE_COUNT(fs->owner);
-}
-
-static struct file_system_type **find_filesystem(const char *name)
-{
-       struct file_system_type **p;
-       for (p=&file_systems; *p; p=&(*p)->next)
-               if (strcmp((*p)->name,name) == 0)
-                       break;
-       return p;
-}
-
-/**
- *     register_filesystem - register a new filesystem
- *     @fs: the file system structure
- *
- *     Adds the file system passed to the list of file systems the kernel
- *     is aware of for mount and other syscalls. Returns 0 on success,
- *     or a negative errno code on an error.
- *
- *     The &struct file_system_type that is passed is linked into the kernel 
- *     structures and must not be freed until the file system has been
- *     unregistered.
- */
-int register_filesystem(struct file_system_type * fs)
-{
-       int res = 0;
-       struct file_system_type ** p;
-
-       if (!fs)
-               return -EINVAL;
-       if (fs->next)
-               return -EBUSY;
-       INIT_LIST_HEAD(&fs->fs_supers);
-       write_lock(&file_systems_lock);
-       p = find_filesystem(fs->name);
-       if (*p)
-               res = -EBUSY;
-       else
-               *p = fs;
-       write_unlock(&file_systems_lock);
-       return res;
-}
-
-/**
- *     unregister_filesystem - unregister a file system
- *     @fs: filesystem to unregister
- *
- *     Remove a file system that was previously successfully registered
- *     with the kernel. An error is returned if the file system is not found.
- *     Zero is returned on a success.
- *     
- *     Once this function has returned the &struct file_system_type structure
- *     may be freed or reused.
- */
-int unregister_filesystem(struct file_system_type * fs)
-{
-       struct file_system_type ** tmp;
-
-       write_lock(&file_systems_lock);
-       tmp = &file_systems;
-       while (*tmp) {
-               if (fs == *tmp) {
-                       *tmp = fs->next;
-                       fs->next = NULL;
-                       write_unlock(&file_systems_lock);
-                       return 0;
-               }
-               tmp = &(*tmp)->next;
-       }
-       write_unlock(&file_systems_lock);
-       return -EINVAL;
-}
-
-static int fs_index(const char * __name)
-{
-       struct file_system_type * tmp;
-       char * name;
-       int err, index;
-
-       name = getname(__name);
-       err = PTR_ERR(name);
-       if (IS_ERR(name))
-               return err;
-
-       err = -EINVAL;
-       read_lock(&file_systems_lock);
-       for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
-               if (strcmp(tmp->name,name) == 0) {
-                       err = index;
-                       break;
-               }
-       }
-       read_unlock(&file_systems_lock);
-       putname(name);
-       return err;
-}
-
-static int fs_name(unsigned int index, char * buf)
-{
-       struct file_system_type * tmp;
-       int len, res;
-
-       read_lock(&file_systems_lock);
-       for (tmp = file_systems; tmp; tmp = tmp->next, index--)
-               if (index <= 0 && try_inc_mod_count(tmp->owner))
-                               break;
-       read_unlock(&file_systems_lock);
-       if (!tmp)
-               return -EINVAL;
-
-       /* OK, we got the reference, so we can safely block */
-       len = strlen(tmp->name) + 1;
-       res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
-       put_filesystem(tmp);
-       return res;
-}
-
-static int fs_maxindex(void)
-{
-       struct file_system_type * tmp;
-       int index;
-
-       read_lock(&file_systems_lock);
-       for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
-               ;
-       read_unlock(&file_systems_lock);
-       return index;
-}
-
-/*
- * Whee.. Weird sysv syscall. 
- */
-asmlinkage long sys_sysfs(int option, unsigned long arg1, unsigned long arg2)
-{
-       int retval = -EINVAL;
-
-       switch (option) {
-               case 1:
-                       retval = fs_index((const char *) arg1);
-                       break;
-
-               case 2:
-                       retval = fs_name(arg1, (char *) arg2);
-                       break;
-
-               case 3:
-                       retval = fs_maxindex();
-                       break;
-       }
-       return retval;
-}
-
-int get_filesystem_list(char * buf)
-{
-       int len = 0;
-       struct file_system_type * tmp;
-
-       read_lock(&file_systems_lock);
-       tmp = file_systems;
-       while (tmp && len < PAGE_SIZE - 80) {
-               len += sprintf(buf+len, "%s\t%s\n",
-                       (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
-                       tmp->name);
-               tmp = tmp->next;
-       }
-       read_unlock(&file_systems_lock);
-       return len;
-}
-
-struct file_system_type *get_fs_type(const char *name)
-{
-       struct file_system_type *fs;
-       
-       read_lock(&file_systems_lock);
-       fs = *(find_filesystem(name));
-       if (fs && !try_inc_mod_count(fs->owner))
-               fs = NULL;
-       read_unlock(&file_systems_lock);
-       if (!fs && (request_module(name) == 0)) {
-               read_lock(&file_systems_lock);
-               fs = *(find_filesystem(name));
-               if (fs && !try_inc_mod_count(fs->owner))
-                       fs = NULL;
-               read_unlock(&file_systems_lock);
-       }
-       return fs;
-}
-
 /**
  *     alloc_super     -       create new superblock
  *