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