xref: /openbmc/linux/fs/nfs/sysfs.c (revision c3dd7de2)
1996bc4f4STrond Myklebust // SPDX-License-Identifier: GPL-2.0
2996bc4f4STrond Myklebust /*
3996bc4f4STrond Myklebust  * Copyright (c) 2019 Hammerspace Inc
4996bc4f4STrond Myklebust  */
5996bc4f4STrond Myklebust 
6996bc4f4STrond Myklebust #include <linux/module.h>
7996bc4f4STrond Myklebust #include <linux/kobject.h>
8996bc4f4STrond Myklebust #include <linux/sysfs.h>
9996bc4f4STrond Myklebust #include <linux/fs.h>
10996bc4f4STrond Myklebust #include <linux/slab.h>
11996bc4f4STrond Myklebust #include <linux/netdevice.h>
12bf11fbdbSTrond Myklebust #include <linux/string.h>
13bf11fbdbSTrond Myklebust #include <linux/nfs_fs.h>
14bf11fbdbSTrond Myklebust #include <linux/rcupdate.h>
15d9615d16SBenjamin Coddington #include <linux/lockd/lockd.h>
16996bc4f4STrond Myklebust 
17bf11fbdbSTrond Myklebust #include "nfs4_fs.h"
18bf11fbdbSTrond Myklebust #include "netns.h"
19996bc4f4STrond Myklebust #include "sysfs.h"
20996bc4f4STrond Myklebust 
218b18a2edSBenjamin Coddington static struct kset *nfs_kset;
22996bc4f4STrond Myklebust 
nfs_kset_release(struct kobject * kobj)23943aef2dSBenjamin Coddington static void nfs_kset_release(struct kobject *kobj)
24943aef2dSBenjamin Coddington {
25943aef2dSBenjamin Coddington 	struct kset *kset = container_of(kobj, struct kset, kobj);
26943aef2dSBenjamin Coddington 	kfree(kset);
27943aef2dSBenjamin Coddington }
28943aef2dSBenjamin Coddington 
nfs_netns_object_child_ns_type(const struct kobject * kobj)29996bc4f4STrond Myklebust static const struct kobj_ns_type_operations *nfs_netns_object_child_ns_type(
3002a476d9SGreg Kroah-Hartman 		const struct kobject *kobj)
31996bc4f4STrond Myklebust {
32996bc4f4STrond Myklebust 	return &net_ns_type_operations;
33996bc4f4STrond Myklebust }
34996bc4f4STrond Myklebust 
35943aef2dSBenjamin Coddington static struct kobj_type nfs_kset_type = {
36943aef2dSBenjamin Coddington 	.release = nfs_kset_release,
37943aef2dSBenjamin Coddington 	.sysfs_ops = &kobj_sysfs_ops,
38996bc4f4STrond Myklebust 	.child_ns_type = nfs_netns_object_child_ns_type,
39996bc4f4STrond Myklebust };
40996bc4f4STrond Myklebust 
nfs_sysfs_init(void)41996bc4f4STrond Myklebust int nfs_sysfs_init(void)
42996bc4f4STrond Myklebust {
43943aef2dSBenjamin Coddington 	int ret;
44943aef2dSBenjamin Coddington 
45943aef2dSBenjamin Coddington 	nfs_kset = kzalloc(sizeof(*nfs_kset), GFP_KERNEL);
468b18a2edSBenjamin Coddington 	if (!nfs_kset)
47996bc4f4STrond Myklebust 		return -ENOMEM;
48943aef2dSBenjamin Coddington 
49943aef2dSBenjamin Coddington 	ret = kobject_set_name(&nfs_kset->kobj, "nfs");
50943aef2dSBenjamin Coddington 	if (ret) {
51943aef2dSBenjamin Coddington 		kfree(nfs_kset);
52943aef2dSBenjamin Coddington 		return ret;
53943aef2dSBenjamin Coddington 	}
54943aef2dSBenjamin Coddington 
55943aef2dSBenjamin Coddington 	nfs_kset->kobj.parent = fs_kobj;
56943aef2dSBenjamin Coddington 	nfs_kset->kobj.ktype = &nfs_kset_type;
57943aef2dSBenjamin Coddington 	nfs_kset->kobj.kset = NULL;
58943aef2dSBenjamin Coddington 
59943aef2dSBenjamin Coddington 	ret = kset_register(nfs_kset);
60943aef2dSBenjamin Coddington 	if (ret) {
61943aef2dSBenjamin Coddington 		kfree(nfs_kset);
62943aef2dSBenjamin Coddington 		return ret;
63943aef2dSBenjamin Coddington 	}
64943aef2dSBenjamin Coddington 
65996bc4f4STrond Myklebust 	return 0;
66996bc4f4STrond Myklebust }
67996bc4f4STrond Myklebust 
nfs_sysfs_exit(void)68996bc4f4STrond Myklebust void nfs_sysfs_exit(void)
69996bc4f4STrond Myklebust {
708b18a2edSBenjamin Coddington 	kset_unregister(nfs_kset);
71996bc4f4STrond Myklebust }
72bf11fbdbSTrond Myklebust 
nfs_netns_identifier_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)73bf11fbdbSTrond Myklebust static ssize_t nfs_netns_identifier_show(struct kobject *kobj,
74bf11fbdbSTrond Myklebust 		struct kobj_attribute *attr, char *buf)
75bf11fbdbSTrond Myklebust {
76bf11fbdbSTrond Myklebust 	struct nfs_netns_client *c = container_of(kobj,
77bf11fbdbSTrond Myklebust 			struct nfs_netns_client,
78bf11fbdbSTrond Myklebust 			kobject);
79094eca37STrond Myklebust 	ssize_t ret;
80094eca37STrond Myklebust 
81094eca37STrond Myklebust 	rcu_read_lock();
8219cdc8faSye xingchen 	ret = sysfs_emit(buf, "%s\n", rcu_dereference(c->identifier));
83094eca37STrond Myklebust 	rcu_read_unlock();
84094eca37STrond Myklebust 	return ret;
85bf11fbdbSTrond Myklebust }
86bf11fbdbSTrond Myklebust 
87bf11fbdbSTrond Myklebust /* Strip trailing '\n' */
nfs_string_strip(const char * c,size_t len)88bf11fbdbSTrond Myklebust static size_t nfs_string_strip(const char *c, size_t len)
89bf11fbdbSTrond Myklebust {
90bf11fbdbSTrond Myklebust 	while (len > 0 && c[len-1] == '\n')
91bf11fbdbSTrond Myklebust 		--len;
92bf11fbdbSTrond Myklebust 	return len;
93bf11fbdbSTrond Myklebust }
94bf11fbdbSTrond Myklebust 
nfs_netns_identifier_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)95bf11fbdbSTrond Myklebust static ssize_t nfs_netns_identifier_store(struct kobject *kobj,
96bf11fbdbSTrond Myklebust 		struct kobj_attribute *attr,
97bf11fbdbSTrond Myklebust 		const char *buf, size_t count)
98bf11fbdbSTrond Myklebust {
99bf11fbdbSTrond Myklebust 	struct nfs_netns_client *c = container_of(kobj,
100bf11fbdbSTrond Myklebust 			struct nfs_netns_client,
101bf11fbdbSTrond Myklebust 			kobject);
102bf11fbdbSTrond Myklebust 	const char *old;
103bf11fbdbSTrond Myklebust 	char *p;
104bf11fbdbSTrond Myklebust 	size_t len;
105bf11fbdbSTrond Myklebust 
106bf11fbdbSTrond Myklebust 	len = nfs_string_strip(buf, min_t(size_t, count, CONTAINER_ID_MAXLEN));
107bf11fbdbSTrond Myklebust 	if (!len)
108bf11fbdbSTrond Myklebust 		return 0;
109bf11fbdbSTrond Myklebust 	p = kmemdup_nul(buf, len, GFP_KERNEL);
110bf11fbdbSTrond Myklebust 	if (!p)
111bf11fbdbSTrond Myklebust 		return -ENOMEM;
112094eca37STrond Myklebust 	old = rcu_dereference_protected(xchg(&c->identifier, (char __rcu *)p), 1);
113bf11fbdbSTrond Myklebust 	if (old) {
114bf11fbdbSTrond Myklebust 		synchronize_rcu();
115bf11fbdbSTrond Myklebust 		kfree(old);
116bf11fbdbSTrond Myklebust 	}
117bf11fbdbSTrond Myklebust 	return count;
118bf11fbdbSTrond Myklebust }
119bf11fbdbSTrond Myklebust 
nfs_netns_client_release(struct kobject * kobj)120bf11fbdbSTrond Myklebust static void nfs_netns_client_release(struct kobject *kobj)
121bf11fbdbSTrond Myklebust {
122bf11fbdbSTrond Myklebust 	struct nfs_netns_client *c = container_of(kobj,
123bf11fbdbSTrond Myklebust 			struct nfs_netns_client,
124bf11fbdbSTrond Myklebust 			kobject);
125bf11fbdbSTrond Myklebust 
126094eca37STrond Myklebust 	kfree(rcu_dereference_raw(c->identifier));
127bf11fbdbSTrond Myklebust }
128bf11fbdbSTrond Myklebust 
nfs_netns_client_namespace(const struct kobject * kobj)12902a476d9SGreg Kroah-Hartman static const void *nfs_netns_client_namespace(const struct kobject *kobj)
130bf11fbdbSTrond Myklebust {
131bf11fbdbSTrond Myklebust 	return container_of(kobj, struct nfs_netns_client, kobject)->net;
132bf11fbdbSTrond Myklebust }
133bf11fbdbSTrond Myklebust 
134bf11fbdbSTrond Myklebust static struct kobj_attribute nfs_netns_client_id = __ATTR(identifier,
135bf11fbdbSTrond Myklebust 		0644, nfs_netns_identifier_show, nfs_netns_identifier_store);
136bf11fbdbSTrond Myklebust 
137bf11fbdbSTrond Myklebust static struct attribute *nfs_netns_client_attrs[] = {
138bf11fbdbSTrond Myklebust 	&nfs_netns_client_id.attr,
139bf11fbdbSTrond Myklebust 	NULL,
140bf11fbdbSTrond Myklebust };
14101f34245SGreg Kroah-Hartman ATTRIBUTE_GROUPS(nfs_netns_client);
142bf11fbdbSTrond Myklebust 
143bf11fbdbSTrond Myklebust static struct kobj_type nfs_netns_client_type = {
144bf11fbdbSTrond Myklebust 	.release = nfs_netns_client_release,
14501f34245SGreg Kroah-Hartman 	.default_groups = nfs_netns_client_groups,
146bf11fbdbSTrond Myklebust 	.sysfs_ops = &kobj_sysfs_ops,
147bf11fbdbSTrond Myklebust 	.namespace = nfs_netns_client_namespace,
148bf11fbdbSTrond Myklebust };
149bf11fbdbSTrond Myklebust 
nfs_netns_object_release(struct kobject * kobj)150e96f9268SBenjamin Coddington static void nfs_netns_object_release(struct kobject *kobj)
151e96f9268SBenjamin Coddington {
152e96f9268SBenjamin Coddington 	struct nfs_netns_client *c = container_of(kobj,
153e96f9268SBenjamin Coddington 			struct nfs_netns_client,
154e96f9268SBenjamin Coddington 			nfs_net_kobj);
155e96f9268SBenjamin Coddington 	kfree(c);
156e96f9268SBenjamin Coddington }
157e96f9268SBenjamin Coddington 
nfs_netns_namespace(const struct kobject * kobj)158e96f9268SBenjamin Coddington static const void *nfs_netns_namespace(const struct kobject *kobj)
159e96f9268SBenjamin Coddington {
160e96f9268SBenjamin Coddington 	return container_of(kobj, struct nfs_netns_client, nfs_net_kobj)->net;
161e96f9268SBenjamin Coddington }
162e96f9268SBenjamin Coddington 
163e96f9268SBenjamin Coddington static struct kobj_type nfs_netns_object_type = {
164e96f9268SBenjamin Coddington 	.release = nfs_netns_object_release,
165e96f9268SBenjamin Coddington 	.sysfs_ops = &kobj_sysfs_ops,
166e96f9268SBenjamin Coddington 	.namespace =  nfs_netns_namespace,
167e96f9268SBenjamin Coddington };
168e96f9268SBenjamin Coddington 
nfs_netns_client_alloc(struct kobject * parent,struct net * net)169bf11fbdbSTrond Myklebust static struct nfs_netns_client *nfs_netns_client_alloc(struct kobject *parent,
170bf11fbdbSTrond Myklebust 		struct net *net)
171bf11fbdbSTrond Myklebust {
172bf11fbdbSTrond Myklebust 	struct nfs_netns_client *p;
173bf11fbdbSTrond Myklebust 
174bf11fbdbSTrond Myklebust 	p = kzalloc(sizeof(*p), GFP_KERNEL);
175bf11fbdbSTrond Myklebust 	if (p) {
176bf11fbdbSTrond Myklebust 		p->net = net;
1778b18a2edSBenjamin Coddington 		p->kobject.kset = nfs_kset;
178e96f9268SBenjamin Coddington 		p->nfs_net_kobj.kset = nfs_kset;
179e96f9268SBenjamin Coddington 
180e96f9268SBenjamin Coddington 		if (kobject_init_and_add(&p->nfs_net_kobj, &nfs_netns_object_type,
181e96f9268SBenjamin Coddington 					parent, "net") != 0) {
182e96f9268SBenjamin Coddington 			kobject_put(&p->nfs_net_kobj);
183e96f9268SBenjamin Coddington 			return NULL;
184e96f9268SBenjamin Coddington 		}
185e96f9268SBenjamin Coddington 
186bf11fbdbSTrond Myklebust 		if (kobject_init_and_add(&p->kobject, &nfs_netns_client_type,
187e96f9268SBenjamin Coddington 					&p->nfs_net_kobj, "nfs_client") == 0)
188bf11fbdbSTrond Myklebust 			return p;
189e96f9268SBenjamin Coddington 
190bf11fbdbSTrond Myklebust 		kobject_put(&p->kobject);
191bf11fbdbSTrond Myklebust 	}
192bf11fbdbSTrond Myklebust 	return NULL;
193bf11fbdbSTrond Myklebust }
194bf11fbdbSTrond Myklebust 
nfs_netns_sysfs_setup(struct nfs_net * netns,struct net * net)195bf11fbdbSTrond Myklebust void nfs_netns_sysfs_setup(struct nfs_net *netns, struct net *net)
196bf11fbdbSTrond Myklebust {
197bf11fbdbSTrond Myklebust 	struct nfs_netns_client *clp;
198bf11fbdbSTrond Myklebust 
199e96f9268SBenjamin Coddington 	clp = nfs_netns_client_alloc(&nfs_kset->kobj, net);
200bf11fbdbSTrond Myklebust 	if (clp) {
201bf11fbdbSTrond Myklebust 		netns->nfs_client = clp;
202bf11fbdbSTrond Myklebust 		kobject_uevent(&clp->kobject, KOBJ_ADD);
203bf11fbdbSTrond Myklebust 	}
204bf11fbdbSTrond Myklebust }
205bf11fbdbSTrond Myklebust 
nfs_netns_sysfs_destroy(struct nfs_net * netns)206bf11fbdbSTrond Myklebust void nfs_netns_sysfs_destroy(struct nfs_net *netns)
207bf11fbdbSTrond Myklebust {
208bf11fbdbSTrond Myklebust 	struct nfs_netns_client *clp = netns->nfs_client;
209bf11fbdbSTrond Myklebust 
210bf11fbdbSTrond Myklebust 	if (clp) {
211bf11fbdbSTrond Myklebust 		kobject_uevent(&clp->kobject, KOBJ_REMOVE);
212bf11fbdbSTrond Myklebust 		kobject_del(&clp->kobject);
213bf11fbdbSTrond Myklebust 		kobject_put(&clp->kobject);
214e96f9268SBenjamin Coddington 		kobject_del(&clp->nfs_net_kobj);
215e96f9268SBenjamin Coddington 		kobject_put(&clp->nfs_net_kobj);
216bf11fbdbSTrond Myklebust 		netns->nfs_client = NULL;
217bf11fbdbSTrond Myklebust 	}
218bf11fbdbSTrond Myklebust }
2191c725118SBenjamin Coddington 
shutdown_match_client(const struct rpc_task * task,const void * data)2207d3e26a0SBenjamin Coddington static bool shutdown_match_client(const struct rpc_task *task, const void *data)
2217d3e26a0SBenjamin Coddington {
2227d3e26a0SBenjamin Coddington 	return true;
2237d3e26a0SBenjamin Coddington }
2247d3e26a0SBenjamin Coddington 
shutdown_client(struct rpc_clnt * clnt)2257d3e26a0SBenjamin Coddington static void shutdown_client(struct rpc_clnt *clnt)
2267d3e26a0SBenjamin Coddington {
2277d3e26a0SBenjamin Coddington 	clnt->cl_shutdown = 1;
2287d3e26a0SBenjamin Coddington 	rpc_cancel_tasks(clnt, -EIO, shutdown_match_client, NULL);
2297d3e26a0SBenjamin Coddington }
2307d3e26a0SBenjamin Coddington 
231d9615d16SBenjamin Coddington static ssize_t
shutdown_show(struct kobject * kobj,struct kobj_attribute * attr,char * buf)232d9615d16SBenjamin Coddington shutdown_show(struct kobject *kobj, struct kobj_attribute *attr,
233d9615d16SBenjamin Coddington 				char *buf)
234d9615d16SBenjamin Coddington {
235d9615d16SBenjamin Coddington 	struct nfs_server *server = container_of(kobj, struct nfs_server, kobj);
236d9615d16SBenjamin Coddington 	bool shutdown = server->flags & NFS_MOUNT_SHUTDOWN;
237d9615d16SBenjamin Coddington 	return sysfs_emit(buf, "%d\n", shutdown);
238d9615d16SBenjamin Coddington }
239d9615d16SBenjamin Coddington 
240d9615d16SBenjamin Coddington static ssize_t
shutdown_store(struct kobject * kobj,struct kobj_attribute * attr,const char * buf,size_t count)241d9615d16SBenjamin Coddington shutdown_store(struct kobject *kobj, struct kobj_attribute *attr,
242d9615d16SBenjamin Coddington 				const char *buf, size_t count)
243d9615d16SBenjamin Coddington {
244d9615d16SBenjamin Coddington 	struct nfs_server *server;
245d9615d16SBenjamin Coddington 	int ret, val;
246d9615d16SBenjamin Coddington 
247d9615d16SBenjamin Coddington 	server = container_of(kobj, struct nfs_server, kobj);
248d9615d16SBenjamin Coddington 
249d9615d16SBenjamin Coddington 	ret = kstrtoint(buf, 0, &val);
250d9615d16SBenjamin Coddington 	if (ret)
251d9615d16SBenjamin Coddington 		return ret;
252d9615d16SBenjamin Coddington 
253d9615d16SBenjamin Coddington 	if (val != 1)
254d9615d16SBenjamin Coddington 		return -EINVAL;
255d9615d16SBenjamin Coddington 
256d9615d16SBenjamin Coddington 	/* already shut down? */
257d9615d16SBenjamin Coddington 	if (server->flags & NFS_MOUNT_SHUTDOWN)
258d9615d16SBenjamin Coddington 		goto out;
259d9615d16SBenjamin Coddington 
260d9615d16SBenjamin Coddington 	server->flags |= NFS_MOUNT_SHUTDOWN;
2617d3e26a0SBenjamin Coddington 	shutdown_client(server->client);
2627d3e26a0SBenjamin Coddington 	shutdown_client(server->nfs_client->cl_rpcclient);
263d9615d16SBenjamin Coddington 
264d9615d16SBenjamin Coddington 	if (!IS_ERR(server->client_acl))
2657d3e26a0SBenjamin Coddington 		shutdown_client(server->client_acl);
266d9615d16SBenjamin Coddington 
267d9615d16SBenjamin Coddington 	if (server->nlm_host)
2687d3e26a0SBenjamin Coddington 		shutdown_client(server->nlm_host->h_rpcclnt);
269d9615d16SBenjamin Coddington out:
270d9615d16SBenjamin Coddington 	return count;
271d9615d16SBenjamin Coddington }
272d9615d16SBenjamin Coddington 
273d9615d16SBenjamin Coddington static struct kobj_attribute nfs_sysfs_attr_shutdown = __ATTR_RW(shutdown);
274d9615d16SBenjamin Coddington 
275e13b5493SBenjamin Coddington #define RPC_CLIENT_NAME_SIZE 64
276e13b5493SBenjamin Coddington 
nfs_sysfs_link_rpc_client(struct nfs_server * server,struct rpc_clnt * clnt,const char * uniq)277e13b5493SBenjamin Coddington void nfs_sysfs_link_rpc_client(struct nfs_server *server,
278e13b5493SBenjamin Coddington 			struct rpc_clnt *clnt, const char *uniq)
279e13b5493SBenjamin Coddington {
280e13b5493SBenjamin Coddington 	char name[RPC_CLIENT_NAME_SIZE];
281e13b5493SBenjamin Coddington 	int ret;
282e13b5493SBenjamin Coddington 
283e13b5493SBenjamin Coddington 	strcpy(name, clnt->cl_program->name);
284e13b5493SBenjamin Coddington 	strcat(name, uniq ? uniq : "");
285e13b5493SBenjamin Coddington 	strcat(name, "_client");
286e13b5493SBenjamin Coddington 
287e13b5493SBenjamin Coddington 	ret = sysfs_create_link_nowarn(&server->kobj,
288e13b5493SBenjamin Coddington 						&clnt->cl_sysfs->kobject, name);
289e13b5493SBenjamin Coddington 	if (ret < 0)
290e13b5493SBenjamin Coddington 		pr_warn("NFS: can't create link to %s in sysfs (%d)\n",
291e13b5493SBenjamin Coddington 			name, ret);
292e13b5493SBenjamin Coddington }
293e13b5493SBenjamin Coddington EXPORT_SYMBOL_GPL(nfs_sysfs_link_rpc_client);
294e13b5493SBenjamin Coddington 
nfs_sysfs_sb_release(struct kobject * kobj)2951c725118SBenjamin Coddington static void nfs_sysfs_sb_release(struct kobject *kobj)
2961c725118SBenjamin Coddington {
2971c725118SBenjamin Coddington 	/* no-op: why? see lib/kobject.c kobject_cleanup() */
2981c725118SBenjamin Coddington }
2991c725118SBenjamin Coddington 
nfs_netns_server_namespace(const struct kobject * kobj)3001c725118SBenjamin Coddington static const void *nfs_netns_server_namespace(const struct kobject *kobj)
3011c725118SBenjamin Coddington {
3021c725118SBenjamin Coddington 	return container_of(kobj, struct nfs_server, kobj)->nfs_client->cl_net;
3031c725118SBenjamin Coddington }
3041c725118SBenjamin Coddington 
3051c725118SBenjamin Coddington static struct kobj_type nfs_sb_ktype = {
3061c725118SBenjamin Coddington 	.release = nfs_sysfs_sb_release,
3071c725118SBenjamin Coddington 	.sysfs_ops = &kobj_sysfs_ops,
3081c725118SBenjamin Coddington 	.namespace = nfs_netns_server_namespace,
3091c725118SBenjamin Coddington 	.child_ns_type = nfs_netns_object_child_ns_type,
3101c725118SBenjamin Coddington };
3111c725118SBenjamin Coddington 
nfs_sysfs_add_server(struct nfs_server * server)3121c725118SBenjamin Coddington void nfs_sysfs_add_server(struct nfs_server *server)
3131c725118SBenjamin Coddington {
3141c725118SBenjamin Coddington 	int ret;
3151c725118SBenjamin Coddington 
3161c725118SBenjamin Coddington 	ret = kobject_init_and_add(&server->kobj, &nfs_sb_ktype,
3171c725118SBenjamin Coddington 				&nfs_kset->kobj, "server-%d", server->s_sysfs_id);
318d9615d16SBenjamin Coddington 	if (ret < 0) {
3191c725118SBenjamin Coddington 		pr_warn("NFS: nfs sysfs add server-%d failed (%d)\n",
3201c725118SBenjamin Coddington 					server->s_sysfs_id, ret);
321d9615d16SBenjamin Coddington 		return;
322d9615d16SBenjamin Coddington 	}
323d9615d16SBenjamin Coddington 	ret = sysfs_create_file_ns(&server->kobj, &nfs_sysfs_attr_shutdown.attr,
324d9615d16SBenjamin Coddington 				nfs_netns_server_namespace(&server->kobj));
325d9615d16SBenjamin Coddington 	if (ret < 0)
326d9615d16SBenjamin Coddington 		pr_warn("NFS: sysfs_create_file_ns for server-%d failed (%d)\n",
327d9615d16SBenjamin Coddington 			server->s_sysfs_id, ret);
3281c725118SBenjamin Coddington }
3291c725118SBenjamin Coddington EXPORT_SYMBOL_GPL(nfs_sysfs_add_server);
3301c725118SBenjamin Coddington 
nfs_sysfs_move_server_to_sb(struct super_block * s)3311c725118SBenjamin Coddington void nfs_sysfs_move_server_to_sb(struct super_block *s)
3321c725118SBenjamin Coddington {
3331c725118SBenjamin Coddington 	struct nfs_server *server = s->s_fs_info;
3341c725118SBenjamin Coddington 	int ret;
3351c725118SBenjamin Coddington 
3361c725118SBenjamin Coddington 	ret = kobject_rename(&server->kobj, s->s_id);
3371c725118SBenjamin Coddington 	if (ret < 0)
3381c725118SBenjamin Coddington 		pr_warn("NFS: rename sysfs %s failed (%d)\n",
3391c725118SBenjamin Coddington 					server->kobj.name, ret);
3401c725118SBenjamin Coddington }
3411c725118SBenjamin Coddington 
nfs_sysfs_move_sb_to_server(struct nfs_server * server)3421c725118SBenjamin Coddington void nfs_sysfs_move_sb_to_server(struct nfs_server *server)
3431c725118SBenjamin Coddington {
3441c725118SBenjamin Coddington 	const char *s;
3451c725118SBenjamin Coddington 	int ret = -ENOMEM;
3461c725118SBenjamin Coddington 
3471c725118SBenjamin Coddington 	s = kasprintf(GFP_KERNEL, "server-%d", server->s_sysfs_id);
348*c3dd7de2SBenjamin Coddington 	if (s) {
3491c725118SBenjamin Coddington 		ret = kobject_rename(&server->kobj, s);
350*c3dd7de2SBenjamin Coddington 		kfree(s);
351*c3dd7de2SBenjamin Coddington 	}
3521c725118SBenjamin Coddington 	if (ret < 0)
3531c725118SBenjamin Coddington 		pr_warn("NFS: rename sysfs %s failed (%d)\n",
3541c725118SBenjamin Coddington 					server->kobj.name, ret);
3551c725118SBenjamin Coddington }
3561c725118SBenjamin Coddington 
3571c725118SBenjamin Coddington /* unlink, not dec-ref */
nfs_sysfs_remove_server(struct nfs_server * server)3581c725118SBenjamin Coddington void nfs_sysfs_remove_server(struct nfs_server *server)
3591c725118SBenjamin Coddington {
3601c725118SBenjamin Coddington 	kobject_del(&server->kobj);
3611c725118SBenjamin Coddington }
362