xref: /openbmc/linux/net/9p/mod.c (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
11f327613SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2bd238fb4SLatchesar Ionkov /*
3bd238fb4SLatchesar Ionkov  *  9P entry point
4bd238fb4SLatchesar Ionkov  *
5bd238fb4SLatchesar Ionkov  *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
6bd238fb4SLatchesar Ionkov  *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
7bd238fb4SLatchesar Ionkov  *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
8bd238fb4SLatchesar Ionkov  */
9bd238fb4SLatchesar Ionkov 
105d385153SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
115d385153SJoe Perches 
12bd238fb4SLatchesar Ionkov #include <linux/module.h>
134cd82a5bSThomas Weißschuh #include <linux/kmod.h>
145d385153SJoe Perches #include <linux/errno.h>
155d385153SJoe Perches #include <linux/sched.h>
16bd238fb4SLatchesar Ionkov #include <linux/moduleparam.h>
17bd238fb4SLatchesar Ionkov #include <net/9p/9p.h>
18fb0466c3SEric Van Hensbergen #include <linux/fs.h>
19fb0466c3SEric Van Hensbergen #include <linux/parser.h>
208b81ef58SEric Van Hensbergen #include <net/9p/client.h>
21fb0466c3SEric Van Hensbergen #include <net/9p/transport.h>
22fb0466c3SEric Van Hensbergen #include <linux/list.h>
2372029fe8STejun Heo #include <linux/spinlock.h>
24bd238fb4SLatchesar Ionkov 
25bd238fb4SLatchesar Ionkov #ifdef CONFIG_NET_9P_DEBUG
266e195b0fSDominique Martinet unsigned int p9_debug_level;	/* feature-rific global debug level  */
27bd238fb4SLatchesar Ionkov EXPORT_SYMBOL(p9_debug_level);
28bd238fb4SLatchesar Ionkov module_param_named(debug, p9_debug_level, uint, 0);
29bd238fb4SLatchesar Ionkov MODULE_PARM_DESC(debug, "9P debugging level");
305d385153SJoe Perches 
_p9_debug(enum p9_debug_flags level,const char * func,const char * fmt,...)315d385153SJoe Perches void _p9_debug(enum p9_debug_flags level, const char *func,
325d385153SJoe Perches 	       const char *fmt, ...)
335d385153SJoe Perches {
345d385153SJoe Perches 	struct va_format vaf;
355d385153SJoe Perches 	va_list args;
365d385153SJoe Perches 
375d385153SJoe Perches 	if ((p9_debug_level & level) != level)
385d385153SJoe Perches 		return;
395d385153SJoe Perches 
405d385153SJoe Perches 	va_start(args, fmt);
415d385153SJoe Perches 
425d385153SJoe Perches 	vaf.fmt = fmt;
435d385153SJoe Perches 	vaf.va = &args;
445d385153SJoe Perches 
455d385153SJoe Perches 	if (level == P9_DEBUG_9P)
465d385153SJoe Perches 		pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
475d385153SJoe Perches 	else
485d385153SJoe Perches 		pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
495d385153SJoe Perches 
505d385153SJoe Perches 	va_end(args);
515d385153SJoe Perches }
525d385153SJoe Perches EXPORT_SYMBOL(_p9_debug);
53bd238fb4SLatchesar Ionkov #endif
54bd238fb4SLatchesar Ionkov 
556e195b0fSDominique Martinet /* Dynamic Transport Registration Routines */
56fb0466c3SEric Van Hensbergen 
5772029fe8STejun Heo static DEFINE_SPINLOCK(v9fs_trans_lock);
58fb0466c3SEric Van Hensbergen static LIST_HEAD(v9fs_trans_list);
59fb0466c3SEric Van Hensbergen 
60fb0466c3SEric Van Hensbergen /**
61fb0466c3SEric Van Hensbergen  * v9fs_register_trans - register a new transport with 9p
62ee443996SEric Van Hensbergen  * @m: structure describing the transport module and entry points
63fb0466c3SEric Van Hensbergen  *
64fb0466c3SEric Van Hensbergen  */
v9fs_register_trans(struct p9_trans_module * m)65fb0466c3SEric Van Hensbergen void v9fs_register_trans(struct p9_trans_module *m)
66fb0466c3SEric Van Hensbergen {
6772029fe8STejun Heo 	spin_lock(&v9fs_trans_lock);
68fb0466c3SEric Van Hensbergen 	list_add_tail(&m->list, &v9fs_trans_list);
6972029fe8STejun Heo 	spin_unlock(&v9fs_trans_lock);
70fb0466c3SEric Van Hensbergen }
71fb0466c3SEric Van Hensbergen EXPORT_SYMBOL(v9fs_register_trans);
72fb0466c3SEric Van Hensbergen 
73fb0466c3SEric Van Hensbergen /**
7472029fe8STejun Heo  * v9fs_unregister_trans - unregister a 9p transport
7572029fe8STejun Heo  * @m: the transport to remove
7672029fe8STejun Heo  *
7772029fe8STejun Heo  */
v9fs_unregister_trans(struct p9_trans_module * m)7872029fe8STejun Heo void v9fs_unregister_trans(struct p9_trans_module *m)
7972029fe8STejun Heo {
8072029fe8STejun Heo 	spin_lock(&v9fs_trans_lock);
8172029fe8STejun Heo 	list_del_init(&m->list);
8272029fe8STejun Heo 	spin_unlock(&v9fs_trans_lock);
8372029fe8STejun Heo }
8472029fe8STejun Heo EXPORT_SYMBOL(v9fs_unregister_trans);
8572029fe8STejun Heo 
_p9_get_trans_by_name(const char * s)86*019641d1SThomas Weißschuh static struct p9_trans_module *_p9_get_trans_by_name(const char *s)
87fb0466c3SEric Van Hensbergen {
8872029fe8STejun Heo 	struct p9_trans_module *t, *found = NULL;
89fb0466c3SEric Van Hensbergen 
9072029fe8STejun Heo 	spin_lock(&v9fs_trans_lock);
9172029fe8STejun Heo 
9272029fe8STejun Heo 	list_for_each_entry(t, &v9fs_trans_list, list)
934d63055fSPrem Karat 		if (strcmp(t->name, s) == 0 &&
9472029fe8STejun Heo 		    try_module_get(t->owner)) {
9572029fe8STejun Heo 			found = t;
9672029fe8STejun Heo 			break;
97fb0466c3SEric Van Hensbergen 		}
9872029fe8STejun Heo 
9972029fe8STejun Heo 	spin_unlock(&v9fs_trans_lock);
1004cd82a5bSThomas Weißschuh 
1014cd82a5bSThomas Weißschuh 	return found;
1024cd82a5bSThomas Weißschuh }
1034cd82a5bSThomas Weißschuh 
1044cd82a5bSThomas Weißschuh /**
1054cd82a5bSThomas Weißschuh  * v9fs_get_trans_by_name - get transport with the matching name
1064cd82a5bSThomas Weißschuh  * @s: string identifying transport
1074cd82a5bSThomas Weißschuh  *
1084cd82a5bSThomas Weißschuh  */
v9fs_get_trans_by_name(const char * s)109*019641d1SThomas Weißschuh struct p9_trans_module *v9fs_get_trans_by_name(const char *s)
1104cd82a5bSThomas Weißschuh {
1114cd82a5bSThomas Weißschuh 	struct p9_trans_module *found = NULL;
1124cd82a5bSThomas Weißschuh 
1134cd82a5bSThomas Weißschuh 	found = _p9_get_trans_by_name(s);
1144cd82a5bSThomas Weißschuh 
1154cd82a5bSThomas Weißschuh #ifdef CONFIG_MODULES
1164cd82a5bSThomas Weißschuh 	if (!found) {
1174cd82a5bSThomas Weißschuh 		request_module("9p-%s", s);
1184cd82a5bSThomas Weißschuh 		found = _p9_get_trans_by_name(s);
1194cd82a5bSThomas Weißschuh 	}
1204cd82a5bSThomas Weißschuh #endif
1214cd82a5bSThomas Weißschuh 
12272029fe8STejun Heo 	return found;
123dd1a4584SLatchesar Ionkov }
12472029fe8STejun Heo EXPORT_SYMBOL(v9fs_get_trans_by_name);
125fb0466c3SEric Van Hensbergen 
126*019641d1SThomas Weißschuh static const char * const v9fs_default_transports[] = {
127*019641d1SThomas Weißschuh 	"virtio", "tcp", "fd", "unix", "xen", "rdma",
128*019641d1SThomas Weißschuh };
129*019641d1SThomas Weißschuh 
130fb0466c3SEric Van Hensbergen /**
13172029fe8STejun Heo  * v9fs_get_default_trans - get the default transport
132fb0466c3SEric Van Hensbergen  *
133fb0466c3SEric Van Hensbergen  */
134fb0466c3SEric Van Hensbergen 
v9fs_get_default_trans(void)13572029fe8STejun Heo struct p9_trans_module *v9fs_get_default_trans(void)
136fb0466c3SEric Van Hensbergen {
13772029fe8STejun Heo 	struct p9_trans_module *t, *found = NULL;
138*019641d1SThomas Weißschuh 	int i;
139fb0466c3SEric Van Hensbergen 
14072029fe8STejun Heo 	spin_lock(&v9fs_trans_lock);
14172029fe8STejun Heo 
14272029fe8STejun Heo 	list_for_each_entry(t, &v9fs_trans_list, list)
14372029fe8STejun Heo 		if (t->def && try_module_get(t->owner)) {
14472029fe8STejun Heo 			found = t;
14572029fe8STejun Heo 			break;
14672029fe8STejun Heo 		}
14772029fe8STejun Heo 
14872029fe8STejun Heo 	if (!found)
14972029fe8STejun Heo 		list_for_each_entry(t, &v9fs_trans_list, list)
15072029fe8STejun Heo 			if (try_module_get(t->owner)) {
15172029fe8STejun Heo 				found = t;
15272029fe8STejun Heo 				break;
15372029fe8STejun Heo 			}
15472029fe8STejun Heo 
15572029fe8STejun Heo 	spin_unlock(&v9fs_trans_lock);
156*019641d1SThomas Weißschuh 
157*019641d1SThomas Weißschuh 	for (i = 0; !found && i < ARRAY_SIZE(v9fs_default_transports); i++)
158*019641d1SThomas Weißschuh 		found = v9fs_get_trans_by_name(v9fs_default_transports[i]);
159*019641d1SThomas Weißschuh 
16072029fe8STejun Heo 	return found;
16172029fe8STejun Heo }
16272029fe8STejun Heo EXPORT_SYMBOL(v9fs_get_default_trans);
16372029fe8STejun Heo 
16472029fe8STejun Heo /**
16572029fe8STejun Heo  * v9fs_put_trans - put trans
16672029fe8STejun Heo  * @m: transport to put
16772029fe8STejun Heo  *
16872029fe8STejun Heo  */
v9fs_put_trans(struct p9_trans_module * m)16972029fe8STejun Heo void v9fs_put_trans(struct p9_trans_module *m)
17072029fe8STejun Heo {
17172029fe8STejun Heo 	if (m)
17272029fe8STejun Heo 		module_put(m->owner);
17372029fe8STejun Heo }
174fb0466c3SEric Van Hensbergen 
175bd238fb4SLatchesar Ionkov /**
176961a5a50SRob Landley  * init_p9 - Initialize module
177bd238fb4SLatchesar Ionkov  *
178bd238fb4SLatchesar Ionkov  */
init_p9(void)179bd238fb4SLatchesar Ionkov static int __init init_p9(void)
180bd238fb4SLatchesar Ionkov {
181996d5b4dSMatthew Wilcox 	int ret;
182996d5b4dSMatthew Wilcox 
183996d5b4dSMatthew Wilcox 	ret = p9_client_init();
184996d5b4dSMatthew Wilcox 	if (ret)
185996d5b4dSMatthew Wilcox 		return ret;
186996d5b4dSMatthew Wilcox 
187bd238fb4SLatchesar Ionkov 	p9_error_init();
1885d385153SJoe Perches 	pr_info("Installing 9P2000 support\n");
189bd238fb4SLatchesar Ionkov 
190996d5b4dSMatthew Wilcox 	return ret;
191bd238fb4SLatchesar Ionkov }
192bd238fb4SLatchesar Ionkov 
193bd238fb4SLatchesar Ionkov /**
194961a5a50SRob Landley  * exit_p9 - shutdown module
195bd238fb4SLatchesar Ionkov  *
196bd238fb4SLatchesar Ionkov  */
197bd238fb4SLatchesar Ionkov 
exit_p9(void)198bd238fb4SLatchesar Ionkov static void __exit exit_p9(void)
199bd238fb4SLatchesar Ionkov {
2005d385153SJoe Perches 	pr_info("Unloading 9P2000 support\n");
20172029fe8STejun Heo 
202996d5b4dSMatthew Wilcox 	p9_client_exit();
203bd238fb4SLatchesar Ionkov }
204bd238fb4SLatchesar Ionkov 
205bd238fb4SLatchesar Ionkov module_init(init_p9)
206bd238fb4SLatchesar Ionkov module_exit(exit_p9)
207bd238fb4SLatchesar Ionkov 
208bd238fb4SLatchesar Ionkov MODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
209bd238fb4SLatchesar Ionkov MODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
210bd238fb4SLatchesar Ionkov MODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
211bd238fb4SLatchesar Ionkov MODULE_LICENSE("GPL");
21267c20de3SRob Gill MODULE_DESCRIPTION("Plan 9 Resource Sharing Support (9P2000)");
213