1bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov/*
2bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  net/9p/9p.c
3bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
4bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  9P entry point
5bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
6bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  Copyright (C) 2007 by Latchesar Ionkov <lucho@ionkov.net>
7bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
8bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
9bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
10bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  This program is free software; you can redistribute it and/or modify
11bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  it under the terms of the GNU General Public License version 2
12bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  as published by the Free Software Foundation.
13bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
14bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  This program is distributed in the hope that it will be useful,
15bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  GNU General Public License for more details.
18bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
19bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  You should have received a copy of the GNU General Public License
20bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  along with this program; if not, write to:
21bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  Free Software Foundation
22bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  51 Franklin Street, Fifth Floor
23bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *  Boston, MA  02111-1301  USA
24bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
25bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov */
26bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
275d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
285d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
29bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov#include <linux/module.h>
305d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches#include <linux/errno.h>
315d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches#include <linux/sched.h>
32bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov#include <linux/moduleparam.h>
33bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov#include <net/9p/9p.h>
34fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen#include <linux/fs.h>
35fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen#include <linux/parser.h>
368b81ef589ad1483dd977ef47fe00d4ce4d91a0abEric Van Hensbergen#include <net/9p/client.h>
37fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen#include <net/9p/transport.h>
38fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen#include <linux/list.h>
3972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo#include <linux/spinlock.h>
40bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
41bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov#ifdef CONFIG_NET_9P_DEBUG
42bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovunsigned int p9_debug_level = 0;	/* feature-rific global debug level  */
43bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovEXPORT_SYMBOL(p9_debug_level);
44bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovmodule_param_named(debug, p9_debug_level, uint, 0);
45bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovMODULE_PARM_DESC(debug, "9P debugging level");
465d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
475d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perchesvoid _p9_debug(enum p9_debug_flags level, const char *func,
485d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches		const char *fmt, ...)
495d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches{
505d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	struct va_format vaf;
515d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	va_list args;
525d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
535d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	if ((p9_debug_level & level) != level)
545d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches		return;
555d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
565d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	va_start(args, fmt);
575d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
585d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	vaf.fmt = fmt;
595d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	vaf.va = &args;
605d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
615d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	if (level == P9_DEBUG_9P)
625d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches		pr_notice("(%8.8d) %pV", task_pid_nr(current), &vaf);
635d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	else
645d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches		pr_notice("-- %s (%d): %pV", func, task_pid_nr(current), &vaf);
655d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches
665d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	va_end(args);
675d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches}
685d3851530d6d68564e4e0ce04d0547d4d106fc72Joe PerchesEXPORT_SYMBOL(_p9_debug);
69bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov#endif
70bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
71fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen/*
72fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen * Dynamic Transport Registration Routines
73fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen *
74fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen */
75fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
7672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heostatic DEFINE_SPINLOCK(v9fs_trans_lock);
77fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergenstatic LIST_HEAD(v9fs_trans_list);
78fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
79fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen/**
80fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen * v9fs_register_trans - register a new transport with 9p
81ee443996a35c1e04f210cafd43d5a98d41e46085Eric Van Hensbergen * @m: structure describing the transport module and entry points
82fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen *
83fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen */
84fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergenvoid v9fs_register_trans(struct p9_trans_module *m)
85fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen{
8672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_lock(&v9fs_trans_lock);
87fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen	list_add_tail(&m->list, &v9fs_trans_list);
8872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_unlock(&v9fs_trans_lock);
89fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen}
90fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van HensbergenEXPORT_SYMBOL(v9fs_register_trans);
91fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
92fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen/**
9372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * v9fs_unregister_trans - unregister a 9p transport
9472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * @m: the transport to remove
9572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo *
9672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo */
9772029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heovoid v9fs_unregister_trans(struct p9_trans_module *m)
9872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo{
9972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_lock(&v9fs_trans_lock);
10072029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	list_del_init(&m->list);
10172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_unlock(&v9fs_trans_lock);
10272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo}
10372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun HeoEXPORT_SYMBOL(v9fs_unregister_trans);
10472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
10572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo/**
10672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * v9fs_get_trans_by_name - get transport with the matching name
107ee443996a35c1e04f210cafd43d5a98d41e46085Eric Van Hensbergen * @name: string identifying transport
108fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen *
109fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen */
1104d63055fa9657aa402da25575045c23f37c3da05Prem Karatstruct p9_trans_module *v9fs_get_trans_by_name(char *s)
111fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen{
11272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	struct p9_trans_module *t, *found = NULL;
11372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
11472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_lock(&v9fs_trans_lock);
11572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
11672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	list_for_each_entry(t, &v9fs_trans_list, list)
1174d63055fa9657aa402da25575045c23f37c3da05Prem Karat		if (strcmp(t->name, s) == 0 &&
11872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		    try_module_get(t->owner)) {
11972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			found = t;
12072029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			break;
12172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		}
12272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
12372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_unlock(&v9fs_trans_lock);
12472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	return found;
125fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen}
12672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun HeoEXPORT_SYMBOL(v9fs_get_trans_by_name);
127fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
128fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen/**
12972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * v9fs_get_default_trans - get the default transport
130fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen *
131fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen */
132fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
13372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heostruct p9_trans_module *v9fs_get_default_trans(void)
134fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen{
13572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	struct p9_trans_module *t, *found = NULL;
13672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
13772029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_lock(&v9fs_trans_lock);
13872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
13972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	list_for_each_entry(t, &v9fs_trans_list, list)
14072029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		if (t->def && try_module_get(t->owner)) {
14172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			found = t;
14272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			break;
14372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		}
14472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
14572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	if (!found)
14672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		list_for_each_entry(t, &v9fs_trans_list, list)
14772029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			if (try_module_get(t->owner)) {
14872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo				found = t;
14972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo				break;
15072029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo			}
15172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
15272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	spin_unlock(&v9fs_trans_lock);
15372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	return found;
154fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen}
15572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun HeoEXPORT_SYMBOL(v9fs_get_default_trans);
156fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
15772029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo/**
15872029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * v9fs_put_trans - put trans
15972029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo * @m: transport to put
16072029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo *
16172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo */
16272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heovoid v9fs_put_trans(struct p9_trans_module *m)
16372029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo{
16472029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	if (m)
16572029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo		module_put(m->owner);
16672029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo}
167fb0466c3ae7f1c73f70072af8fd27ac166908a2fEric Van Hensbergen
168bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov/**
169961a5a5028b8ae6fe91f28d5a81696de90b74bc2Rob Landley * init_p9 - Initialize module
170bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
171bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov */
172bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovstatic int __init init_p9(void)
173bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov{
1748a0dc95fd976a052e5e799ef33e6c8e3141b5dffEric Van Hensbergen	int ret = 0;
175bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
176bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov	p9_error_init();
1775d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	pr_info("Installing 9P2000 support\n");
178887b3ece65be7b643dfdae0d433c91a26a3f437dEric Van Hensbergen	p9_trans_fd_init();
179bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
180bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov	return ret;
181bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov}
182bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
183bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov/**
184961a5a5028b8ae6fe91f28d5a81696de90b74bc2Rob Landley * exit_p9 - shutdown module
185bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov *
186bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov */
187bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
188bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovstatic void __exit exit_p9(void)
189bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov{
1905d3851530d6d68564e4e0ce04d0547d4d106fc72Joe Perches	pr_info("Unloading 9P2000 support\n");
19172029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo
19272029fe85d8d060b3f966f2dbc36b3c75b5a6532Tejun Heo	p9_trans_fd_exit();
193bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov}
194bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
195bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovmodule_init(init_p9)
196bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkovmodule_exit(exit_p9)
197bd238fb431f31989898423c8b6496bc8c4204a86Latchesar Ionkov
198bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovMODULE_AUTHOR("Latchesar Ionkov <lucho@ionkov.net>");
199bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovMODULE_AUTHOR("Eric Van Hensbergen <ericvh@gmail.com>");
200bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovMODULE_AUTHOR("Ron Minnich <rminnich@lanl.gov>");
201bd238fb431f31989898423c8b6496bc8c4204a86Latchesar IonkovMODULE_LICENSE("GPL");
202