root/fs/filesystems.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_filesystem
  2. put_filesystem
  3. find_filesystem
  4. register_filesystem
  5. unregister_filesystem
  6. fs_index
  7. fs_name
  8. fs_maxindex
  9. SYSCALL_DEFINE3
  10. get_filesystem_list
  11. filesystems_proc_show
  12. proc_filesystems_init
  13. __get_fs_type
  14. get_fs_type

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  *  linux/fs/filesystems.c
   4  *
   5  *  Copyright (C) 1991, 1992  Linus Torvalds
   6  *
   7  *  table of configured filesystems
   8  */
   9 
  10 #include <linux/syscalls.h>
  11 #include <linux/fs.h>
  12 #include <linux/proc_fs.h>
  13 #include <linux/seq_file.h>
  14 #include <linux/kmod.h>
  15 #include <linux/init.h>
  16 #include <linux/module.h>
  17 #include <linux/slab.h>
  18 #include <linux/uaccess.h>
  19 #include <linux/fs_parser.h>
  20 
  21 /*
  22  * Handling of filesystem drivers list.
  23  * Rules:
  24  *      Inclusion to/removals from/scanning of list are protected by spinlock.
  25  *      During the unload module must call unregister_filesystem().
  26  *      We can access the fields of list element if:
  27  *              1) spinlock is held or
  28  *              2) we hold the reference to the module.
  29  *      The latter can be guaranteed by call of try_module_get(); if it
  30  *      returned 0 we must skip the element, otherwise we got the reference.
  31  *      Once the reference is obtained we can drop the spinlock.
  32  */
  33 
  34 static struct file_system_type *file_systems;
  35 static DEFINE_RWLOCK(file_systems_lock);
  36 
  37 /* WARNING: This can be used only if we _already_ own a reference */
  38 struct file_system_type *get_filesystem(struct file_system_type *fs)
  39 {
  40         __module_get(fs->owner);
  41         return fs;
  42 }
  43 
  44 void put_filesystem(struct file_system_type *fs)
  45 {
  46         module_put(fs->owner);
  47 }
  48 
  49 static struct file_system_type **find_filesystem(const char *name, unsigned len)
  50 {
  51         struct file_system_type **p;
  52         for (p = &file_systems; *p; p = &(*p)->next)
  53                 if (strncmp((*p)->name, name, len) == 0 &&
  54                     !(*p)->name[len])
  55                         break;
  56         return p;
  57 }
  58 
  59 /**
  60  *      register_filesystem - register a new filesystem
  61  *      @fs: the file system structure
  62  *
  63  *      Adds the file system passed to the list of file systems the kernel
  64  *      is aware of for mount and other syscalls. Returns 0 on success,
  65  *      or a negative errno code on an error.
  66  *
  67  *      The &struct file_system_type that is passed is linked into the kernel 
  68  *      structures and must not be freed until the file system has been
  69  *      unregistered.
  70  */
  71  
  72 int register_filesystem(struct file_system_type * fs)
  73 {
  74         int res = 0;
  75         struct file_system_type ** p;
  76 
  77         if (fs->parameters && !fs_validate_description(fs->parameters))
  78                 return -EINVAL;
  79 
  80         BUG_ON(strchr(fs->name, '.'));
  81         if (fs->next)
  82                 return -EBUSY;
  83         write_lock(&file_systems_lock);
  84         p = find_filesystem(fs->name, strlen(fs->name));
  85         if (*p)
  86                 res = -EBUSY;
  87         else
  88                 *p = fs;
  89         write_unlock(&file_systems_lock);
  90         return res;
  91 }
  92 
  93 EXPORT_SYMBOL(register_filesystem);
  94 
  95 /**
  96  *      unregister_filesystem - unregister a file system
  97  *      @fs: filesystem to unregister
  98  *
  99  *      Remove a file system that was previously successfully registered
 100  *      with the kernel. An error is returned if the file system is not found.
 101  *      Zero is returned on a success.
 102  *      
 103  *      Once this function has returned the &struct file_system_type structure
 104  *      may be freed or reused.
 105  */
 106  
 107 int unregister_filesystem(struct file_system_type * fs)
 108 {
 109         struct file_system_type ** tmp;
 110 
 111         write_lock(&file_systems_lock);
 112         tmp = &file_systems;
 113         while (*tmp) {
 114                 if (fs == *tmp) {
 115                         *tmp = fs->next;
 116                         fs->next = NULL;
 117                         write_unlock(&file_systems_lock);
 118                         synchronize_rcu();
 119                         return 0;
 120                 }
 121                 tmp = &(*tmp)->next;
 122         }
 123         write_unlock(&file_systems_lock);
 124 
 125         return -EINVAL;
 126 }
 127 
 128 EXPORT_SYMBOL(unregister_filesystem);
 129 
 130 #ifdef CONFIG_SYSFS_SYSCALL
 131 static int fs_index(const char __user * __name)
 132 {
 133         struct file_system_type * tmp;
 134         struct filename *name;
 135         int err, index;
 136 
 137         name = getname(__name);
 138         err = PTR_ERR(name);
 139         if (IS_ERR(name))
 140                 return err;
 141 
 142         err = -EINVAL;
 143         read_lock(&file_systems_lock);
 144         for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
 145                 if (strcmp(tmp->name, name->name) == 0) {
 146                         err = index;
 147                         break;
 148                 }
 149         }
 150         read_unlock(&file_systems_lock);
 151         putname(name);
 152         return err;
 153 }
 154 
 155 static int fs_name(unsigned int index, char __user * buf)
 156 {
 157         struct file_system_type * tmp;
 158         int len, res;
 159 
 160         read_lock(&file_systems_lock);
 161         for (tmp = file_systems; tmp; tmp = tmp->next, index--)
 162                 if (index <= 0 && try_module_get(tmp->owner))
 163                         break;
 164         read_unlock(&file_systems_lock);
 165         if (!tmp)
 166                 return -EINVAL;
 167 
 168         /* OK, we got the reference, so we can safely block */
 169         len = strlen(tmp->name) + 1;
 170         res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
 171         put_filesystem(tmp);
 172         return res;
 173 }
 174 
 175 static int fs_maxindex(void)
 176 {
 177         struct file_system_type * tmp;
 178         int index;
 179 
 180         read_lock(&file_systems_lock);
 181         for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
 182                 ;
 183         read_unlock(&file_systems_lock);
 184         return index;
 185 }
 186 
 187 /*
 188  * Whee.. Weird sysv syscall. 
 189  */
 190 SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2)
 191 {
 192         int retval = -EINVAL;
 193 
 194         switch (option) {
 195                 case 1:
 196                         retval = fs_index((const char __user *) arg1);
 197                         break;
 198 
 199                 case 2:
 200                         retval = fs_name(arg1, (char __user *) arg2);
 201                         break;
 202 
 203                 case 3:
 204                         retval = fs_maxindex();
 205                         break;
 206         }
 207         return retval;
 208 }
 209 #endif
 210 
 211 int __init get_filesystem_list(char *buf)
 212 {
 213         int len = 0;
 214         struct file_system_type * tmp;
 215 
 216         read_lock(&file_systems_lock);
 217         tmp = file_systems;
 218         while (tmp && len < PAGE_SIZE - 80) {
 219                 len += sprintf(buf+len, "%s\t%s\n",
 220                         (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
 221                         tmp->name);
 222                 tmp = tmp->next;
 223         }
 224         read_unlock(&file_systems_lock);
 225         return len;
 226 }
 227 
 228 #ifdef CONFIG_PROC_FS
 229 static int filesystems_proc_show(struct seq_file *m, void *v)
 230 {
 231         struct file_system_type * tmp;
 232 
 233         read_lock(&file_systems_lock);
 234         tmp = file_systems;
 235         while (tmp) {
 236                 seq_printf(m, "%s\t%s\n",
 237                         (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
 238                         tmp->name);
 239                 tmp = tmp->next;
 240         }
 241         read_unlock(&file_systems_lock);
 242         return 0;
 243 }
 244 
 245 static int __init proc_filesystems_init(void)
 246 {
 247         proc_create_single("filesystems", 0, NULL, filesystems_proc_show);
 248         return 0;
 249 }
 250 module_init(proc_filesystems_init);
 251 #endif
 252 
 253 static struct file_system_type *__get_fs_type(const char *name, int len)
 254 {
 255         struct file_system_type *fs;
 256 
 257         read_lock(&file_systems_lock);
 258         fs = *(find_filesystem(name, len));
 259         if (fs && !try_module_get(fs->owner))
 260                 fs = NULL;
 261         read_unlock(&file_systems_lock);
 262         return fs;
 263 }
 264 
 265 struct file_system_type *get_fs_type(const char *name)
 266 {
 267         struct file_system_type *fs;
 268         const char *dot = strchr(name, '.');
 269         int len = dot ? dot - name : strlen(name);
 270 
 271         fs = __get_fs_type(name, len);
 272         if (!fs && (request_module("fs-%.*s", len, name) == 0)) {
 273                 fs = __get_fs_type(name, len);
 274                 if (!fs)
 275                         pr_warn_once("request_module fs-%.*s succeeded, but still no fs?\n",
 276                                      len, name);
 277         }
 278 
 279         if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
 280                 put_filesystem(fs);
 281                 fs = NULL;
 282         }
 283         return fs;
 284 }
 285 
 286 EXPORT_SYMBOL(get_fs_type);

/* [<][>][^][v][top][bottom][index][help] */