xref: /OK3568_Linux_fs/kernel/fs/gfs2/sys.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
4*4882a593Smuzhiyun  * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
5*4882a593Smuzhiyun  */
6*4882a593Smuzhiyun 
7*4882a593Smuzhiyun #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
8*4882a593Smuzhiyun 
9*4882a593Smuzhiyun #include <linux/sched.h>
10*4882a593Smuzhiyun #include <linux/cred.h>
11*4882a593Smuzhiyun #include <linux/spinlock.h>
12*4882a593Smuzhiyun #include <linux/completion.h>
13*4882a593Smuzhiyun #include <linux/buffer_head.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/kobject.h>
16*4882a593Smuzhiyun #include <linux/uaccess.h>
17*4882a593Smuzhiyun #include <linux/gfs2_ondisk.h>
18*4882a593Smuzhiyun #include <linux/genhd.h>
19*4882a593Smuzhiyun 
20*4882a593Smuzhiyun #include "gfs2.h"
21*4882a593Smuzhiyun #include "incore.h"
22*4882a593Smuzhiyun #include "sys.h"
23*4882a593Smuzhiyun #include "super.h"
24*4882a593Smuzhiyun #include "glock.h"
25*4882a593Smuzhiyun #include "quota.h"
26*4882a593Smuzhiyun #include "util.h"
27*4882a593Smuzhiyun #include "glops.h"
28*4882a593Smuzhiyun #include "recovery.h"
29*4882a593Smuzhiyun 
30*4882a593Smuzhiyun struct gfs2_attr {
31*4882a593Smuzhiyun 	struct attribute attr;
32*4882a593Smuzhiyun 	ssize_t (*show)(struct gfs2_sbd *, char *);
33*4882a593Smuzhiyun 	ssize_t (*store)(struct gfs2_sbd *, const char *, size_t);
34*4882a593Smuzhiyun };
35*4882a593Smuzhiyun 
gfs2_attr_show(struct kobject * kobj,struct attribute * attr,char * buf)36*4882a593Smuzhiyun static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr,
37*4882a593Smuzhiyun 			      char *buf)
38*4882a593Smuzhiyun {
39*4882a593Smuzhiyun 	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
40*4882a593Smuzhiyun 	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
41*4882a593Smuzhiyun 	return a->show ? a->show(sdp, buf) : 0;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun 
gfs2_attr_store(struct kobject * kobj,struct attribute * attr,const char * buf,size_t len)44*4882a593Smuzhiyun static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr,
45*4882a593Smuzhiyun 			       const char *buf, size_t len)
46*4882a593Smuzhiyun {
47*4882a593Smuzhiyun 	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
48*4882a593Smuzhiyun 	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
49*4882a593Smuzhiyun 	return a->store ? a->store(sdp, buf, len) : len;
50*4882a593Smuzhiyun }
51*4882a593Smuzhiyun 
52*4882a593Smuzhiyun static const struct sysfs_ops gfs2_attr_ops = {
53*4882a593Smuzhiyun 	.show  = gfs2_attr_show,
54*4882a593Smuzhiyun 	.store = gfs2_attr_store,
55*4882a593Smuzhiyun };
56*4882a593Smuzhiyun 
57*4882a593Smuzhiyun 
58*4882a593Smuzhiyun static struct kset *gfs2_kset;
59*4882a593Smuzhiyun 
id_show(struct gfs2_sbd * sdp,char * buf)60*4882a593Smuzhiyun static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
61*4882a593Smuzhiyun {
62*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%u:%u\n",
63*4882a593Smuzhiyun 			MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev));
64*4882a593Smuzhiyun }
65*4882a593Smuzhiyun 
fsname_show(struct gfs2_sbd * sdp,char * buf)66*4882a593Smuzhiyun static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf)
67*4882a593Smuzhiyun {
68*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname);
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
uuid_show(struct gfs2_sbd * sdp,char * buf)71*4882a593Smuzhiyun static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf)
72*4882a593Smuzhiyun {
73*4882a593Smuzhiyun 	struct super_block *s = sdp->sd_vfs;
74*4882a593Smuzhiyun 
75*4882a593Smuzhiyun 	buf[0] = '\0';
76*4882a593Smuzhiyun 	if (uuid_is_null(&s->s_uuid))
77*4882a593Smuzhiyun 		return 0;
78*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%pUB\n", &s->s_uuid);
79*4882a593Smuzhiyun }
80*4882a593Smuzhiyun 
freeze_show(struct gfs2_sbd * sdp,char * buf)81*4882a593Smuzhiyun static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
82*4882a593Smuzhiyun {
83*4882a593Smuzhiyun 	struct super_block *sb = sdp->sd_vfs;
84*4882a593Smuzhiyun 	int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1;
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%d\n", frozen);
87*4882a593Smuzhiyun }
88*4882a593Smuzhiyun 
freeze_store(struct gfs2_sbd * sdp,const char * buf,size_t len)89*4882a593Smuzhiyun static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
90*4882a593Smuzhiyun {
91*4882a593Smuzhiyun 	int error, n;
92*4882a593Smuzhiyun 
93*4882a593Smuzhiyun 	error = kstrtoint(buf, 0, &n);
94*4882a593Smuzhiyun 	if (error)
95*4882a593Smuzhiyun 		return error;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
98*4882a593Smuzhiyun 		return -EPERM;
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	switch (n) {
101*4882a593Smuzhiyun 	case 0:
102*4882a593Smuzhiyun 		error = thaw_super(sdp->sd_vfs);
103*4882a593Smuzhiyun 		break;
104*4882a593Smuzhiyun 	case 1:
105*4882a593Smuzhiyun 		error = freeze_super(sdp->sd_vfs);
106*4882a593Smuzhiyun 		break;
107*4882a593Smuzhiyun 	default:
108*4882a593Smuzhiyun 		return -EINVAL;
109*4882a593Smuzhiyun 	}
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	if (error) {
112*4882a593Smuzhiyun 		fs_warn(sdp, "freeze %d error %d\n", n, error);
113*4882a593Smuzhiyun 		return error;
114*4882a593Smuzhiyun 	}
115*4882a593Smuzhiyun 
116*4882a593Smuzhiyun 	return len;
117*4882a593Smuzhiyun }
118*4882a593Smuzhiyun 
withdraw_show(struct gfs2_sbd * sdp,char * buf)119*4882a593Smuzhiyun static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf)
120*4882a593Smuzhiyun {
121*4882a593Smuzhiyun 	unsigned int b = gfs2_withdrawn(sdp);
122*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%u\n", b);
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
withdraw_store(struct gfs2_sbd * sdp,const char * buf,size_t len)125*4882a593Smuzhiyun static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
126*4882a593Smuzhiyun {
127*4882a593Smuzhiyun 	int error, val;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
130*4882a593Smuzhiyun 		return -EPERM;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	error = kstrtoint(buf, 0, &val);
133*4882a593Smuzhiyun 	if (error)
134*4882a593Smuzhiyun 		return error;
135*4882a593Smuzhiyun 
136*4882a593Smuzhiyun 	if (val != 1)
137*4882a593Smuzhiyun 		return -EINVAL;
138*4882a593Smuzhiyun 
139*4882a593Smuzhiyun 	gfs2_lm(sdp, "withdrawing from cluster at user's request\n");
140*4882a593Smuzhiyun 	gfs2_withdraw(sdp);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	return len;
143*4882a593Smuzhiyun }
144*4882a593Smuzhiyun 
statfs_sync_store(struct gfs2_sbd * sdp,const char * buf,size_t len)145*4882a593Smuzhiyun static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
146*4882a593Smuzhiyun 				 size_t len)
147*4882a593Smuzhiyun {
148*4882a593Smuzhiyun 	int error, val;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
151*4882a593Smuzhiyun 		return -EPERM;
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun 	error = kstrtoint(buf, 0, &val);
154*4882a593Smuzhiyun 	if (error)
155*4882a593Smuzhiyun 		return error;
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	if (val != 1)
158*4882a593Smuzhiyun 		return -EINVAL;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	gfs2_statfs_sync(sdp->sd_vfs, 0);
161*4882a593Smuzhiyun 	return len;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun 
quota_sync_store(struct gfs2_sbd * sdp,const char * buf,size_t len)164*4882a593Smuzhiyun static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
165*4882a593Smuzhiyun 				size_t len)
166*4882a593Smuzhiyun {
167*4882a593Smuzhiyun 	int error, val;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
170*4882a593Smuzhiyun 		return -EPERM;
171*4882a593Smuzhiyun 
172*4882a593Smuzhiyun 	error = kstrtoint(buf, 0, &val);
173*4882a593Smuzhiyun 	if (error)
174*4882a593Smuzhiyun 		return error;
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun 	if (val != 1)
177*4882a593Smuzhiyun 		return -EINVAL;
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun 	gfs2_quota_sync(sdp->sd_vfs, 0);
180*4882a593Smuzhiyun 	return len;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun 
quota_refresh_user_store(struct gfs2_sbd * sdp,const char * buf,size_t len)183*4882a593Smuzhiyun static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
184*4882a593Smuzhiyun 					size_t len)
185*4882a593Smuzhiyun {
186*4882a593Smuzhiyun 	struct kqid qid;
187*4882a593Smuzhiyun 	int error;
188*4882a593Smuzhiyun 	u32 id;
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
191*4882a593Smuzhiyun 		return -EPERM;
192*4882a593Smuzhiyun 
193*4882a593Smuzhiyun 	error = kstrtou32(buf, 0, &id);
194*4882a593Smuzhiyun 	if (error)
195*4882a593Smuzhiyun 		return error;
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun 	qid = make_kqid(current_user_ns(), USRQUOTA, id);
198*4882a593Smuzhiyun 	if (!qid_valid(qid))
199*4882a593Smuzhiyun 		return -EINVAL;
200*4882a593Smuzhiyun 
201*4882a593Smuzhiyun 	error = gfs2_quota_refresh(sdp, qid);
202*4882a593Smuzhiyun 	return error ? error : len;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun 
quota_refresh_group_store(struct gfs2_sbd * sdp,const char * buf,size_t len)205*4882a593Smuzhiyun static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
206*4882a593Smuzhiyun 					 size_t len)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun 	struct kqid qid;
209*4882a593Smuzhiyun 	int error;
210*4882a593Smuzhiyun 	u32 id;
211*4882a593Smuzhiyun 
212*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
213*4882a593Smuzhiyun 		return -EPERM;
214*4882a593Smuzhiyun 
215*4882a593Smuzhiyun 	error = kstrtou32(buf, 0, &id);
216*4882a593Smuzhiyun 	if (error)
217*4882a593Smuzhiyun 		return error;
218*4882a593Smuzhiyun 
219*4882a593Smuzhiyun 	qid = make_kqid(current_user_ns(), GRPQUOTA, id);
220*4882a593Smuzhiyun 	if (!qid_valid(qid))
221*4882a593Smuzhiyun 		return -EINVAL;
222*4882a593Smuzhiyun 
223*4882a593Smuzhiyun 	error = gfs2_quota_refresh(sdp, qid);
224*4882a593Smuzhiyun 	return error ? error : len;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun 
demote_rq_store(struct gfs2_sbd * sdp,const char * buf,size_t len)227*4882a593Smuzhiyun static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun 	struct gfs2_glock *gl;
230*4882a593Smuzhiyun 	const struct gfs2_glock_operations *glops;
231*4882a593Smuzhiyun 	unsigned int glmode;
232*4882a593Smuzhiyun 	unsigned int gltype;
233*4882a593Smuzhiyun 	unsigned long long glnum;
234*4882a593Smuzhiyun 	char mode[16];
235*4882a593Smuzhiyun 	int rv;
236*4882a593Smuzhiyun 
237*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
238*4882a593Smuzhiyun 		return -EPERM;
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun 	rv = sscanf(buf, "%u:%llu %15s", &gltype, &glnum,
241*4882a593Smuzhiyun 		    mode);
242*4882a593Smuzhiyun 	if (rv != 3)
243*4882a593Smuzhiyun 		return -EINVAL;
244*4882a593Smuzhiyun 
245*4882a593Smuzhiyun 	if (strcmp(mode, "EX") == 0)
246*4882a593Smuzhiyun 		glmode = LM_ST_UNLOCKED;
247*4882a593Smuzhiyun 	else if ((strcmp(mode, "CW") == 0) || (strcmp(mode, "DF") == 0))
248*4882a593Smuzhiyun 		glmode = LM_ST_DEFERRED;
249*4882a593Smuzhiyun 	else if ((strcmp(mode, "PR") == 0) || (strcmp(mode, "SH") == 0))
250*4882a593Smuzhiyun 		glmode = LM_ST_SHARED;
251*4882a593Smuzhiyun 	else
252*4882a593Smuzhiyun 		return -EINVAL;
253*4882a593Smuzhiyun 
254*4882a593Smuzhiyun 	if (gltype > LM_TYPE_JOURNAL)
255*4882a593Smuzhiyun 		return -EINVAL;
256*4882a593Smuzhiyun 	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK)
257*4882a593Smuzhiyun 		glops = &gfs2_freeze_glops;
258*4882a593Smuzhiyun 	else
259*4882a593Smuzhiyun 		glops = gfs2_glops_list[gltype];
260*4882a593Smuzhiyun 	if (glops == NULL)
261*4882a593Smuzhiyun 		return -EINVAL;
262*4882a593Smuzhiyun 	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
263*4882a593Smuzhiyun 		fs_info(sdp, "demote interface used\n");
264*4882a593Smuzhiyun 	rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl);
265*4882a593Smuzhiyun 	if (rv)
266*4882a593Smuzhiyun 		return rv;
267*4882a593Smuzhiyun 	gfs2_glock_cb(gl, glmode);
268*4882a593Smuzhiyun 	gfs2_glock_put(gl);
269*4882a593Smuzhiyun 	return len;
270*4882a593Smuzhiyun }
271*4882a593Smuzhiyun 
272*4882a593Smuzhiyun 
273*4882a593Smuzhiyun #define GFS2_ATTR(name, mode, show, store) \
274*4882a593Smuzhiyun static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store)
275*4882a593Smuzhiyun 
276*4882a593Smuzhiyun GFS2_ATTR(id,                  0444, id_show,       NULL);
277*4882a593Smuzhiyun GFS2_ATTR(fsname,              0444, fsname_show,   NULL);
278*4882a593Smuzhiyun GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
279*4882a593Smuzhiyun GFS2_ATTR(freeze,              0644, freeze_show,   freeze_store);
280*4882a593Smuzhiyun GFS2_ATTR(withdraw,            0644, withdraw_show, withdraw_store);
281*4882a593Smuzhiyun GFS2_ATTR(statfs_sync,         0200, NULL,          statfs_sync_store);
282*4882a593Smuzhiyun GFS2_ATTR(quota_sync,          0200, NULL,          quota_sync_store);
283*4882a593Smuzhiyun GFS2_ATTR(quota_refresh_user,  0200, NULL,          quota_refresh_user_store);
284*4882a593Smuzhiyun GFS2_ATTR(quota_refresh_group, 0200, NULL,          quota_refresh_group_store);
285*4882a593Smuzhiyun GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
286*4882a593Smuzhiyun 
287*4882a593Smuzhiyun static struct attribute *gfs2_attrs[] = {
288*4882a593Smuzhiyun 	&gfs2_attr_id.attr,
289*4882a593Smuzhiyun 	&gfs2_attr_fsname.attr,
290*4882a593Smuzhiyun 	&gfs2_attr_uuid.attr,
291*4882a593Smuzhiyun 	&gfs2_attr_freeze.attr,
292*4882a593Smuzhiyun 	&gfs2_attr_withdraw.attr,
293*4882a593Smuzhiyun 	&gfs2_attr_statfs_sync.attr,
294*4882a593Smuzhiyun 	&gfs2_attr_quota_sync.attr,
295*4882a593Smuzhiyun 	&gfs2_attr_quota_refresh_user.attr,
296*4882a593Smuzhiyun 	&gfs2_attr_quota_refresh_group.attr,
297*4882a593Smuzhiyun 	&gfs2_attr_demote_rq.attr,
298*4882a593Smuzhiyun 	NULL,
299*4882a593Smuzhiyun };
300*4882a593Smuzhiyun ATTRIBUTE_GROUPS(gfs2);
301*4882a593Smuzhiyun 
gfs2_sbd_release(struct kobject * kobj)302*4882a593Smuzhiyun static void gfs2_sbd_release(struct kobject *kobj)
303*4882a593Smuzhiyun {
304*4882a593Smuzhiyun 	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
305*4882a593Smuzhiyun 
306*4882a593Smuzhiyun 	complete(&sdp->sd_kobj_unregister);
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun static struct kobj_type gfs2_ktype = {
310*4882a593Smuzhiyun 	.release = gfs2_sbd_release,
311*4882a593Smuzhiyun 	.default_groups = gfs2_groups,
312*4882a593Smuzhiyun 	.sysfs_ops     = &gfs2_attr_ops,
313*4882a593Smuzhiyun };
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun /*
317*4882a593Smuzhiyun  * lock_module. Originally from lock_dlm
318*4882a593Smuzhiyun  */
319*4882a593Smuzhiyun 
proto_name_show(struct gfs2_sbd * sdp,char * buf)320*4882a593Smuzhiyun static ssize_t proto_name_show(struct gfs2_sbd *sdp, char *buf)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun 	const struct lm_lockops *ops = sdp->sd_lockstruct.ls_ops;
323*4882a593Smuzhiyun 	return sprintf(buf, "%s\n", ops->lm_proto_name);
324*4882a593Smuzhiyun }
325*4882a593Smuzhiyun 
block_show(struct gfs2_sbd * sdp,char * buf)326*4882a593Smuzhiyun static ssize_t block_show(struct gfs2_sbd *sdp, char *buf)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
329*4882a593Smuzhiyun 	ssize_t ret;
330*4882a593Smuzhiyun 	int val = 0;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
333*4882a593Smuzhiyun 		val = 1;
334*4882a593Smuzhiyun 	ret = sprintf(buf, "%d\n", val);
335*4882a593Smuzhiyun 	return ret;
336*4882a593Smuzhiyun }
337*4882a593Smuzhiyun 
block_store(struct gfs2_sbd * sdp,const char * buf,size_t len)338*4882a593Smuzhiyun static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
341*4882a593Smuzhiyun 	int ret, val;
342*4882a593Smuzhiyun 
343*4882a593Smuzhiyun 	ret = kstrtoint(buf, 0, &val);
344*4882a593Smuzhiyun 	if (ret)
345*4882a593Smuzhiyun 		return ret;
346*4882a593Smuzhiyun 
347*4882a593Smuzhiyun 	if (val == 1)
348*4882a593Smuzhiyun 		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
349*4882a593Smuzhiyun 	else if (val == 0) {
350*4882a593Smuzhiyun 		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
351*4882a593Smuzhiyun 		smp_mb__after_atomic();
352*4882a593Smuzhiyun 		gfs2_glock_thaw(sdp);
353*4882a593Smuzhiyun 	} else {
354*4882a593Smuzhiyun 		return -EINVAL;
355*4882a593Smuzhiyun 	}
356*4882a593Smuzhiyun 	return len;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun 
wdack_show(struct gfs2_sbd * sdp,char * buf)359*4882a593Smuzhiyun static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf)
360*4882a593Smuzhiyun {
361*4882a593Smuzhiyun 	int val = completion_done(&sdp->sd_wdack) ? 1 : 0;
362*4882a593Smuzhiyun 
363*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", val);
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun 
wdack_store(struct gfs2_sbd * sdp,const char * buf,size_t len)366*4882a593Smuzhiyun static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun 	int ret, val;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	ret = kstrtoint(buf, 0, &val);
371*4882a593Smuzhiyun 	if (ret)
372*4882a593Smuzhiyun 		return ret;
373*4882a593Smuzhiyun 
374*4882a593Smuzhiyun 	if ((val == 1) &&
375*4882a593Smuzhiyun 	    !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
376*4882a593Smuzhiyun 		complete(&sdp->sd_wdack);
377*4882a593Smuzhiyun 	else
378*4882a593Smuzhiyun 		return -EINVAL;
379*4882a593Smuzhiyun 	return len;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun 
lkfirst_show(struct gfs2_sbd * sdp,char * buf)382*4882a593Smuzhiyun static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
383*4882a593Smuzhiyun {
384*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
385*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", ls->ls_first);
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun 
lkfirst_store(struct gfs2_sbd * sdp,const char * buf,size_t len)388*4882a593Smuzhiyun static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
389*4882a593Smuzhiyun {
390*4882a593Smuzhiyun 	unsigned first;
391*4882a593Smuzhiyun 	int rv;
392*4882a593Smuzhiyun 
393*4882a593Smuzhiyun 	rv = sscanf(buf, "%u", &first);
394*4882a593Smuzhiyun 	if (rv != 1 || first > 1)
395*4882a593Smuzhiyun 		return -EINVAL;
396*4882a593Smuzhiyun 	rv = wait_for_completion_killable(&sdp->sd_locking_init);
397*4882a593Smuzhiyun 	if (rv)
398*4882a593Smuzhiyun 		return rv;
399*4882a593Smuzhiyun 	spin_lock(&sdp->sd_jindex_spin);
400*4882a593Smuzhiyun 	rv = -EBUSY;
401*4882a593Smuzhiyun 	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
402*4882a593Smuzhiyun 		goto out;
403*4882a593Smuzhiyun 	rv = -EINVAL;
404*4882a593Smuzhiyun 	if (sdp->sd_args.ar_spectator)
405*4882a593Smuzhiyun 		goto out;
406*4882a593Smuzhiyun 	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
407*4882a593Smuzhiyun 		goto out;
408*4882a593Smuzhiyun 	sdp->sd_lockstruct.ls_first = first;
409*4882a593Smuzhiyun 	rv = 0;
410*4882a593Smuzhiyun out:
411*4882a593Smuzhiyun         spin_unlock(&sdp->sd_jindex_spin);
412*4882a593Smuzhiyun         return rv ? rv : len;
413*4882a593Smuzhiyun }
414*4882a593Smuzhiyun 
first_done_show(struct gfs2_sbd * sdp,char * buf)415*4882a593Smuzhiyun static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
416*4882a593Smuzhiyun {
417*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
418*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun 
gfs2_recover_set(struct gfs2_sbd * sdp,unsigned jid)421*4882a593Smuzhiyun int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
422*4882a593Smuzhiyun {
423*4882a593Smuzhiyun 	struct gfs2_jdesc *jd;
424*4882a593Smuzhiyun 	int rv;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	/* Wait for our primary journal to be initialized */
427*4882a593Smuzhiyun 	wait_for_completion(&sdp->sd_journal_ready);
428*4882a593Smuzhiyun 
429*4882a593Smuzhiyun 	spin_lock(&sdp->sd_jindex_spin);
430*4882a593Smuzhiyun 	rv = -EBUSY;
431*4882a593Smuzhiyun 	/**
432*4882a593Smuzhiyun 	 * If we're a spectator, we use journal0, but it's not really ours.
433*4882a593Smuzhiyun 	 * So we need to wait for its recovery too. If we skip it we'd never
434*4882a593Smuzhiyun 	 * queue work to the recovery workqueue, and so its completion would
435*4882a593Smuzhiyun 	 * never clear the DFL_BLOCK_LOCKS flag, so all our locks would
436*4882a593Smuzhiyun 	 * permanently stop working.
437*4882a593Smuzhiyun 	 */
438*4882a593Smuzhiyun 	if (!sdp->sd_jdesc)
439*4882a593Smuzhiyun 		goto out;
440*4882a593Smuzhiyun 	if (sdp->sd_jdesc->jd_jid == jid && !sdp->sd_args.ar_spectator)
441*4882a593Smuzhiyun 		goto out;
442*4882a593Smuzhiyun 	rv = -ENOENT;
443*4882a593Smuzhiyun 	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
444*4882a593Smuzhiyun 		if (jd->jd_jid != jid && !sdp->sd_args.ar_spectator)
445*4882a593Smuzhiyun 			continue;
446*4882a593Smuzhiyun 		rv = gfs2_recover_journal(jd, false);
447*4882a593Smuzhiyun 		break;
448*4882a593Smuzhiyun 	}
449*4882a593Smuzhiyun out:
450*4882a593Smuzhiyun 	spin_unlock(&sdp->sd_jindex_spin);
451*4882a593Smuzhiyun 	return rv;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
recover_store(struct gfs2_sbd * sdp,const char * buf,size_t len)454*4882a593Smuzhiyun static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
455*4882a593Smuzhiyun {
456*4882a593Smuzhiyun 	unsigned jid;
457*4882a593Smuzhiyun 	int rv;
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun 	rv = sscanf(buf, "%u", &jid);
460*4882a593Smuzhiyun 	if (rv != 1)
461*4882a593Smuzhiyun 		return -EINVAL;
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun 	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
464*4882a593Smuzhiyun 		rv = -ESHUTDOWN;
465*4882a593Smuzhiyun 		goto out;
466*4882a593Smuzhiyun 	}
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	rv = gfs2_recover_set(sdp, jid);
469*4882a593Smuzhiyun out:
470*4882a593Smuzhiyun 	return rv ? rv : len;
471*4882a593Smuzhiyun }
472*4882a593Smuzhiyun 
recover_done_show(struct gfs2_sbd * sdp,char * buf)473*4882a593Smuzhiyun static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf)
474*4882a593Smuzhiyun {
475*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
476*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", ls->ls_recover_jid_done);
477*4882a593Smuzhiyun }
478*4882a593Smuzhiyun 
recover_status_show(struct gfs2_sbd * sdp,char * buf)479*4882a593Smuzhiyun static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf)
480*4882a593Smuzhiyun {
481*4882a593Smuzhiyun 	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
482*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", ls->ls_recover_jid_status);
483*4882a593Smuzhiyun }
484*4882a593Smuzhiyun 
jid_show(struct gfs2_sbd * sdp,char * buf)485*4882a593Smuzhiyun static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
486*4882a593Smuzhiyun {
487*4882a593Smuzhiyun 	return sprintf(buf, "%d\n", sdp->sd_lockstruct.ls_jid);
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun 
jid_store(struct gfs2_sbd * sdp,const char * buf,size_t len)490*4882a593Smuzhiyun static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
491*4882a593Smuzhiyun {
492*4882a593Smuzhiyun         int jid;
493*4882a593Smuzhiyun 	int rv;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	rv = sscanf(buf, "%d", &jid);
496*4882a593Smuzhiyun 	if (rv != 1)
497*4882a593Smuzhiyun 		return -EINVAL;
498*4882a593Smuzhiyun 	rv = wait_for_completion_killable(&sdp->sd_locking_init);
499*4882a593Smuzhiyun 	if (rv)
500*4882a593Smuzhiyun 		return rv;
501*4882a593Smuzhiyun 	spin_lock(&sdp->sd_jindex_spin);
502*4882a593Smuzhiyun 	rv = -EINVAL;
503*4882a593Smuzhiyun 	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
504*4882a593Smuzhiyun 		goto out;
505*4882a593Smuzhiyun 	rv = -EBUSY;
506*4882a593Smuzhiyun 	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
507*4882a593Smuzhiyun 		goto out;
508*4882a593Smuzhiyun 	rv = 0;
509*4882a593Smuzhiyun 	if (sdp->sd_args.ar_spectator && jid > 0)
510*4882a593Smuzhiyun 		rv = jid = -EINVAL;
511*4882a593Smuzhiyun 	sdp->sd_lockstruct.ls_jid = jid;
512*4882a593Smuzhiyun 	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
513*4882a593Smuzhiyun 	smp_mb__after_atomic();
514*4882a593Smuzhiyun 	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
515*4882a593Smuzhiyun out:
516*4882a593Smuzhiyun 	spin_unlock(&sdp->sd_jindex_spin);
517*4882a593Smuzhiyun 	return rv ? rv : len;
518*4882a593Smuzhiyun }
519*4882a593Smuzhiyun 
520*4882a593Smuzhiyun #define GDLM_ATTR(_name,_mode,_show,_store) \
521*4882a593Smuzhiyun static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
522*4882a593Smuzhiyun 
523*4882a593Smuzhiyun GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
524*4882a593Smuzhiyun GDLM_ATTR(block,		0644, block_show,		block_store);
525*4882a593Smuzhiyun GDLM_ATTR(withdraw,		0644, wdack_show,		wdack_store);
526*4882a593Smuzhiyun GDLM_ATTR(jid,			0644, jid_show,			jid_store);
527*4882a593Smuzhiyun GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
528*4882a593Smuzhiyun GDLM_ATTR(first_done,		0444, first_done_show,		NULL);
529*4882a593Smuzhiyun GDLM_ATTR(recover,		0600, NULL,			recover_store);
530*4882a593Smuzhiyun GDLM_ATTR(recover_done,		0444, recover_done_show,	NULL);
531*4882a593Smuzhiyun GDLM_ATTR(recover_status,	0444, recover_status_show,	NULL);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun static struct attribute *lock_module_attrs[] = {
534*4882a593Smuzhiyun 	&gdlm_attr_proto_name.attr,
535*4882a593Smuzhiyun 	&gdlm_attr_block.attr,
536*4882a593Smuzhiyun 	&gdlm_attr_withdraw.attr,
537*4882a593Smuzhiyun 	&gdlm_attr_jid.attr,
538*4882a593Smuzhiyun 	&gdlm_attr_first.attr,
539*4882a593Smuzhiyun 	&gdlm_attr_first_done.attr,
540*4882a593Smuzhiyun 	&gdlm_attr_recover.attr,
541*4882a593Smuzhiyun 	&gdlm_attr_recover_done.attr,
542*4882a593Smuzhiyun 	&gdlm_attr_recover_status.attr,
543*4882a593Smuzhiyun 	NULL,
544*4882a593Smuzhiyun };
545*4882a593Smuzhiyun 
546*4882a593Smuzhiyun /*
547*4882a593Smuzhiyun  * get and set struct gfs2_tune fields
548*4882a593Smuzhiyun  */
549*4882a593Smuzhiyun 
quota_scale_show(struct gfs2_sbd * sdp,char * buf)550*4882a593Smuzhiyun static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf)
551*4882a593Smuzhiyun {
552*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%u %u\n",
553*4882a593Smuzhiyun 			sdp->sd_tune.gt_quota_scale_num,
554*4882a593Smuzhiyun 			sdp->sd_tune.gt_quota_scale_den);
555*4882a593Smuzhiyun }
556*4882a593Smuzhiyun 
quota_scale_store(struct gfs2_sbd * sdp,const char * buf,size_t len)557*4882a593Smuzhiyun static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf,
558*4882a593Smuzhiyun 				 size_t len)
559*4882a593Smuzhiyun {
560*4882a593Smuzhiyun 	struct gfs2_tune *gt = &sdp->sd_tune;
561*4882a593Smuzhiyun 	unsigned int x, y;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
564*4882a593Smuzhiyun 		return -EPERM;
565*4882a593Smuzhiyun 
566*4882a593Smuzhiyun 	if (sscanf(buf, "%u %u", &x, &y) != 2 || !y)
567*4882a593Smuzhiyun 		return -EINVAL;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	spin_lock(&gt->gt_spin);
570*4882a593Smuzhiyun 	gt->gt_quota_scale_num = x;
571*4882a593Smuzhiyun 	gt->gt_quota_scale_den = y;
572*4882a593Smuzhiyun 	spin_unlock(&gt->gt_spin);
573*4882a593Smuzhiyun 	return len;
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun 
tune_set(struct gfs2_sbd * sdp,unsigned int * field,int check_zero,const char * buf,size_t len)576*4882a593Smuzhiyun static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field,
577*4882a593Smuzhiyun 			int check_zero, const char *buf, size_t len)
578*4882a593Smuzhiyun {
579*4882a593Smuzhiyun 	struct gfs2_tune *gt = &sdp->sd_tune;
580*4882a593Smuzhiyun 	unsigned int x;
581*4882a593Smuzhiyun 	int error;
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun 	if (!capable(CAP_SYS_ADMIN))
584*4882a593Smuzhiyun 		return -EPERM;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	error = kstrtouint(buf, 0, &x);
587*4882a593Smuzhiyun 	if (error)
588*4882a593Smuzhiyun 		return error;
589*4882a593Smuzhiyun 
590*4882a593Smuzhiyun 	if (check_zero && !x)
591*4882a593Smuzhiyun 		return -EINVAL;
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun 	spin_lock(&gt->gt_spin);
594*4882a593Smuzhiyun 	*field = x;
595*4882a593Smuzhiyun 	spin_unlock(&gt->gt_spin);
596*4882a593Smuzhiyun 	return len;
597*4882a593Smuzhiyun }
598*4882a593Smuzhiyun 
599*4882a593Smuzhiyun #define TUNE_ATTR_3(name, show, store)                                        \
600*4882a593Smuzhiyun static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
601*4882a593Smuzhiyun 
602*4882a593Smuzhiyun #define TUNE_ATTR_2(name, store)                                              \
603*4882a593Smuzhiyun static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
604*4882a593Smuzhiyun {                                                                             \
605*4882a593Smuzhiyun 	return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name);      \
606*4882a593Smuzhiyun }                                                                             \
607*4882a593Smuzhiyun TUNE_ATTR_3(name, name##_show, store)
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun #define TUNE_ATTR(name, check_zero)                                           \
610*4882a593Smuzhiyun static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\
611*4882a593Smuzhiyun {                                                                             \
612*4882a593Smuzhiyun 	return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len);  \
613*4882a593Smuzhiyun }                                                                             \
614*4882a593Smuzhiyun TUNE_ATTR_2(name, name##_store)
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun TUNE_ATTR(quota_warn_period, 0);
617*4882a593Smuzhiyun TUNE_ATTR(quota_quantum, 0);
618*4882a593Smuzhiyun TUNE_ATTR(max_readahead, 0);
619*4882a593Smuzhiyun TUNE_ATTR(complain_secs, 0);
620*4882a593Smuzhiyun TUNE_ATTR(statfs_slow, 0);
621*4882a593Smuzhiyun TUNE_ATTR(new_files_jdata, 0);
622*4882a593Smuzhiyun TUNE_ATTR(statfs_quantum, 1);
623*4882a593Smuzhiyun TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun static struct attribute *tune_attrs[] = {
626*4882a593Smuzhiyun 	&tune_attr_quota_warn_period.attr,
627*4882a593Smuzhiyun 	&tune_attr_quota_quantum.attr,
628*4882a593Smuzhiyun 	&tune_attr_max_readahead.attr,
629*4882a593Smuzhiyun 	&tune_attr_complain_secs.attr,
630*4882a593Smuzhiyun 	&tune_attr_statfs_slow.attr,
631*4882a593Smuzhiyun 	&tune_attr_statfs_quantum.attr,
632*4882a593Smuzhiyun 	&tune_attr_quota_scale.attr,
633*4882a593Smuzhiyun 	&tune_attr_new_files_jdata.attr,
634*4882a593Smuzhiyun 	NULL,
635*4882a593Smuzhiyun };
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun static const struct attribute_group tune_group = {
638*4882a593Smuzhiyun 	.name = "tune",
639*4882a593Smuzhiyun 	.attrs = tune_attrs,
640*4882a593Smuzhiyun };
641*4882a593Smuzhiyun 
642*4882a593Smuzhiyun static const struct attribute_group lock_module_group = {
643*4882a593Smuzhiyun 	.name = "lock_module",
644*4882a593Smuzhiyun 	.attrs = lock_module_attrs,
645*4882a593Smuzhiyun };
646*4882a593Smuzhiyun 
gfs2_sys_fs_add(struct gfs2_sbd * sdp)647*4882a593Smuzhiyun int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun 	struct super_block *sb = sdp->sd_vfs;
650*4882a593Smuzhiyun 	int error;
651*4882a593Smuzhiyun 	char ro[20];
652*4882a593Smuzhiyun 	char spectator[20];
653*4882a593Smuzhiyun 	char *envp[] = { ro, spectator, NULL };
654*4882a593Smuzhiyun 
655*4882a593Smuzhiyun 	sprintf(ro, "RDONLY=%d", sb_rdonly(sb));
656*4882a593Smuzhiyun 	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
657*4882a593Smuzhiyun 
658*4882a593Smuzhiyun 	init_completion(&sdp->sd_kobj_unregister);
659*4882a593Smuzhiyun 	sdp->sd_kobj.kset = gfs2_kset;
660*4882a593Smuzhiyun 	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
661*4882a593Smuzhiyun 				     "%s", sdp->sd_table_name);
662*4882a593Smuzhiyun 	if (error)
663*4882a593Smuzhiyun 		goto fail_reg;
664*4882a593Smuzhiyun 
665*4882a593Smuzhiyun 	error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
666*4882a593Smuzhiyun 	if (error)
667*4882a593Smuzhiyun 		goto fail_reg;
668*4882a593Smuzhiyun 
669*4882a593Smuzhiyun 	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
670*4882a593Smuzhiyun 	if (error)
671*4882a593Smuzhiyun 		goto fail_tune;
672*4882a593Smuzhiyun 
673*4882a593Smuzhiyun 	error = sysfs_create_link(&sdp->sd_kobj,
674*4882a593Smuzhiyun 				  &disk_to_dev(sb->s_bdev->bd_disk)->kobj,
675*4882a593Smuzhiyun 				  "device");
676*4882a593Smuzhiyun 	if (error)
677*4882a593Smuzhiyun 		goto fail_lock_module;
678*4882a593Smuzhiyun 
679*4882a593Smuzhiyun 	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
680*4882a593Smuzhiyun 	return 0;
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun fail_lock_module:
683*4882a593Smuzhiyun 	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
684*4882a593Smuzhiyun fail_tune:
685*4882a593Smuzhiyun 	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
686*4882a593Smuzhiyun fail_reg:
687*4882a593Smuzhiyun 	fs_err(sdp, "error %d adding sysfs files\n", error);
688*4882a593Smuzhiyun 	kobject_put(&sdp->sd_kobj);
689*4882a593Smuzhiyun 	wait_for_completion(&sdp->sd_kobj_unregister);
690*4882a593Smuzhiyun 	sb->s_fs_info = NULL;
691*4882a593Smuzhiyun 	return error;
692*4882a593Smuzhiyun }
693*4882a593Smuzhiyun 
gfs2_sys_fs_del(struct gfs2_sbd * sdp)694*4882a593Smuzhiyun void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
695*4882a593Smuzhiyun {
696*4882a593Smuzhiyun 	sysfs_remove_link(&sdp->sd_kobj, "device");
697*4882a593Smuzhiyun 	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
698*4882a593Smuzhiyun 	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
699*4882a593Smuzhiyun 	kobject_put(&sdp->sd_kobj);
700*4882a593Smuzhiyun 	wait_for_completion(&sdp->sd_kobj_unregister);
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun 
gfs2_uevent(struct kset * kset,struct kobject * kobj,struct kobj_uevent_env * env)703*4882a593Smuzhiyun static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
704*4882a593Smuzhiyun 		       struct kobj_uevent_env *env)
705*4882a593Smuzhiyun {
706*4882a593Smuzhiyun 	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
707*4882a593Smuzhiyun 	struct super_block *s = sdp->sd_vfs;
708*4882a593Smuzhiyun 
709*4882a593Smuzhiyun 	add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
710*4882a593Smuzhiyun 	add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
711*4882a593Smuzhiyun 	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
712*4882a593Smuzhiyun 		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
713*4882a593Smuzhiyun 	if (!uuid_is_null(&s->s_uuid))
714*4882a593Smuzhiyun 		add_uevent_var(env, "UUID=%pUB", &s->s_uuid);
715*4882a593Smuzhiyun 	return 0;
716*4882a593Smuzhiyun }
717*4882a593Smuzhiyun 
718*4882a593Smuzhiyun static const struct kset_uevent_ops gfs2_uevent_ops = {
719*4882a593Smuzhiyun 	.uevent = gfs2_uevent,
720*4882a593Smuzhiyun };
721*4882a593Smuzhiyun 
gfs2_sys_init(void)722*4882a593Smuzhiyun int gfs2_sys_init(void)
723*4882a593Smuzhiyun {
724*4882a593Smuzhiyun 	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
725*4882a593Smuzhiyun 	if (!gfs2_kset)
726*4882a593Smuzhiyun 		return -ENOMEM;
727*4882a593Smuzhiyun 	return 0;
728*4882a593Smuzhiyun }
729*4882a593Smuzhiyun 
gfs2_sys_uninit(void)730*4882a593Smuzhiyun void gfs2_sys_uninit(void)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun 	kset_unregister(gfs2_kset);
733*4882a593Smuzhiyun }
734*4882a593Smuzhiyun 
735