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