Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  *  9P entry point
0004  *
0005  *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
0006  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
0007  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
0008  */
0009 
0010 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0011 
0012 #include <linux/module.h>
0013 #include <linux/kmod.h>
0014 #include <linux/errno.h>
0015 #include <linux/sched.h>
0016 #include <linux/moduleparam.h>
0017 #include <net/9p/9p.h>
0018 #include <linux/fs.h>
0019 #include <linux/parser.h>
0020 #include <net/9p/client.h>
0021 #include <net/9p/transport.h>
0022 #include <linux/list.h>
0023 #include <linux/spinlock.h>
0024 
0025 #ifdef CONFIG_NET_9P_DEBUG
0026 unsigned int p9_debug_level;    /* feature-rific global debug level  */
0027 EXPORT_SYMBOL(p9_debug_level);
0028 module_param_named(debug, p9_debug_level, uint, 0);
0029 MODULE_PARM_DESC(debug, "9P debugging level");
0030 
0031 void _p9_debug(enum p9_debug_flags level, const char *func,
0032            const char *fmt, ...)
0033 {
0034     struct va_format vaf;
0035     va_list args;
0036 
0037     if ((p9_debug_level & level) != level)
0038         return;
0039 
0040     va_start(args, fmt);
0041 
0042     vaf.fmt = fmt;
0043     vaf.va = &args;
0044 
0045     if (level == P9_DEBUG_9P)
0046         pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
0047     else
0048         pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
0049 
0050     va_end(args);
0051 }
0052 EXPORT_SYMBOL(_p9_debug);
0053 #endif
0054 
0055 /* Dynamic Transport Registration Routines */
0056 
0057 static DEFINE_SPINLOCK(v9fs_trans_lock);
0058 static LIST_HEAD(v9fs_trans_list);
0059 
0060 /**
0061  * v9fs_register_trans - register a new transport with 9p
0062  * @m: structure describing the transport module and entry points
0063  *
0064  */
0065 void v9fs_register_trans(struct p9_trans_module *m)
0066 {
0067     spin_lock(&v9fs_trans_lock);
0068     list_add_tail(&m->list, &v9fs_trans_list);
0069     spin_unlock(&v9fs_trans_lock);
0070 }
0071 EXPORT_SYMBOL(v9fs_register_trans);
0072 
0073 /**
0074  * v9fs_unregister_trans - unregister a 9p transport
0075  * @m: the transport to remove
0076  *
0077  */
0078 void v9fs_unregister_trans(struct p9_trans_module *m)
0079 {
0080     spin_lock(&v9fs_trans_lock);
0081     list_del_init(&m->list);
0082     spin_unlock(&v9fs_trans_lock);
0083 }
0084 EXPORT_SYMBOL(v9fs_unregister_trans);
0085 
0086 static struct p9_trans_module *_p9_get_trans_by_name(const char *s)
0087 {
0088     struct p9_trans_module *t, *found = NULL;
0089 
0090     spin_lock(&v9fs_trans_lock);
0091 
0092     list_for_each_entry(t, &v9fs_trans_list, list)
0093         if (strcmp(t->name, s) == 0 &&
0094             try_module_get(t->owner)) {
0095             found = t;
0096             break;
0097         }
0098 
0099     spin_unlock(&v9fs_trans_lock);
0100 
0101     return found;
0102 }
0103 
0104 /**
0105  * v9fs_get_trans_by_name - get transport with the matching name
0106  * @s: string identifying transport
0107  *
0108  */
0109 struct p9_trans_module *v9fs_get_trans_by_name(const char *s)
0110 {
0111     struct p9_trans_module *found = NULL;
0112 
0113     found = _p9_get_trans_by_name(s);
0114 
0115 #ifdef CONFIG_MODULES
0116     if (!found) {
0117         request_module("9p-%s", s);
0118         found = _p9_get_trans_by_name(s);
0119     }
0120 #endif
0121 
0122     return found;
0123 }
0124 EXPORT_SYMBOL(v9fs_get_trans_by_name);
0125 
0126 static const char * const v9fs_default_transports[] = {
0127     "virtio", "tcp", "fd", "unix", "xen", "rdma",
0128 };
0129 
0130 /**
0131  * v9fs_get_default_trans - get the default transport
0132  *
0133  */
0134 
0135 struct p9_trans_module *v9fs_get_default_trans(void)
0136 {
0137     struct p9_trans_module *t, *found = NULL;
0138     int i;
0139 
0140     spin_lock(&v9fs_trans_lock);
0141 
0142     list_for_each_entry(t, &v9fs_trans_list, list)
0143         if (t->def && try_module_get(t->owner)) {
0144             found = t;
0145             break;
0146         }
0147 
0148     if (!found)
0149         list_for_each_entry(t, &v9fs_trans_list, list)
0150             if (try_module_get(t->owner)) {
0151                 found = t;
0152                 break;
0153             }
0154 
0155     spin_unlock(&v9fs_trans_lock);
0156 
0157     for (i = 0; !found && i < ARRAY_SIZE(v9fs_default_transports); i++)
0158         found = v9fs_get_trans_by_name(v9fs_default_transports[i]);
0159 
0160     return found;
0161 }
0162 EXPORT_SYMBOL(v9fs_get_default_trans);
0163 
0164 /**
0165  * v9fs_put_trans - put trans
0166  * @m: transport to put
0167  *
0168  */
0169 void v9fs_put_trans(struct p9_trans_module *m)
0170 {
0171     if (m)
0172         module_put(m->owner);
0173 }
0174 
0175 /**
0176  * init_p9 - Initialize module
0177  *
0178  */
0179 static int __init init_p9(void)
0180 {
0181     int ret;
0182 
0183     ret = p9_client_init();
0184     if (ret)
0185         return ret;
0186 
0187     p9_error_init();
0188     pr_info("Installing 9P2000 support\n");
0189 
0190     return ret;
0191 }
0192 
0193 /**
0194  * exit_p9 - shutdown module
0195  *
0196  */
0197 
0198 static void __exit exit_p9(void)
0199 {
0200     pr_info("Unloading 9P2000 support\n");
0201 
0202     p9_client_exit();
0203 }
0204 
0205 module_init(init_p9)
0206 module_exit(exit_p9)
0207 
0208 MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
0209 MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
0210 MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
0211 MODULE_LICENSE("GPL");
0212 MODULE_DESCRIPTION("Plan 9 Resource Sharing Support (9P2000)");