sys.c 17.6 KB
Newer Older
D
David Teigland 已提交
1 2
/*
 * Copyright (C) Sistina Software, Inc.  1997-2003 All rights reserved.
3
 * Copyright (C) 2004-2006 Red Hat, Inc.  All rights reserved.
D
David Teigland 已提交
4 5 6
 *
 * This copyrighted material is made available to anyone wishing to use,
 * modify, copy, or redistribute it subject to the terms and conditions
7
 * of the GNU General Public License version 2.
D
David Teigland 已提交
8 9
 */

10 11
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

D
David Teigland 已提交
12 13 14 15 16 17 18
#include <linux/sched.h>
#include <linux/spinlock.h>
#include <linux/completion.h>
#include <linux/buffer_head.h>
#include <linux/module.h>
#include <linux/kobject.h>
#include <asm/uaccess.h>
19
#include <linux/gfs2_ondisk.h>
20
#include <linux/genhd.h>
D
David Teigland 已提交
21 22

#include "gfs2.h"
23
#include "incore.h"
D
David Teigland 已提交
24 25 26 27
#include "sys.h"
#include "super.h"
#include "glock.h"
#include "quota.h"
28
#include "util.h"
29
#include "glops.h"
30
#include "recovery.h"
D
David Teigland 已提交
31

32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
struct gfs2_attr {
	struct attribute attr;
	ssize_t (*show)(struct gfs2_sbd *, char *);
	ssize_t (*store)(struct gfs2_sbd *, const char *, size_t);
};

static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr,
			      char *buf)
{
	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
	return a->show ? a->show(sdp, buf) : 0;
}

static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr,
			       const char *buf, size_t len)
{
	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
	struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr);
	return a->store ? a->store(sdp, buf, len) : len;
}

54
static const struct sysfs_ops gfs2_attr_ops = {
55 56 57 58 59 60 61
	.show  = gfs2_attr_show,
	.store = gfs2_attr_store,
};


static struct kset *gfs2_kset;

D
David Teigland 已提交
62 63
static ssize_t id_show(struct gfs2_sbd *sdp, char *buf)
{
64 65
	return snprintf(buf, PAGE_SIZE, "%u:%u\n",
			MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev));
D
David Teigland 已提交
66 67 68 69
}

static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf)
{
70
	return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname);
D
David Teigland 已提交
71 72
}

73 74 75 76 77 78 79 80 81 82 83 84 85
static int gfs2_uuid_valid(const u8 *uuid)
{
	int i;

	for (i = 0; i < 16; i++) {
		if (uuid[i])
			return 1;
	}
	return 0;
}

static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf)
{
86 87
	struct super_block *s = sdp->sd_vfs;
	const u8 *uuid = s->s_uuid;
88 89 90
	buf[0] = '\0';
	if (!gfs2_uuid_valid(uuid))
		return 0;
91
	return snprintf(buf, PAGE_SIZE, "%pUB\n", uuid);
92 93
}

D
David Teigland 已提交
94 95
static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf)
{
S
Steven Whitehouse 已提交
96 97
	struct super_block *sb = sdp->sd_vfs;
	int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1;
D
David Teigland 已提交
98

A
alex chen 已提交
99
	return snprintf(buf, PAGE_SIZE, "%d\n", frozen);
D
David Teigland 已提交
100 101 102 103
}

static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
104 105 106 107 108
	int error, n;

	error = kstrtoint(buf, 0, &n);
	if (error)
		return error;
D
David Teigland 已提交
109 110

	if (!capable(CAP_SYS_ADMIN))
111
		return -EPERM;
D
David Teigland 已提交
112 113 114

	switch (n) {
	case 0:
S
Steven Whitehouse 已提交
115
		error = thaw_super(sdp->sd_vfs);
D
David Teigland 已提交
116 117
		break;
	case 1:
S
Steven Whitehouse 已提交
118
		error = freeze_super(sdp->sd_vfs);
D
David Teigland 已提交
119 120
		break;
	default:
S
Steven Whitehouse 已提交
121
		return -EINVAL;
D
David Teigland 已提交
122 123
	}

S
Steven Whitehouse 已提交
124
	if (error) {
D
David Teigland 已提交
125
		fs_warn(sdp, "freeze %d error %d", n, error);
S
Steven Whitehouse 已提交
126 127
		return error;
	}
D
David Teigland 已提交
128

S
Steven Whitehouse 已提交
129
	return len;
D
David Teigland 已提交
130 131 132 133 134
}

static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf)
{
	unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags);
135
	return snprintf(buf, PAGE_SIZE, "%u\n", b);
D
David Teigland 已提交
136 137 138 139
}

static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
140 141
	int error, val;

D
David Teigland 已提交
142
	if (!capable(CAP_SYS_ADMIN))
143
		return -EPERM;
D
David Teigland 已提交
144

145 146 147 148 149
	error = kstrtoint(buf, 0, &val);
	if (error)
		return error;

	if (val != 1)
D
David Teigland 已提交
150 151
		return -EINVAL;

152 153
	gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request\n");

D
David Teigland 已提交
154 155 156 157 158 159
	return len;
}

static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
				 size_t len)
{
160 161
	int error, val;

D
David Teigland 已提交
162
	if (!capable(CAP_SYS_ADMIN))
163
		return -EPERM;
D
David Teigland 已提交
164

165 166 167 168 169
	error = kstrtoint(buf, 0, &val);
	if (error)
		return error;

	if (val != 1)
D
David Teigland 已提交
170 171
		return -EINVAL;

172
	gfs2_statfs_sync(sdp->sd_vfs, 0);
D
David Teigland 已提交
173 174 175 176 177 178
	return len;
}

static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
				size_t len)
{
179 180
	int error, val;

D
David Teigland 已提交
181
	if (!capable(CAP_SYS_ADMIN))
182
		return -EPERM;
D
David Teigland 已提交
183

184 185 186 187 188
	error = kstrtoint(buf, 0, &val);
	if (error)
		return error;

	if (val != 1)
D
David Teigland 已提交
189 190
		return -EINVAL;

191
	gfs2_quota_sync(sdp->sd_vfs, 0);
D
David Teigland 已提交
192 193 194 195 196 197
	return len;
}

static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
					size_t len)
{
198
	struct kqid qid;
199
	int error;
200
	u32 id;
D
David Teigland 已提交
201 202

	if (!capable(CAP_SYS_ADMIN))
203
		return -EPERM;
D
David Teigland 已提交
204

205 206 207
	error = kstrtou32(buf, 0, &id);
	if (error)
		return error;
D
David Teigland 已提交
208

209 210 211 212 213
	qid = make_kqid(current_user_ns(), USRQUOTA, id);
	if (!qid_valid(qid))
		return -EINVAL;

	error = gfs2_quota_refresh(sdp, qid);
214
	return error ? error : len;
D
David Teigland 已提交
215 216 217 218 219
}

static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf,
					 size_t len)
{
220
	struct kqid qid;
221
	int error;
222
	u32 id;
D
David Teigland 已提交
223 224

	if (!capable(CAP_SYS_ADMIN))
225
		return -EPERM;
D
David Teigland 已提交
226

227 228 229
	error = kstrtou32(buf, 0, &id);
	if (error)
		return error;
D
David Teigland 已提交
230

231 232 233 234 235
	qid = make_kqid(current_user_ns(), GRPQUOTA, id);
	if (!qid_valid(qid))
		return -EINVAL;

	error = gfs2_quota_refresh(sdp, qid);
236
	return error ? error : len;
D
David Teigland 已提交
237 238
}

239 240 241 242 243 244 245 246 247 248 249
static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
	struct gfs2_glock *gl;
	const struct gfs2_glock_operations *glops;
	unsigned int glmode;
	unsigned int gltype;
	unsigned long long glnum;
	char mode[16];
	int rv;

	if (!capable(CAP_SYS_ADMIN))
250
		return -EPERM;
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267

	rv = sscanf(buf, "%u:%llu %15s", &gltype, &glnum,
		    mode);
	if (rv != 3)
		return -EINVAL;

	if (strcmp(mode, "EX") == 0)
		glmode = LM_ST_UNLOCKED;
	else if ((strcmp(mode, "CW") == 0) || (strcmp(mode, "DF") == 0))
		glmode = LM_ST_DEFERRED;
	else if ((strcmp(mode, "PR") == 0) || (strcmp(mode, "SH") == 0))
		glmode = LM_ST_SHARED;
	else
		return -EINVAL;

	if (gltype > LM_TYPE_JOURNAL)
		return -EINVAL;
268 269
	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK)
		glops = &gfs2_freeze_glops;
270 271
	else
		glops = gfs2_glops_list[gltype];
272 273
	if (glops == NULL)
		return -EINVAL;
S
Steven Whitehouse 已提交
274
	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
275
		fs_info(sdp, "demote interface used\n");
276 277 278 279 280 281 282 283
	rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl);
	if (rv)
		return rv;
	gfs2_glock_cb(gl, glmode);
	gfs2_glock_put(gl);
	return len;
}

D
David Teigland 已提交
284 285 286 287 288 289

#define GFS2_ATTR(name, mode, show, store) \
static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store)

GFS2_ATTR(id,                  0444, id_show,       NULL);
GFS2_ATTR(fsname,              0444, fsname_show,   NULL);
290
GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
D
David Teigland 已提交
291 292 293 294 295 296
GFS2_ATTR(freeze,              0644, freeze_show,   freeze_store);
GFS2_ATTR(withdraw,            0644, withdraw_show, withdraw_store);
GFS2_ATTR(statfs_sync,         0200, NULL,          statfs_sync_store);
GFS2_ATTR(quota_sync,          0200, NULL,          quota_sync_store);
GFS2_ATTR(quota_refresh_user,  0200, NULL,          quota_refresh_user_store);
GFS2_ATTR(quota_refresh_group, 0200, NULL,          quota_refresh_group_store);
297
GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
D
David Teigland 已提交
298 299 300 301

static struct attribute *gfs2_attrs[] = {
	&gfs2_attr_id.attr,
	&gfs2_attr_fsname.attr,
302
	&gfs2_attr_uuid.attr,
D
David Teigland 已提交
303 304 305 306 307 308
	&gfs2_attr_freeze.attr,
	&gfs2_attr_withdraw.attr,
	&gfs2_attr_statfs_sync.attr,
	&gfs2_attr_quota_sync.attr,
	&gfs2_attr_quota_refresh_user.attr,
	&gfs2_attr_quota_refresh_group.attr,
309
	&gfs2_attr_demote_rq.attr,
D
David Teigland 已提交
310 311 312
	NULL,
};

B
Bob Peterson 已提交
313 314 315 316 317 318 319
static void gfs2_sbd_release(struct kobject *kobj)
{
	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);

	kfree(sdp);
}

D
David Teigland 已提交
320
static struct kobj_type gfs2_ktype = {
B
Bob Peterson 已提交
321
	.release = gfs2_sbd_release,
D
David Teigland 已提交
322 323 324 325
	.default_attrs = gfs2_attrs,
	.sysfs_ops     = &gfs2_attr_ops,
};

326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342

/*
 * lock_module. Originally from lock_dlm
 */

static ssize_t proto_name_show(struct gfs2_sbd *sdp, char *buf)
{
	const struct lm_lockops *ops = sdp->sd_lockstruct.ls_ops;
	return sprintf(buf, "%s\n", ops->lm_proto_name);
}

static ssize_t block_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	ssize_t ret;
	int val = 0;

343
	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
344 345 346 347 348 349 350 351
		val = 1;
	ret = sprintf(buf, "%d\n", val);
	return ret;
}

static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
352
	int ret, val;
353

354 355 356
	ret = kstrtoint(buf, 0, &val);
	if (ret)
		return ret;
357 358

	if (val == 1)
359
		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
360
	else if (val == 0) {
361
		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
362
		smp_mb__after_atomic();
363 364
		gfs2_glock_thaw(sdp);
	} else {
365
		return -EINVAL;
366
	}
367
	return len;
368 369
}

370 371 372 373 374 375 376 377 378
static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf)
{
	int val = completion_done(&sdp->sd_wdack) ? 1 : 0;

	return sprintf(buf, "%d\n", val);
}

static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
379
	int ret, val;
380

381 382 383
	ret = kstrtoint(buf, 0, &val);
	if (ret)
		return ret;
384 385 386 387 388

	if ((val == 1) &&
	    !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm"))
		complete(&sdp->sd_wdack);
	else
389 390
		return -EINVAL;
	return len;
391 392
}

393 394 395 396 397 398
static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	return sprintf(buf, "%d\n", ls->ls_first);
}

399 400 401 402 403 404 405 406
static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
	unsigned first;
	int rv;

	rv = sscanf(buf, "%u", &first);
	if (rv != 1 || first > 1)
		return -EINVAL;
407 408 409
	rv = wait_for_completion_killable(&sdp->sd_locking_init);
	if (rv)
		return rv;
410 411 412 413 414 415 416 417 418
	spin_lock(&sdp->sd_jindex_spin);
	rv = -EBUSY;
	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
		goto out;
	rv = -EINVAL;
	if (sdp->sd_args.ar_spectator)
		goto out;
	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
		goto out;
419 420
	sdp->sd_lockstruct.ls_first = first;
	rv = 0;
421 422 423 424 425
out:
        spin_unlock(&sdp->sd_jindex_spin);
        return rv ? rv : len;
}

426 427 428
static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
429
	return sprintf(buf, "%d\n", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
430 431
}

432
int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
433 434
{
	struct gfs2_jdesc *jd;
435 436
	int rv;

437 438 439
	/* Wait for our primary journal to be initialized */
	wait_for_completion(&sdp->sd_journal_ready);

440
	spin_lock(&sdp->sd_jindex_spin);
441 442 443 444
	rv = -EBUSY;
	if (sdp->sd_jdesc->jd_jid == jid)
		goto out;
	rv = -ENOENT;
445 446 447
	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
		if (jd->jd_jid != jid)
			continue;
448
		rv = gfs2_recover_journal(jd, false);
449 450
		break;
	}
451
out:
452
	spin_unlock(&sdp->sd_jindex_spin);
453 454 455 456 457 458 459 460 461 462 463 464
	return rv;
}

static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
	unsigned jid;
	int rv;

	rv = sscanf(buf, "%u", &jid);
	if (rv != 1)
		return -EINVAL;

465 466 467 468
	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
		rv = -ESHUTDOWN;
		goto out;
	}
469

470 471
	rv = gfs2_recover_set(sdp, jid);
out:
472
	return rv ? rv : len;
473 474 475 476 477 478 479 480 481 482 483 484 485 486
}

static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	return sprintf(buf, "%d\n", ls->ls_recover_jid_done);
}

static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
	return sprintf(buf, "%d\n", ls->ls_recover_jid_status);
}

487 488
static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
{
489
	return sprintf(buf, "%d\n", sdp->sd_lockstruct.ls_jid);
490 491
}

492 493
static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
494
        int jid;
495 496
	int rv;

497
	rv = sscanf(buf, "%d", &jid);
498 499
	if (rv != 1)
		return -EINVAL;
500 501 502
	rv = wait_for_completion_killable(&sdp->sd_locking_init);
	if (rv)
		return rv;
503 504 505 506 507
	spin_lock(&sdp->sd_jindex_spin);
	rv = -EINVAL;
	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
		goto out;
	rv = -EBUSY;
508
	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
509
		goto out;
510 511 512
	rv = 0;
	if (sdp->sd_args.ar_spectator && jid > 0)
		rv = jid = -EINVAL;
513
	sdp->sd_lockstruct.ls_jid = jid;
514
	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
515
	smp_mb__after_atomic();
516 517 518 519 520 521
	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
out:
	spin_unlock(&sdp->sd_jindex_spin);
	return rv ? rv : len;
}

522
#define GDLM_ATTR(_name,_mode,_show,_store) \
523
static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
524

525 526
GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
GDLM_ATTR(block,		0644, block_show,		block_store);
527
GDLM_ATTR(withdraw,		0644, wdack_show,		wdack_store);
528 529
GDLM_ATTR(jid,			0644, jid_show,			jid_store);
GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
530 531 532 533
GDLM_ATTR(first_done,		0444, first_done_show,		NULL);
GDLM_ATTR(recover,		0600, NULL,			recover_store);
GDLM_ATTR(recover_done,		0444, recover_done_show,	NULL);
GDLM_ATTR(recover_status,	0444, recover_status_show,	NULL);
534 535 536 537 538

static struct attribute *lock_module_attrs[] = {
	&gdlm_attr_proto_name.attr,
	&gdlm_attr_block.attr,
	&gdlm_attr_withdraw.attr,
539
	&gdlm_attr_jid.attr,
540 541 542 543 544
	&gdlm_attr_first.attr,
	&gdlm_attr_first_done.attr,
	&gdlm_attr_recover.attr,
	&gdlm_attr_recover_done.attr,
	&gdlm_attr_recover_status.attr,
545
	NULL,
D
David Teigland 已提交
546 547 548 549 550 551 552 553
};

/*
 * get and set struct gfs2_tune fields
 */

static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf)
{
554 555 556
	return snprintf(buf, PAGE_SIZE, "%u %u\n",
			sdp->sd_tune.gt_quota_scale_num,
			sdp->sd_tune.gt_quota_scale_den);
D
David Teigland 已提交
557 558 559 560 561 562 563 564 565
}

static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf,
				 size_t len)
{
	struct gfs2_tune *gt = &sdp->sd_tune;
	unsigned int x, y;

	if (!capable(CAP_SYS_ADMIN))
566
		return -EPERM;
D
David Teigland 已提交
567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582

	if (sscanf(buf, "%u %u", &x, &y) != 2 || !y)
		return -EINVAL;

	spin_lock(&gt->gt_spin);
	gt->gt_quota_scale_num = x;
	gt->gt_quota_scale_den = y;
	spin_unlock(&gt->gt_spin);
	return len;
}

static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field,
			int check_zero, const char *buf, size_t len)
{
	struct gfs2_tune *gt = &sdp->sd_tune;
	unsigned int x;
583
	int error;
D
David Teigland 已提交
584 585

	if (!capable(CAP_SYS_ADMIN))
586
		return -EPERM;
D
David Teigland 已提交
587

588 589 590
	error = kstrtouint(buf, 0, &x);
	if (error)
		return error;
D
David Teigland 已提交
591 592 593 594 595 596 597 598 599 600 601

	if (check_zero && !x)
		return -EINVAL;

	spin_lock(&gt->gt_spin);
	*field = x;
	spin_unlock(&gt->gt_spin);
	return len;
}

#define TUNE_ATTR_3(name, show, store)                                        \
602
static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
D
David Teigland 已提交
603 604 605 606

#define TUNE_ATTR_2(name, store)                                              \
static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
{                                                                             \
607
	return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name);      \
D
David Teigland 已提交
608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635
}                                                                             \
TUNE_ATTR_3(name, name##_show, store)

#define TUNE_ATTR(name, check_zero)                                           \
static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\
{                                                                             \
	return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len);  \
}                                                                             \
TUNE_ATTR_2(name, name##_store)

TUNE_ATTR(quota_warn_period, 0);
TUNE_ATTR(quota_quantum, 0);
TUNE_ATTR(max_readahead, 0);
TUNE_ATTR(complain_secs, 0);
TUNE_ATTR(statfs_slow, 0);
TUNE_ATTR(new_files_jdata, 0);
TUNE_ATTR(statfs_quantum, 1);
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store);

static struct attribute *tune_attrs[] = {
	&tune_attr_quota_warn_period.attr,
	&tune_attr_quota_quantum.attr,
	&tune_attr_max_readahead.attr,
	&tune_attr_complain_secs.attr,
	&tune_attr_statfs_slow.attr,
	&tune_attr_statfs_quantum.attr,
	&tune_attr_quota_scale.attr,
	&tune_attr_new_files_jdata.attr,
636
	NULL,
D
David Teigland 已提交
637 638 639 640
};

static struct attribute_group tune_group = {
	.name = "tune",
641
	.attrs = tune_attrs,
D
David Teigland 已提交
642 643
};

644 645 646 647 648
static struct attribute_group lock_module_group = {
	.name = "lock_module",
	.attrs = lock_module_attrs,
};

D
David Teigland 已提交
649 650
int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
{
651
	struct super_block *sb = sdp->sd_vfs;
D
David Teigland 已提交
652
	int error;
653 654 655
	char ro[20];
	char spectator[20];
	char *envp[] = { ro, spectator, NULL };
B
Bob Peterson 已提交
656
	int sysfs_frees_sdp = 0;
657 658 659

	sprintf(ro, "RDONLY=%d", (sb->s_flags & MS_RDONLY) ? 1 : 0);
	sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0);
D
David Teigland 已提交
660

661
	sdp->sd_kobj.kset = gfs2_kset;
662 663
	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
				     "%s", sdp->sd_table_name);
D
David Teigland 已提交
664
	if (error)
B
Bob Peterson 已提交
665
		goto fail_reg;
D
David Teigland 已提交
666

B
Bob Peterson 已提交
667 668
	sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling
				function gfs2_sbd_release. */
D
David Teigland 已提交
669 670
	error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
	if (error)
671
		goto fail_reg;
D
David Teigland 已提交
672

673 674 675 676
	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
	if (error)
		goto fail_tune;

677 678 679 680 681 682
	error = sysfs_create_link(&sdp->sd_kobj,
				  &disk_to_dev(sb->s_bdev->bd_disk)->kobj,
				  "device");
	if (error)
		goto fail_lock_module;

683
	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
D
David Teigland 已提交
684 685
	return 0;

686 687
fail_lock_module:
	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
688 689
fail_tune:
	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
690
fail_reg:
B
Bob Peterson 已提交
691
	free_percpu(sdp->sd_lkstats);
692
	fs_err(sdp, "error %d adding sysfs files", error);
B
Bob Peterson 已提交
693 694 695 696 697
	if (sysfs_frees_sdp)
		kobject_put(&sdp->sd_kobj);
	else
		kfree(sdp);
	sb->s_fs_info = NULL;
D
David Teigland 已提交
698 699 700 701 702
	return error;
}

void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
{
703
	sysfs_remove_link(&sdp->sd_kobj, "device");
D
David Teigland 已提交
704
	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
705
	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
706
	kobject_put(&sdp->sd_kobj);
D
David Teigland 已提交
707 708
}

709 710 711 712
static int gfs2_uevent(struct kset *kset, struct kobject *kobj,
		       struct kobj_uevent_env *env)
{
	struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj);
713 714
	struct super_block *s = sdp->sd_vfs;
	const u8 *uuid = s->s_uuid;
715

716 717
	add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
	add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
718
	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
719
		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
720 721
	if (gfs2_uuid_valid(uuid))
		add_uevent_var(env, "UUID=%pUB", uuid);
722 723 724
	return 0;
}

725
static const struct kset_uevent_ops gfs2_uevent_ops = {
726 727 728
	.uevent = gfs2_uevent,
};

D
David Teigland 已提交
729 730
int gfs2_sys_init(void)
{
731
	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
732 733 734
	if (!gfs2_kset)
		return -ENOMEM;
	return 0;
D
David Teigland 已提交
735 736 737 738
}

void gfs2_sys_uninit(void)
{
739
	kset_unregister(gfs2_kset);
D
David Teigland 已提交
740 741
}