Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*
0003  *  linux/fs/filesystems.c
0004  *
0005  *  Copyright (C) 1991, 1992  Linus Torvalds
0006  *
0007  *  table of configured filesystems
0008  */
0009 
0010 #include <linux/syscalls.h>
0011 #include <linux/fs.h>
0012 #include <linux/proc_fs.h>
0013 #include <linux/seq_file.h>
0014 #include <linux/kmod.h>
0015 #include <linux/init.h>
0016 #include <linux/module.h>
0017 #include <linux/slab.h>
0018 #include <linux/uaccess.h>
0019 #include <linux/fs_parser.h>
0020 
0021 /*
0022  * Handling of filesystem drivers list.
0023  * Rules:
0024  *  Inclusion to/removals from/scanning of list are protected by spinlock.
0025  *  During the unload module must call unregister_filesystem().
0026  *  We can access the fields of list element if:
0027  *      1) spinlock is held or
0028  *      2) we hold the reference to the module.
0029  *  The latter can be guaranteed by call of try_module_get(); if it
0030  *  returned 0 we must skip the element, otherwise we got the reference.
0031  *  Once the reference is obtained we can drop the spinlock.
0032  */
0033 
0034 static struct file_system_type *file_systems;
0035 static DEFINE_RWLOCK(file_systems_lock);
0036 
0037 /* WARNING: This can be used only if we _already_ own a reference */
0038 struct file_system_type *get_filesystem(struct file_system_type *fs)
0039 {
0040     __module_get(fs->owner);
0041     return fs;
0042 }
0043 
0044 void put_filesystem(struct file_system_type *fs)
0045 {
0046     module_put(fs->owner);
0047 }
0048 
0049 static struct file_system_type **find_filesystem(const char *name, unsigned len)
0050 {
0051     struct file_system_type **p;
0052     for (p = &file_systems; *p; p = &(*p)->next)
0053         if (strncmp((*p)->name, name, len) == 0 &&
0054             !(*p)->name[len])
0055             break;
0056     return p;
0057 }
0058 
0059 /**
0060  *  register_filesystem - register a new filesystem
0061  *  @fs: the file system structure
0062  *
0063  *  Adds the file system passed to the list of file systems the kernel
0064  *  is aware of for mount and other syscalls. Returns 0 on success,
0065  *  or a negative errno code on an error.
0066  *
0067  *  The &struct file_system_type that is passed is linked into the kernel 
0068  *  structures and must not be freed until the file system has been
0069  *  unregistered.
0070  */
0071  
0072 int register_filesystem(struct file_system_type * fs)
0073 {
0074     int res = 0;
0075     struct file_system_type ** p;
0076 
0077     if (fs->parameters &&
0078         !fs_validate_description(fs->name, fs->parameters))
0079         return -EINVAL;
0080 
0081     BUG_ON(strchr(fs->name, '.'));
0082     if (fs->next)
0083         return -EBUSY;
0084     write_lock(&file_systems_lock);
0085     p = find_filesystem(fs->name, strlen(fs->name));
0086     if (*p)
0087         res = -EBUSY;
0088     else
0089         *p = fs;
0090     write_unlock(&file_systems_lock);
0091     return res;
0092 }
0093 
0094 EXPORT_SYMBOL(register_filesystem);
0095 
0096 /**
0097  *  unregister_filesystem - unregister a file system
0098  *  @fs: filesystem to unregister
0099  *
0100  *  Remove a file system that was previously successfully registered
0101  *  with the kernel. An error is returned if the file system is not found.
0102  *  Zero is returned on a success.
0103  *  
0104  *  Once this function has returned the &struct file_system_type structure
0105  *  may be freed or reused.
0106  */
0107  
0108 int unregister_filesystem(struct file_system_type * fs)
0109 {
0110     struct file_system_type ** tmp;
0111 
0112     write_lock(&file_systems_lock);
0113     tmp = &file_systems;
0114     while (*tmp) {
0115         if (fs == *tmp) {
0116             *tmp = fs->next;
0117             fs->next = NULL;
0118             write_unlock(&file_systems_lock);
0119             synchronize_rcu();
0120             return 0;
0121         }
0122         tmp = &(*tmp)->next;
0123     }
0124     write_unlock(&file_systems_lock);
0125 
0126     return -EINVAL;
0127 }
0128 
0129 EXPORT_SYMBOL(unregister_filesystem);
0130 
0131 #ifdef CONFIG_SYSFS_SYSCALL
0132 static int fs_index(const char __user * __name)
0133 {
0134     struct file_system_type * tmp;
0135     struct filename *name;
0136     int err, index;
0137 
0138     name = getname(__name);
0139     err = PTR_ERR(name);
0140     if (IS_ERR(name))
0141         return err;
0142 
0143     err = -EINVAL;
0144     read_lock(&file_systems_lock);
0145     for (tmp=file_systems, index=0 ; tmp ; tmp=tmp->next, index++) {
0146         if (strcmp(tmp->name, name->name) == 0) {
0147             err = index;
0148             break;
0149         }
0150     }
0151     read_unlock(&file_systems_lock);
0152     putname(name);
0153     return err;
0154 }
0155 
0156 static int fs_name(unsigned int index, char __user * buf)
0157 {
0158     struct file_system_type * tmp;
0159     int len, res;
0160 
0161     read_lock(&file_systems_lock);
0162     for (tmp = file_systems; tmp; tmp = tmp->next, index--)
0163         if (index <= 0 && try_module_get(tmp->owner))
0164             break;
0165     read_unlock(&file_systems_lock);
0166     if (!tmp)
0167         return -EINVAL;
0168 
0169     /* OK, we got the reference, so we can safely block */
0170     len = strlen(tmp->name) + 1;
0171     res = copy_to_user(buf, tmp->name, len) ? -EFAULT : 0;
0172     put_filesystem(tmp);
0173     return res;
0174 }
0175 
0176 static int fs_maxindex(void)
0177 {
0178     struct file_system_type * tmp;
0179     int index;
0180 
0181     read_lock(&file_systems_lock);
0182     for (tmp = file_systems, index = 0 ; tmp ; tmp = tmp->next, index++)
0183         ;
0184     read_unlock(&file_systems_lock);
0185     return index;
0186 }
0187 
0188 /*
0189  * Whee.. Weird sysv syscall. 
0190  */
0191 SYSCALL_DEFINE3(sysfs, int, option, unsigned long, arg1, unsigned long, arg2)
0192 {
0193     int retval = -EINVAL;
0194 
0195     switch (option) {
0196         case 1:
0197             retval = fs_index((const char __user *) arg1);
0198             break;
0199 
0200         case 2:
0201             retval = fs_name(arg1, (char __user *) arg2);
0202             break;
0203 
0204         case 3:
0205             retval = fs_maxindex();
0206             break;
0207     }
0208     return retval;
0209 }
0210 #endif
0211 
0212 int __init list_bdev_fs_names(char *buf, size_t size)
0213 {
0214     struct file_system_type *p;
0215     size_t len;
0216     int count = 0;
0217 
0218     read_lock(&file_systems_lock);
0219     for (p = file_systems; p; p = p->next) {
0220         if (!(p->fs_flags & FS_REQUIRES_DEV))
0221             continue;
0222         len = strlen(p->name) + 1;
0223         if (len > size) {
0224             pr_warn("%s: truncating file system list\n", __func__);
0225             break;
0226         }
0227         memcpy(buf, p->name, len);
0228         buf += len;
0229         size -= len;
0230         count++;
0231     }
0232     read_unlock(&file_systems_lock);
0233     return count;
0234 }
0235 
0236 #ifdef CONFIG_PROC_FS
0237 static int filesystems_proc_show(struct seq_file *m, void *v)
0238 {
0239     struct file_system_type * tmp;
0240 
0241     read_lock(&file_systems_lock);
0242     tmp = file_systems;
0243     while (tmp) {
0244         seq_printf(m, "%s\t%s\n",
0245             (tmp->fs_flags & FS_REQUIRES_DEV) ? "" : "nodev",
0246             tmp->name);
0247         tmp = tmp->next;
0248     }
0249     read_unlock(&file_systems_lock);
0250     return 0;
0251 }
0252 
0253 static int __init proc_filesystems_init(void)
0254 {
0255     proc_create_single("filesystems", 0, NULL, filesystems_proc_show);
0256     return 0;
0257 }
0258 module_init(proc_filesystems_init);
0259 #endif
0260 
0261 static struct file_system_type *__get_fs_type(const char *name, int len)
0262 {
0263     struct file_system_type *fs;
0264 
0265     read_lock(&file_systems_lock);
0266     fs = *(find_filesystem(name, len));
0267     if (fs && !try_module_get(fs->owner))
0268         fs = NULL;
0269     read_unlock(&file_systems_lock);
0270     return fs;
0271 }
0272 
0273 struct file_system_type *get_fs_type(const char *name)
0274 {
0275     struct file_system_type *fs;
0276     const char *dot = strchr(name, '.');
0277     int len = dot ? dot - name : strlen(name);
0278 
0279     fs = __get_fs_type(name, len);
0280     if (!fs && (request_module("fs-%.*s", len, name) == 0)) {
0281         fs = __get_fs_type(name, len);
0282         if (!fs)
0283             pr_warn_once("request_module fs-%.*s succeeded, but still no fs?\n",
0284                      len, name);
0285     }
0286 
0287     if (dot && fs && !(fs->fs_flags & FS_HAS_SUBTYPE)) {
0288         put_filesystem(fs);
0289         fs = NULL;
0290     }
0291     return fs;
0292 }
0293 
0294 EXPORT_SYMBOL(get_fs_type);