mod.c (4362B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * 9P entry point 4 * 5 * Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net> 6 * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> 7 * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> 8 */ 9 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12#include <linux/module.h> 13#include <linux/kmod.h> 14#include <linux/errno.h> 15#include <linux/sched.h> 16#include <linux/moduleparam.h> 17#include <net/9p/9p.h> 18#include <linux/fs.h> 19#include <linux/parser.h> 20#include <net/9p/client.h> 21#include <net/9p/transport.h> 22#include <linux/list.h> 23#include <linux/spinlock.h> 24 25#ifdef CONFIG_NET_9P_DEBUG 26unsigned int p9_debug_level; /* feature-rific global debug level */ 27EXPORT_SYMBOL(p9_debug_level); 28module_param_named(debug, p9_debug_level, uint, 0); 29MODULE_PARM_DESC(debug, "9P debugging level"); 30 31void _p9_debug(enum p9_debug_flags level, const char *func, 32 const char *fmt, ...) 33{ 34 struct va_format vaf; 35 va_list args; 36 37 if ((p9_debug_level & level) != level) 38 return; 39 40 va_start(args, fmt); 41 42 vaf.fmt = fmt; 43 vaf.va = &args; 44 45 if (level == P9_DEBUG_9P) 46 pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf); 47 else 48 pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf); 49 50 va_end(args); 51} 52EXPORT_SYMBOL(_p9_debug); 53#endif 54 55/* Dynamic Transport Registration Routines */ 56 57static DEFINE_SPINLOCK(v9fs_trans_lock); 58static LIST_HEAD(v9fs_trans_list); 59 60/** 61 * v9fs_register_trans - register a new transport with 9p 62 * @m: structure describing the transport module and entry points 63 * 64 */ 65void v9fs_register_trans(struct p9_trans_module *m) 66{ 67 spin_lock(&v9fs_trans_lock); 68 list_add_tail(&m->list, &v9fs_trans_list); 69 spin_unlock(&v9fs_trans_lock); 70} 71EXPORT_SYMBOL(v9fs_register_trans); 72 73/** 74 * v9fs_unregister_trans - unregister a 9p transport 75 * @m: the transport to remove 76 * 77 */ 78void v9fs_unregister_trans(struct p9_trans_module *m) 79{ 80 spin_lock(&v9fs_trans_lock); 81 list_del_init(&m->list); 82 spin_unlock(&v9fs_trans_lock); 83} 84EXPORT_SYMBOL(v9fs_unregister_trans); 85 86static struct p9_trans_module *_p9_get_trans_by_name(const char *s) 87{ 88 struct p9_trans_module *t, *found = NULL; 89 90 spin_lock(&v9fs_trans_lock); 91 92 list_for_each_entry(t, &v9fs_trans_list, list) 93 if (strcmp(t->name, s) == 0 && 94 try_module_get(t->owner)) { 95 found = t; 96 break; 97 } 98 99 spin_unlock(&v9fs_trans_lock); 100 101 return found; 102} 103 104/** 105 * v9fs_get_trans_by_name - get transport with the matching name 106 * @s: string identifying transport 107 * 108 */ 109struct p9_trans_module *v9fs_get_trans_by_name(const char *s) 110{ 111 struct p9_trans_module *found = NULL; 112 113 found = _p9_get_trans_by_name(s); 114 115#ifdef CONFIG_MODULES 116 if (!found) { 117 request_module("9p-%s", s); 118 found = _p9_get_trans_by_name(s); 119 } 120#endif 121 122 return found; 123} 124EXPORT_SYMBOL(v9fs_get_trans_by_name); 125 126static const char * const v9fs_default_transports[] = { 127 "virtio", "tcp", "fd", "unix", "xen", "rdma", 128}; 129 130/** 131 * v9fs_get_default_trans - get the default transport 132 * 133 */ 134 135struct p9_trans_module *v9fs_get_default_trans(void) 136{ 137 struct p9_trans_module *t, *found = NULL; 138 int i; 139 140 spin_lock(&v9fs_trans_lock); 141 142 list_for_each_entry(t, &v9fs_trans_list, list) 143 if (t->def && try_module_get(t->owner)) { 144 found = t; 145 break; 146 } 147 148 if (!found) 149 list_for_each_entry(t, &v9fs_trans_list, list) 150 if (try_module_get(t->owner)) { 151 found = t; 152 break; 153 } 154 155 spin_unlock(&v9fs_trans_lock); 156 157 for (i = 0; !found && i < ARRAY_SIZE(v9fs_default_transports); i++) 158 found = v9fs_get_trans_by_name(v9fs_default_transports[i]); 159 160 return found; 161} 162EXPORT_SYMBOL(v9fs_get_default_trans); 163 164/** 165 * v9fs_put_trans - put trans 166 * @m: transport to put 167 * 168 */ 169void v9fs_put_trans(struct p9_trans_module *m) 170{ 171 if (m) 172 module_put(m->owner); 173} 174 175/** 176 * init_p9 - Initialize module 177 * 178 */ 179static int __init init_p9(void) 180{ 181 int ret; 182 183 ret = p9_client_init(); 184 if (ret) 185 return ret; 186 187 p9_error_init(); 188 pr_info("Installing 9P2000 support\n"); 189 190 return ret; 191} 192 193/** 194 * exit_p9 - shutdown module 195 * 196 */ 197 198static void __exit exit_p9(void) 199{ 200 pr_info("Unloading 9P2000 support\n"); 201 202 p9_client_exit(); 203} 204 205module_init(init_p9) 206module_exit(exit_p9) 207 208MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>"); 209MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>"); 210MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>"); 211MODULE_LICENSE("GPL"); 212MODULE_DESCRIPTION("Plan 9 Resource Sharing Support (9P2000)");