1 // SPDX-License-Identifier: GPL-2.0
3 * Copyright (c) 2019 Hammerspace Inc
6 #include <linux/module.h>
7 #include <linux/kobject.h>
8 #include <linux/sysfs.h>
10 #include <linux/slab.h>
11 #include <linux/netdevice.h>
12 #include <linux/string.h>
13 #include <linux/nfs_fs.h>
14 #include <linux/rcupdate.h>
15 #include <linux/lockd/lockd.h>
21 static struct kset
*nfs_kset
;
23 static void nfs_kset_release(struct kobject
*kobj
)
25 struct kset
*kset
= container_of(kobj
, struct kset
, kobj
);
29 static const struct kobj_ns_type_operations
*nfs_netns_object_child_ns_type(
30 const struct kobject
*kobj
)
32 return &net_ns_type_operations
;
35 static struct kobj_type nfs_kset_type
= {
36 .release
= nfs_kset_release
,
37 .sysfs_ops
= &kobj_sysfs_ops
,
38 .child_ns_type
= nfs_netns_object_child_ns_type
,
41 int nfs_sysfs_init(void)
45 nfs_kset
= kzalloc(sizeof(*nfs_kset
), GFP_KERNEL
);
49 ret
= kobject_set_name(&nfs_kset
->kobj
, "nfs");
55 nfs_kset
->kobj
.parent
= fs_kobj
;
56 nfs_kset
->kobj
.ktype
= &nfs_kset_type
;
57 nfs_kset
->kobj
.kset
= NULL
;
59 ret
= kset_register(nfs_kset
);
68 void nfs_sysfs_exit(void)
70 kset_unregister(nfs_kset
);
73 static ssize_t
nfs_netns_identifier_show(struct kobject
*kobj
,
74 struct kobj_attribute
*attr
, char *buf
)
76 struct nfs_netns_client
*c
= container_of(kobj
,
77 struct nfs_netns_client
,
82 ret
= sysfs_emit(buf
, "%s\n", rcu_dereference(c
->identifier
));
87 /* Strip trailing '\n' */
88 static size_t nfs_string_strip(const char *c
, size_t len
)
90 while (len
> 0 && c
[len
-1] == '\n')
95 static ssize_t
nfs_netns_identifier_store(struct kobject
*kobj
,
96 struct kobj_attribute
*attr
,
97 const char *buf
, size_t count
)
99 struct nfs_netns_client
*c
= container_of(kobj
,
100 struct nfs_netns_client
,
106 len
= nfs_string_strip(buf
, min_t(size_t, count
, CONTAINER_ID_MAXLEN
));
109 p
= kmemdup_nul(buf
, len
, GFP_KERNEL
);
112 old
= rcu_dereference_protected(xchg(&c
->identifier
, (char __rcu
*)p
), 1);
120 static void nfs_netns_client_release(struct kobject
*kobj
)
122 struct nfs_netns_client
*c
= container_of(kobj
,
123 struct nfs_netns_client
,
126 kfree(rcu_dereference_raw(c
->identifier
));
129 static const void *nfs_netns_client_namespace(const struct kobject
*kobj
)
131 return container_of(kobj
, struct nfs_netns_client
, kobject
)->net
;
134 static struct kobj_attribute nfs_netns_client_id
= __ATTR(identifier
,
135 0644, nfs_netns_identifier_show
, nfs_netns_identifier_store
);
137 static struct attribute
*nfs_netns_client_attrs
[] = {
138 &nfs_netns_client_id
.attr
,
141 ATTRIBUTE_GROUPS(nfs_netns_client
);
143 static struct kobj_type nfs_netns_client_type
= {
144 .release
= nfs_netns_client_release
,
145 .default_groups
= nfs_netns_client_groups
,
146 .sysfs_ops
= &kobj_sysfs_ops
,
147 .namespace = nfs_netns_client_namespace
,
150 static void nfs_netns_object_release(struct kobject
*kobj
)
152 struct nfs_netns_client
*c
= container_of(kobj
,
153 struct nfs_netns_client
,
158 static const void *nfs_netns_namespace(const struct kobject
*kobj
)
160 return container_of(kobj
, struct nfs_netns_client
, nfs_net_kobj
)->net
;
163 static struct kobj_type nfs_netns_object_type
= {
164 .release
= nfs_netns_object_release
,
165 .sysfs_ops
= &kobj_sysfs_ops
,
166 .namespace = nfs_netns_namespace
,
169 static struct nfs_netns_client
*nfs_netns_client_alloc(struct kobject
*parent
,
172 struct nfs_netns_client
*p
;
174 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
177 p
->kobject
.kset
= nfs_kset
;
178 p
->nfs_net_kobj
.kset
= nfs_kset
;
180 if (kobject_init_and_add(&p
->nfs_net_kobj
, &nfs_netns_object_type
,
181 parent
, "net") != 0) {
182 kobject_put(&p
->nfs_net_kobj
);
186 if (kobject_init_and_add(&p
->kobject
, &nfs_netns_client_type
,
187 &p
->nfs_net_kobj
, "nfs_client") == 0)
190 kobject_put(&p
->kobject
);
195 void nfs_netns_sysfs_setup(struct nfs_net
*netns
, struct net
*net
)
197 struct nfs_netns_client
*clp
;
199 clp
= nfs_netns_client_alloc(&nfs_kset
->kobj
, net
);
201 netns
->nfs_client
= clp
;
202 kobject_uevent(&clp
->kobject
, KOBJ_ADD
);
206 void nfs_netns_sysfs_destroy(struct nfs_net
*netns
)
208 struct nfs_netns_client
*clp
= netns
->nfs_client
;
211 kobject_uevent(&clp
->kobject
, KOBJ_REMOVE
);
212 kobject_del(&clp
->kobject
);
213 kobject_put(&clp
->kobject
);
214 kobject_del(&clp
->nfs_net_kobj
);
215 kobject_put(&clp
->nfs_net_kobj
);
216 netns
->nfs_client
= NULL
;
220 static bool shutdown_match_client(const struct rpc_task
*task
, const void *data
)
225 static void shutdown_client(struct rpc_clnt
*clnt
)
227 clnt
->cl_shutdown
= 1;
228 rpc_cancel_tasks(clnt
, -EIO
, shutdown_match_client
, NULL
);
232 shutdown_show(struct kobject
*kobj
, struct kobj_attribute
*attr
,
235 struct nfs_server
*server
= container_of(kobj
, struct nfs_server
, kobj
);
236 bool shutdown
= server
->flags
& NFS_MOUNT_SHUTDOWN
;
237 return sysfs_emit(buf
, "%d\n", shutdown
);
241 shutdown_store(struct kobject
*kobj
, struct kobj_attribute
*attr
,
242 const char *buf
, size_t count
)
244 struct nfs_server
*server
;
247 server
= container_of(kobj
, struct nfs_server
, kobj
);
249 ret
= kstrtoint(buf
, 0, &val
);
256 /* already shut down? */
257 if (server
->flags
& NFS_MOUNT_SHUTDOWN
)
260 server
->flags
|= NFS_MOUNT_SHUTDOWN
;
261 shutdown_client(server
->client
);
262 shutdown_client(server
->nfs_client
->cl_rpcclient
);
264 if (!IS_ERR(server
->client_acl
))
265 shutdown_client(server
->client_acl
);
267 if (server
->nlm_host
)
268 shutdown_client(server
->nlm_host
->h_rpcclnt
);
273 static struct kobj_attribute nfs_sysfs_attr_shutdown
= __ATTR_RW(shutdown
);
275 #define RPC_CLIENT_NAME_SIZE 64
277 void nfs_sysfs_link_rpc_client(struct nfs_server
*server
,
278 struct rpc_clnt
*clnt
, const char *uniq
)
280 char name
[RPC_CLIENT_NAME_SIZE
];
283 strcpy(name
, clnt
->cl_program
->name
);
284 strcat(name
, uniq
? uniq
: "");
285 strcat(name
, "_client");
287 ret
= sysfs_create_link_nowarn(&server
->kobj
,
288 &clnt
->cl_sysfs
->kobject
, name
);
290 pr_warn("NFS: can't create link to %s in sysfs (%d)\n",
293 EXPORT_SYMBOL_GPL(nfs_sysfs_link_rpc_client
);
295 static void nfs_sysfs_sb_release(struct kobject
*kobj
)
297 /* no-op: why? see lib/kobject.c kobject_cleanup() */
300 static const void *nfs_netns_server_namespace(const struct kobject
*kobj
)
302 return container_of(kobj
, struct nfs_server
, kobj
)->nfs_client
->cl_net
;
305 static struct kobj_type nfs_sb_ktype
= {
306 .release
= nfs_sysfs_sb_release
,
307 .sysfs_ops
= &kobj_sysfs_ops
,
308 .namespace = nfs_netns_server_namespace
,
309 .child_ns_type
= nfs_netns_object_child_ns_type
,
312 void nfs_sysfs_add_server(struct nfs_server
*server
)
316 ret
= kobject_init_and_add(&server
->kobj
, &nfs_sb_ktype
,
317 &nfs_kset
->kobj
, "server-%d", server
->s_sysfs_id
);
319 pr_warn("NFS: nfs sysfs add server-%d failed (%d)\n",
320 server
->s_sysfs_id
, ret
);
323 ret
= sysfs_create_file_ns(&server
->kobj
, &nfs_sysfs_attr_shutdown
.attr
,
324 nfs_netns_server_namespace(&server
->kobj
));
326 pr_warn("NFS: sysfs_create_file_ns for server-%d failed (%d)\n",
327 server
->s_sysfs_id
, ret
);
329 EXPORT_SYMBOL_GPL(nfs_sysfs_add_server
);
331 void nfs_sysfs_move_server_to_sb(struct super_block
*s
)
333 struct nfs_server
*server
= s
->s_fs_info
;
336 ret
= kobject_rename(&server
->kobj
, s
->s_id
);
338 pr_warn("NFS: rename sysfs %s failed (%d)\n",
339 server
->kobj
.name
, ret
);
342 void nfs_sysfs_move_sb_to_server(struct nfs_server
*server
)
347 s
= kasprintf(GFP_KERNEL
, "server-%d", server
->s_sysfs_id
);
349 ret
= kobject_rename(&server
->kobj
, s
);
353 pr_warn("NFS: rename sysfs %s failed (%d)\n",
354 server
->kobj
.name
, ret
);
357 /* unlink, not dec-ref */
358 void nfs_sysfs_remove_server(struct nfs_server
*server
)
360 kobject_del(&server
->kobj
);