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