sys.c 17.2 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

S
Steven Whitehouse 已提交
99
	return snprintf(buf, PAGE_SIZE, "%u\n", frozen);
D
David Teigland 已提交
100 101 102 103
}

static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
S
Steven Whitehouse 已提交
104
	int error;
D
David Teigland 已提交
105 106 107
	int n = simple_strtol(buf, NULL, 0);

	if (!capable(CAP_SYS_ADMIN))
108
		return -EPERM;
D
David Teigland 已提交
109 110 111

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

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

S
Steven Whitehouse 已提交
126
	return len;
D
David Teigland 已提交
127 128 129 130 131
}

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

static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
	if (!capable(CAP_SYS_ADMIN))
138
		return -EPERM;
D
David Teigland 已提交
139 140 141 142

	if (simple_strtol(buf, NULL, 0) != 1)
		return -EINVAL;

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

D
David Teigland 已提交
145 146 147 148 149 150 151
	return len;
}

static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf,
				 size_t len)
{
	if (!capable(CAP_SYS_ADMIN))
152
		return -EPERM;
D
David Teigland 已提交
153 154 155 156

	if (simple_strtol(buf, NULL, 0) != 1)
		return -EINVAL;

157
	gfs2_statfs_sync(sdp->sd_vfs, 0);
D
David Teigland 已提交
158 159 160 161 162 163 164
	return len;
}

static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf,
				size_t len)
{
	if (!capable(CAP_SYS_ADMIN))
165
		return -EPERM;
D
David Teigland 已提交
166 167 168 169

	if (simple_strtol(buf, NULL, 0) != 1)
		return -EINVAL;

170
	gfs2_quota_sync(sdp->sd_vfs, 0);
D
David Teigland 已提交
171 172 173 174 175 176
	return len;
}

static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf,
					size_t len)
{
177
	struct kqid qid;
178
	int error;
179
	u32 id;
D
David Teigland 已提交
180 181

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

	id = simple_strtoul(buf, NULL, 0);

186 187 188 189 190
	qid = make_kqid(current_user_ns(), USRQUOTA, id);
	if (!qid_valid(qid))
		return -EINVAL;

	error = gfs2_quota_refresh(sdp, qid);
191
	return error ? error : len;
D
David Teigland 已提交
192 193 194 195 196
}

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

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

	id = simple_strtoul(buf, NULL, 0);

206 207 208 209 210
	qid = make_kqid(current_user_ns(), GRPQUOTA, id);
	if (!qid_valid(qid))
		return -EINVAL;

	error = gfs2_quota_refresh(sdp, qid);
211
	return error ? error : len;
D
David Teigland 已提交
212 213
}

214 215 216 217 218 219 220 221 222 223 224
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))
225
		return -EPERM;
226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242

	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;
243 244 245 246
	if (gltype == LM_TYPE_NONDISK && glnum == GFS2_TRANS_LOCK)
		glops = &gfs2_trans_glops;
	else
		glops = gfs2_glops_list[gltype];
247 248
	if (glops == NULL)
		return -EINVAL;
S
Steven Whitehouse 已提交
249
	if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags))
250
		fs_info(sdp, "demote interface used\n");
251 252 253 254 255 256 257 258
	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 已提交
259 260 261 262 263 264

#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);
265
GFS2_ATTR(uuid,                0444, uuid_show,     NULL);
D
David Teigland 已提交
266 267 268 269 270 271
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);
272
GFS2_ATTR(demote_rq,           0200, NULL,	    demote_rq_store);
D
David Teigland 已提交
273 274 275 276

static struct attribute *gfs2_attrs[] = {
	&gfs2_attr_id.attr,
	&gfs2_attr_fsname.attr,
277
	&gfs2_attr_uuid.attr,
D
David Teigland 已提交
278 279 280 281 282 283
	&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,
284
	&gfs2_attr_demote_rq.attr,
D
David Teigland 已提交
285 286 287
	NULL,
};

B
Bob Peterson 已提交
288 289 290 291 292 293 294
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 已提交
295
static struct kobj_type gfs2_ktype = {
B
Bob Peterson 已提交
296
	.release = gfs2_sbd_release,
D
David Teigland 已提交
297 298 299 300
	.default_attrs = gfs2_attrs,
	.sysfs_ops     = &gfs2_attr_ops,
};

301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317

/*
 * 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;

318
	if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags))
319 320 321 322 323 324 325 326 327 328 329 330 331 332
		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;
	ssize_t ret = len;
	int val;

	val = simple_strtol(buf, NULL, 0);

	if (val == 1)
333
		set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
334
	else if (val == 0) {
335
		clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags);
336 337 338 339 340 341 342 343
		smp_mb__after_clear_bit();
		gfs2_glock_thaw(sdp);
	} else {
		ret = -EINVAL;
	}
	return ret;
}

344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365
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)
{
	ssize_t ret = len;
	int val;

	val = simple_strtol(buf, NULL, 0);

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

366 367 368 369 370 371
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);
}

372 373 374 375 376 377 378 379
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;
380 381 382
	rv = wait_for_completion_killable(&sdp->sd_locking_init);
	if (rv)
		return rv;
383 384 385 386 387 388 389 390 391
	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;
392 393
	sdp->sd_lockstruct.ls_first = first;
	rv = 0;
394 395 396 397 398
out:
        spin_unlock(&sdp->sd_jindex_spin);
        return rv ? rv : len;
}

399 400 401
static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf)
{
	struct lm_lockstruct *ls = &sdp->sd_lockstruct;
402
	return sprintf(buf, "%d\n", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags));
403 404
}

405
int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid)
406 407
{
	struct gfs2_jdesc *jd;
408 409
	int rv;

410
	spin_lock(&sdp->sd_jindex_spin);
411 412 413 414
	rv = -EBUSY;
	if (sdp->sd_jdesc->jd_jid == jid)
		goto out;
	rv = -ENOENT;
415 416 417
	list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) {
		if (jd->jd_jid != jid)
			continue;
418
		rv = gfs2_recover_journal(jd, false);
419 420
		break;
	}
421
out:
422
	spin_unlock(&sdp->sd_jindex_spin);
423 424 425 426 427 428 429 430 431 432 433 434
	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;

435 436 437 438
	if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) {
		rv = -ESHUTDOWN;
		goto out;
	}
439

440 441
	rv = gfs2_recover_set(sdp, jid);
out:
442
	return rv ? rv : len;
443 444 445 446 447 448 449 450 451 452 453 454 455 456
}

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);
}

457 458
static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf)
{
459
	return sprintf(buf, "%d\n", sdp->sd_lockstruct.ls_jid);
460 461
}

462 463
static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len)
{
464
        int jid;
465 466
	int rv;

467
	rv = sscanf(buf, "%d", &jid);
468 469
	if (rv != 1)
		return -EINVAL;
470 471 472
	rv = wait_for_completion_killable(&sdp->sd_locking_init);
	if (rv)
		return rv;
473 474 475 476 477
	spin_lock(&sdp->sd_jindex_spin);
	rv = -EINVAL;
	if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL)
		goto out;
	rv = -EBUSY;
478
	if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0)
479
		goto out;
480 481 482
	rv = 0;
	if (sdp->sd_args.ar_spectator && jid > 0)
		rv = jid = -EINVAL;
483
	sdp->sd_lockstruct.ls_jid = jid;
484
	clear_bit(SDF_NOJOURNALID, &sdp->sd_flags);
485 486 487 488 489 490 491
	smp_mb__after_clear_bit();
	wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID);
out:
	spin_unlock(&sdp->sd_jindex_spin);
	return rv ? rv : len;
}

492
#define GDLM_ATTR(_name,_mode,_show,_store) \
493
static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store)
494

495 496
GDLM_ATTR(proto_name,		0444, proto_name_show,		NULL);
GDLM_ATTR(block,		0644, block_show,		block_store);
497
GDLM_ATTR(withdraw,		0644, wdack_show,		wdack_store);
498 499
GDLM_ATTR(jid,			0644, jid_show,			jid_store);
GDLM_ATTR(first,		0644, lkfirst_show,		lkfirst_store);
500 501 502 503
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);
504 505 506 507 508

static struct attribute *lock_module_attrs[] = {
	&gdlm_attr_proto_name.attr,
	&gdlm_attr_block.attr,
	&gdlm_attr_withdraw.attr,
509
	&gdlm_attr_jid.attr,
510 511 512 513 514
	&gdlm_attr_first.attr,
	&gdlm_attr_first_done.attr,
	&gdlm_attr_recover.attr,
	&gdlm_attr_recover_done.attr,
	&gdlm_attr_recover_status.attr,
515
	NULL,
D
David Teigland 已提交
516 517 518 519 520 521 522 523
};

/*
 * get and set struct gfs2_tune fields
 */

static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf)
{
524 525 526
	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 已提交
527 528 529 530 531 532 533 534 535
}

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))
536
		return -EPERM;
D
David Teigland 已提交
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554

	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;

	if (!capable(CAP_SYS_ADMIN))
555
		return -EPERM;
D
David Teigland 已提交
556 557 558 559 560 561 562 563 564 565 566 567 568

	x = simple_strtoul(buf, NULL, 0);

	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)                                        \
569
static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store)
D
David Teigland 已提交
570 571 572 573

#define TUNE_ATTR_2(name, store)                                              \
static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf)                   \
{                                                                             \
574
	return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name);      \
D
David Teigland 已提交
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
}                                                                             \
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,
603
	NULL,
D
David Teigland 已提交
604 605 606 607
};

static struct attribute_group tune_group = {
	.name = "tune",
608
	.attrs = tune_attrs,
D
David Teigland 已提交
609 610
};

611 612 613 614 615
static struct attribute_group lock_module_group = {
	.name = "lock_module",
	.attrs = lock_module_attrs,
};

D
David Teigland 已提交
616 617
int gfs2_sys_fs_add(struct gfs2_sbd *sdp)
{
618
	struct super_block *sb = sdp->sd_vfs;
D
David Teigland 已提交
619
	int error;
620 621 622
	char ro[20];
	char spectator[20];
	char *envp[] = { ro, spectator, NULL };
B
Bob Peterson 已提交
623
	int sysfs_frees_sdp = 0;
624 625 626

	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 已提交
627

628
	sdp->sd_kobj.kset = gfs2_kset;
629 630
	error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL,
				     "%s", sdp->sd_table_name);
D
David Teigland 已提交
631
	if (error)
B
Bob Peterson 已提交
632
		goto fail_reg;
D
David Teigland 已提交
633

B
Bob Peterson 已提交
634 635
	sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling
				function gfs2_sbd_release. */
D
David Teigland 已提交
636 637
	error = sysfs_create_group(&sdp->sd_kobj, &tune_group);
	if (error)
638
		goto fail_reg;
D
David Teigland 已提交
639

640 641 642 643
	error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group);
	if (error)
		goto fail_tune;

644 645 646 647 648 649
	error = sysfs_create_link(&sdp->sd_kobj,
				  &disk_to_dev(sb->s_bdev->bd_disk)->kobj,
				  "device");
	if (error)
		goto fail_lock_module;

650
	kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp);
D
David Teigland 已提交
651 652
	return 0;

653 654
fail_lock_module:
	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
655 656
fail_tune:
	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
657
fail_reg:
B
Bob Peterson 已提交
658
	free_percpu(sdp->sd_lkstats);
659
	fs_err(sdp, "error %d adding sysfs files", error);
B
Bob Peterson 已提交
660 661 662 663 664
	if (sysfs_frees_sdp)
		kobject_put(&sdp->sd_kobj);
	else
		kfree(sdp);
	sb->s_fs_info = NULL;
D
David Teigland 已提交
665 666 667 668 669
	return error;
}

void gfs2_sys_fs_del(struct gfs2_sbd *sdp)
{
670
	sysfs_remove_link(&sdp->sd_kobj, "device");
D
David Teigland 已提交
671
	sysfs_remove_group(&sdp->sd_kobj, &tune_group);
672
	sysfs_remove_group(&sdp->sd_kobj, &lock_module_group);
673
	kobject_put(&sdp->sd_kobj);
D
David Teigland 已提交
674 675
}

676 677 678 679
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);
680 681
	struct super_block *s = sdp->sd_vfs;
	const u8 *uuid = s->s_uuid;
682

683 684
	add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name);
	add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name);
685
	if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags))
686
		add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid);
687 688
	if (gfs2_uuid_valid(uuid))
		add_uevent_var(env, "UUID=%pUB", uuid);
689 690 691
	return 0;
}

692
static const struct kset_uevent_ops gfs2_uevent_ops = {
693 694 695
	.uevent = gfs2_uevent,
};

D
David Teigland 已提交
696 697
int gfs2_sys_init(void)
{
698
	gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj);
699 700 701
	if (!gfs2_kset)
		return -ENOMEM;
	return 0;
D
David Teigland 已提交
702 703 704 705
}

void gfs2_sys_uninit(void)
{
706
	kset_unregister(gfs2_kset);
D
David Teigland 已提交
707 708
}