tangled
alpha
login
or
join now
tjh.dev
/
kernel
1
fork
atom
Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1
fork
atom
overview
issues
pulls
pipelines
Merge branch 'containers'
Trond Myklebust
6 years ago
28ade856
02a2779f
+242
-9
7 changed files
expand all
collapse all
unified
split
fs
nfs
Makefile
client.c
inode.c
internal.h
netns.h
sysfs.c
sysfs.h
+2
-1
fs/nfs/Makefile
reviewed
···
8
8
CFLAGS_nfstrace.o += -I$(src)
9
9
nfs-y := client.o dir.o file.o getroot.o inode.o super.o \
10
10
io.o direct.o pagelist.o read.o symlink.o unlink.o \
11
11
-
write.o namespace.o mount_clnt.o nfstrace.o export.o
11
11
+
write.o namespace.o mount_clnt.o nfstrace.o \
12
12
+
export.o sysfs.o
12
13
nfs-$(CONFIG_ROOT_NFS) += nfsroot.o
13
14
nfs-$(CONFIG_SYSCTL) += sysctl.o
14
15
nfs-$(CONFIG_NFS_FSCACHE) += fscache.o fscache-index.o
+15
-2
fs/nfs/client.c
reviewed
···
49
49
#include "pnfs.h"
50
50
#include "nfs.h"
51
51
#include "netns.h"
52
52
+
#include "sysfs.h"
52
53
53
54
#define NFSDBG_FACILITY NFSDBG_CLIENT
54
55
···
193
192
EXPORT_SYMBOL_GPL(nfs_alloc_client);
194
193
195
194
#if IS_ENABLED(CONFIG_NFS_V4)
196
196
-
void nfs_cleanup_cb_ident_idr(struct net *net)
195
195
+
static void nfs_cleanup_cb_ident_idr(struct net *net)
197
196
{
198
197
struct nfs_net *nn = net_generic(net, nfs_net_id);
199
198
···
215
214
}
216
215
217
216
#else
218
218
-
void nfs_cleanup_cb_ident_idr(struct net *net)
217
217
+
static void nfs_cleanup_cb_ident_idr(struct net *net)
219
218
{
220
219
}
221
220
···
1073
1072
#endif
1074
1073
spin_lock_init(&nn->nfs_client_lock);
1075
1074
nn->boot_time = ktime_get_real();
1075
1075
+
1076
1076
+
nfs_netns_sysfs_setup(nn, net);
1077
1077
+
}
1078
1078
+
1079
1079
+
void nfs_clients_exit(struct net *net)
1080
1080
+
{
1081
1081
+
struct nfs_net *nn = net_generic(net, nfs_net_id);
1082
1082
+
1083
1083
+
nfs_netns_sysfs_destroy(nn);
1084
1084
+
nfs_cleanup_cb_ident_idr(net);
1085
1085
+
WARN_ON_ONCE(!list_empty(&nn->nfs_client_list));
1086
1086
+
WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list));
1076
1087
}
1077
1088
1078
1089
#ifdef CONFIG_PROC_FS
+9
-5
fs/nfs/inode.c
reviewed
···
51
51
#include "pnfs.h"
52
52
#include "nfs.h"
53
53
#include "netns.h"
54
54
+
#include "sysfs.h"
54
55
55
56
#include "nfstrace.h"
56
57
···
2168
2167
2169
2168
static void nfs_net_exit(struct net *net)
2170
2169
{
2171
2171
-
struct nfs_net *nn = net_generic(net, nfs_net_id);
2172
2172
-
2173
2170
nfs_fs_proc_net_exit(net);
2174
2174
-
nfs_cleanup_cb_ident_idr(net);
2175
2175
-
WARN_ON_ONCE(!list_empty(&nn->nfs_client_list));
2176
2176
-
WARN_ON_ONCE(!list_empty(&nn->nfs_volume_list));
2171
2171
+
nfs_clients_exit(net);
2177
2172
}
2178
2173
2179
2174
static struct pernet_operations nfs_net_ops = {
···
2185
2188
static int __init init_nfs_fs(void)
2186
2189
{
2187
2190
int err;
2191
2191
+
2192
2192
+
err = nfs_sysfs_init();
2193
2193
+
if (err < 0)
2194
2194
+
goto out10;
2188
2195
2189
2196
err = register_pernet_subsys(&nfs_net_ops);
2190
2197
if (err < 0)
···
2253
2252
out8:
2254
2253
unregister_pernet_subsys(&nfs_net_ops);
2255
2254
out9:
2255
2255
+
nfs_sysfs_exit();
2256
2256
+
out10:
2256
2257
return err;
2257
2258
}
2258
2259
···
2271
2268
unregister_nfs_fs();
2272
2269
nfs_fs_proc_exit();
2273
2270
nfsiod_stop();
2271
2271
+
nfs_sysfs_exit();
2274
2272
}
2275
2273
2276
2274
/* Not quite true; I just maintain it */
+1
-1
fs/nfs/internal.h
reviewed
···
158
158
/* client.c */
159
159
extern const struct rpc_program nfs_program;
160
160
extern void nfs_clients_init(struct net *net);
161
161
+
extern void nfs_clients_exit(struct net *net);
161
162
extern struct nfs_client *nfs_alloc_client(const struct nfs_client_initdata *);
162
163
int nfs_create_rpc_client(struct nfs_client *, const struct nfs_client_initdata *, rpc_authflavor_t);
163
164
struct nfs_client *nfs_get_client(const struct nfs_client_initdata *);
···
171
170
struct nfs_server *nfs_alloc_server(void);
172
171
void nfs_server_copy_userdata(struct nfs_server *, struct nfs_server *);
173
172
174
174
-
extern void nfs_cleanup_cb_ident_idr(struct net *);
175
173
extern void nfs_put_client(struct nfs_client *);
176
174
extern void nfs_free_client(struct nfs_client *);
177
175
extern struct nfs_client *nfs4_find_client_ident(struct net *, int);
+3
fs/nfs/netns.h
reviewed
···
15
15
uint32_t major, minor;
16
16
};
17
17
18
18
+
struct nfs_netns_client;
19
19
+
18
20
struct nfs_net {
19
21
struct cache_detail *nfs_dns_resolve;
20
22
struct rpc_pipe *bl_device_pipe;
···
31
29
unsigned short nfs_callback_tcpport6;
32
30
int cb_users[NFS4_MAX_MINOR_VERSION + 1];
33
31
#endif
32
32
+
struct nfs_netns_client *nfs_client;
34
33
spinlock_t nfs_client_lock;
35
34
ktime_t boot_time;
36
35
#ifdef CONFIG_PROC_FS
+187
fs/nfs/sysfs.c
reviewed
···
1
1
+
// SPDX-License-Identifier: GPL-2.0
2
2
+
/*
3
3
+
* Copyright (c) 2019 Hammerspace Inc
4
4
+
*/
5
5
+
6
6
+
#include <linux/module.h>
7
7
+
#include <linux/kobject.h>
8
8
+
#include <linux/sysfs.h>
9
9
+
#include <linux/fs.h>
10
10
+
#include <linux/slab.h>
11
11
+
#include <linux/netdevice.h>
12
12
+
#include <linux/string.h>
13
13
+
#include <linux/nfs_fs.h>
14
14
+
#include <linux/rcupdate.h>
15
15
+
16
16
+
#include "nfs4_fs.h"
17
17
+
#include "netns.h"
18
18
+
#include "sysfs.h"
19
19
+
20
20
+
struct kobject *nfs_client_kobj;
21
21
+
static struct kset *nfs_client_kset;
22
22
+
23
23
+
static void nfs_netns_object_release(struct kobject *kobj)
24
24
+
{
25
25
+
kfree(kobj);
26
26
+
}
27
27
+
28
28
+
static const struct kobj_ns_type_operations *nfs_netns_object_child_ns_type(
29
29
+
struct kobject *kobj)
30
30
+
{
31
31
+
return &net_ns_type_operations;
32
32
+
}
33
33
+
34
34
+
static struct kobj_type nfs_netns_object_type = {
35
35
+
.release = nfs_netns_object_release,
36
36
+
.sysfs_ops = &kobj_sysfs_ops,
37
37
+
.child_ns_type = nfs_netns_object_child_ns_type,
38
38
+
};
39
39
+
40
40
+
static struct kobject *nfs_netns_object_alloc(const char *name,
41
41
+
struct kset *kset, struct kobject *parent)
42
42
+
{
43
43
+
struct kobject *kobj;
44
44
+
45
45
+
kobj = kzalloc(sizeof(*kobj), GFP_KERNEL);
46
46
+
if (kobj) {
47
47
+
kobj->kset = kset;
48
48
+
if (kobject_init_and_add(kobj, &nfs_netns_object_type,
49
49
+
parent, "%s", name) == 0)
50
50
+
return kobj;
51
51
+
kobject_put(kobj);
52
52
+
}
53
53
+
return NULL;
54
54
+
}
55
55
+
56
56
+
int nfs_sysfs_init(void)
57
57
+
{
58
58
+
nfs_client_kset = kset_create_and_add("nfs", NULL, fs_kobj);
59
59
+
if (!nfs_client_kset)
60
60
+
return -ENOMEM;
61
61
+
nfs_client_kobj = nfs_netns_object_alloc("net", nfs_client_kset, NULL);
62
62
+
if (!nfs_client_kobj) {
63
63
+
kset_unregister(nfs_client_kset);
64
64
+
nfs_client_kset = NULL;
65
65
+
return -ENOMEM;
66
66
+
}
67
67
+
return 0;
68
68
+
}
69
69
+
70
70
+
void nfs_sysfs_exit(void)
71
71
+
{
72
72
+
kobject_put(nfs_client_kobj);
73
73
+
kset_unregister(nfs_client_kset);
74
74
+
}
75
75
+
76
76
+
static ssize_t nfs_netns_identifier_show(struct kobject *kobj,
77
77
+
struct kobj_attribute *attr, char *buf)
78
78
+
{
79
79
+
struct nfs_netns_client *c = container_of(kobj,
80
80
+
struct nfs_netns_client,
81
81
+
kobject);
82
82
+
return scnprintf(buf, PAGE_SIZE, "%s\n", c->identifier);
83
83
+
}
84
84
+
85
85
+
/* Strip trailing '\n' */
86
86
+
static size_t nfs_string_strip(const char *c, size_t len)
87
87
+
{
88
88
+
while (len > 0 && c[len-1] == '\n')
89
89
+
--len;
90
90
+
return len;
91
91
+
}
92
92
+
93
93
+
static ssize_t nfs_netns_identifier_store(struct kobject *kobj,
94
94
+
struct kobj_attribute *attr,
95
95
+
const char *buf, size_t count)
96
96
+
{
97
97
+
struct nfs_netns_client *c = container_of(kobj,
98
98
+
struct nfs_netns_client,
99
99
+
kobject);
100
100
+
const char *old;
101
101
+
char *p;
102
102
+
size_t len;
103
103
+
104
104
+
len = nfs_string_strip(buf, min_t(size_t, count, CONTAINER_ID_MAXLEN));
105
105
+
if (!len)
106
106
+
return 0;
107
107
+
p = kmemdup_nul(buf, len, GFP_KERNEL);
108
108
+
if (!p)
109
109
+
return -ENOMEM;
110
110
+
old = xchg(&c->identifier, p);
111
111
+
if (old) {
112
112
+
synchronize_rcu();
113
113
+
kfree(old);
114
114
+
}
115
115
+
return count;
116
116
+
}
117
117
+
118
118
+
static void nfs_netns_client_release(struct kobject *kobj)
119
119
+
{
120
120
+
struct nfs_netns_client *c = container_of(kobj,
121
121
+
struct nfs_netns_client,
122
122
+
kobject);
123
123
+
124
124
+
if (c->identifier)
125
125
+
kfree(c->identifier);
126
126
+
kfree(c);
127
127
+
}
128
128
+
129
129
+
static const void *nfs_netns_client_namespace(struct kobject *kobj)
130
130
+
{
131
131
+
return container_of(kobj, struct nfs_netns_client, kobject)->net;
132
132
+
}
133
133
+
134
134
+
static struct kobj_attribute nfs_netns_client_id = __ATTR(identifier,
135
135
+
0644, nfs_netns_identifier_show, nfs_netns_identifier_store);
136
136
+
137
137
+
static struct attribute *nfs_netns_client_attrs[] = {
138
138
+
&nfs_netns_client_id.attr,
139
139
+
NULL,
140
140
+
};
141
141
+
142
142
+
static struct kobj_type nfs_netns_client_type = {
143
143
+
.release = nfs_netns_client_release,
144
144
+
.default_attrs = nfs_netns_client_attrs,
145
145
+
.sysfs_ops = &kobj_sysfs_ops,
146
146
+
.namespace = nfs_netns_client_namespace,
147
147
+
};
148
148
+
149
149
+
static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent,
150
150
+
struct net *net)
151
151
+
{
152
152
+
struct nfs_netns_client *p;
153
153
+
154
154
+
p = kzalloc(sizeof(*p), GFP_KERNEL);
155
155
+
if (p) {
156
156
+
p->net = net;
157
157
+
p->kobject.kset = nfs_client_kset;
158
158
+
if (kobject_init_and_add(&p->kobject, &nfs_netns_client_type,
159
159
+
parent, "nfs_client") == 0)
160
160
+
return p;
161
161
+
kobject_put(&p->kobject);
162
162
+
}
163
163
+
return NULL;
164
164
+
}
165
165
+
166
166
+
void nfs_netns_sysfs_setup(struct nfs_net *netns, struct net *net)
167
167
+
{
168
168
+
struct nfs_netns_client *clp;
169
169
+
170
170
+
clp = nfs_netns_client_alloc(nfs_client_kobj, net);
171
171
+
if (clp) {
172
172
+
netns->nfs_client = clp;
173
173
+
kobject_uevent(&clp->kobject, KOBJ_ADD);
174
174
+
}
175
175
+
}
176
176
+
177
177
+
void nfs_netns_sysfs_destroy(struct nfs_net *netns)
178
178
+
{
179
179
+
struct nfs_netns_client *clp = netns->nfs_client;
180
180
+
181
181
+
if (clp) {
182
182
+
kobject_uevent(&clp->kobject, KOBJ_REMOVE);
183
183
+
kobject_del(&clp->kobject);
184
184
+
kobject_put(&clp->kobject);
185
185
+
netns->nfs_client = NULL;
186
186
+
}
187
187
+
}
+25
fs/nfs/sysfs.h
reviewed
···
1
1
+
// SPDX-License-Identifier: GPL-2.0
2
2
+
/*
3
3
+
* Copyright (c) 2019 Hammerspace Inc
4
4
+
*/
5
5
+
6
6
+
#ifndef __NFS_SYSFS_H
7
7
+
#define __NFS_SYSFS_H
8
8
+
9
9
+
#define CONTAINER_ID_MAXLEN (64)
10
10
+
11
11
+
struct nfs_netns_client {
12
12
+
struct kobject kobject;
13
13
+
struct net *net;
14
14
+
const char *identifier;
15
15
+
};
16
16
+
17
17
+
extern struct kobject *nfs_client_kobj;
18
18
+
19
19
+
extern int nfs_sysfs_init(void);
20
20
+
extern void nfs_sysfs_exit(void);
21
21
+
22
22
+
void nfs_netns_sysfs_setup(struct nfs_net *netns, struct net *net);
23
23
+
void nfs_netns_sysfs_destroy(struct nfs_net *netns);
24
24
+
25
25
+
#endif