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