1b3b94faaSDavid Teigland /* 2b3b94faaSDavid Teigland * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. 33a8a9a10SSteven Whitehouse * Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. 4b3b94faaSDavid Teigland * 5b3b94faaSDavid Teigland * This copyrighted material is made available to anyone wishing to use, 6b3b94faaSDavid Teigland * modify, copy, or redistribute it subject to the terms and conditions 7e9fc2aa0SSteven Whitehouse * of the GNU General Public License version 2. 8b3b94faaSDavid Teigland */ 9b3b94faaSDavid Teigland 10d77d1b58SJoe Perches #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11d77d1b58SJoe Perches 12b3b94faaSDavid Teigland #include <linux/sched.h> 135b825c3aSIngo Molnar #include <linux/cred.h> 14b3b94faaSDavid Teigland #include <linux/spinlock.h> 15b3b94faaSDavid Teigland #include <linux/completion.h> 16b3b94faaSDavid Teigland #include <linux/buffer_head.h> 17b3b94faaSDavid Teigland #include <linux/module.h> 18b3b94faaSDavid Teigland #include <linux/kobject.h> 197c0f6ba6SLinus Torvalds #include <linux/uaccess.h> 20f057f6cdSSteven Whitehouse #include <linux/gfs2_ondisk.h> 2131e54b01SSteven Whitehouse #include <linux/genhd.h> 22b3b94faaSDavid Teigland 23b3b94faaSDavid Teigland #include "gfs2.h" 245c676f6dSSteven Whitehouse #include "incore.h" 25b3b94faaSDavid Teigland #include "sys.h" 26b3b94faaSDavid Teigland #include "super.h" 27b3b94faaSDavid Teigland #include "glock.h" 28b3b94faaSDavid Teigland #include "quota.h" 295c676f6dSSteven Whitehouse #include "util.h" 3064d576baSSteven Whitehouse #include "glops.h" 316ecd7c2dSTejun Heo #include "recovery.h" 32b3b94faaSDavid Teigland 3348c2b613SSteven Whitehouse struct gfs2_attr { 3448c2b613SSteven Whitehouse struct attribute attr; 3548c2b613SSteven Whitehouse ssize_t (*show)(struct gfs2_sbd *, char *); 3648c2b613SSteven Whitehouse ssize_t (*store)(struct gfs2_sbd *, const char *, size_t); 3748c2b613SSteven Whitehouse }; 3848c2b613SSteven Whitehouse 3948c2b613SSteven Whitehouse static ssize_t gfs2_attr_show(struct kobject *kobj, struct attribute *attr, 4048c2b613SSteven Whitehouse char *buf) 4148c2b613SSteven Whitehouse { 4248c2b613SSteven Whitehouse struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); 4348c2b613SSteven Whitehouse struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); 4448c2b613SSteven Whitehouse return a->show ? a->show(sdp, buf) : 0; 4548c2b613SSteven Whitehouse } 4648c2b613SSteven Whitehouse 4748c2b613SSteven Whitehouse static ssize_t gfs2_attr_store(struct kobject *kobj, struct attribute *attr, 4848c2b613SSteven Whitehouse const char *buf, size_t len) 4948c2b613SSteven Whitehouse { 5048c2b613SSteven Whitehouse struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); 5148c2b613SSteven Whitehouse struct gfs2_attr *a = container_of(attr, struct gfs2_attr, attr); 5248c2b613SSteven Whitehouse return a->store ? a->store(sdp, buf, len) : len; 5348c2b613SSteven Whitehouse } 5448c2b613SSteven Whitehouse 5552cf25d0SEmese Revfy static const struct sysfs_ops gfs2_attr_ops = { 5648c2b613SSteven Whitehouse .show = gfs2_attr_show, 5748c2b613SSteven Whitehouse .store = gfs2_attr_store, 5848c2b613SSteven Whitehouse }; 5948c2b613SSteven Whitehouse 6048c2b613SSteven Whitehouse 6148c2b613SSteven Whitehouse static struct kset *gfs2_kset; 6248c2b613SSteven Whitehouse 63b3b94faaSDavid Teigland static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) 64b3b94faaSDavid Teigland { 65c7227e46SBob Peterson return snprintf(buf, PAGE_SIZE, "%u:%u\n", 66c7227e46SBob Peterson MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); 67b3b94faaSDavid Teigland } 68b3b94faaSDavid Teigland 69b3b94faaSDavid Teigland static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) 70b3b94faaSDavid Teigland { 713204a6c0SDavid Teigland return snprintf(buf, PAGE_SIZE, "%s\n", sdp->sd_fsname); 72b3b94faaSDavid Teigland } 73b3b94faaSDavid Teigland 7402e3cc70SSteven Whitehouse static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf) 7502e3cc70SSteven Whitehouse { 7632e471efSSteven Whitehouse struct super_block *s = sdp->sd_vfs; 7785787090SChristoph Hellwig 7802e3cc70SSteven Whitehouse buf[0] = '\0'; 7985787090SChristoph Hellwig if (uuid_is_null(&s->s_uuid)) 8002e3cc70SSteven Whitehouse return 0; 8185787090SChristoph Hellwig return snprintf(buf, PAGE_SIZE, "%pUB\n", &s->s_uuid); 8202e3cc70SSteven Whitehouse } 8302e3cc70SSteven Whitehouse 84b3b94faaSDavid Teigland static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf) 85b3b94faaSDavid Teigland { 86d564053fSSteven Whitehouse struct super_block *sb = sdp->sd_vfs; 87d564053fSSteven Whitehouse int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1; 88b3b94faaSDavid Teigland 893566c964Salex chen return snprintf(buf, PAGE_SIZE, "%d\n", frozen); 90b3b94faaSDavid Teigland } 91b3b94faaSDavid Teigland 92b3b94faaSDavid Teigland static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 93b3b94faaSDavid Teigland { 94e50ead48SFabian Frederick int error, n; 95e50ead48SFabian Frederick 96e50ead48SFabian Frederick error = kstrtoint(buf, 0, &n); 97e50ead48SFabian Frederick if (error) 98e50ead48SFabian Frederick return error; 99b3b94faaSDavid Teigland 100b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 10141735818SZhao Hongjiang return -EPERM; 102b3b94faaSDavid Teigland 103b3b94faaSDavid Teigland switch (n) { 104b3b94faaSDavid Teigland case 0: 105d564053fSSteven Whitehouse error = thaw_super(sdp->sd_vfs); 106b3b94faaSDavid Teigland break; 107b3b94faaSDavid Teigland case 1: 108d564053fSSteven Whitehouse error = freeze_super(sdp->sd_vfs); 109b3b94faaSDavid Teigland break; 110b3b94faaSDavid Teigland default: 111d564053fSSteven Whitehouse return -EINVAL; 112b3b94faaSDavid Teigland } 113b3b94faaSDavid Teigland 114d564053fSSteven Whitehouse if (error) { 115*af38816eSAndreas Gruenbacher fs_warn(sdp, "freeze %d error %d\n", n, error); 116d564053fSSteven Whitehouse return error; 117d564053fSSteven Whitehouse } 118b3b94faaSDavid Teigland 119d564053fSSteven Whitehouse return len; 120b3b94faaSDavid Teigland } 121b3b94faaSDavid Teigland 122b3b94faaSDavid Teigland static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) 123b3b94faaSDavid Teigland { 124b3b94faaSDavid Teigland unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags); 1253204a6c0SDavid Teigland return snprintf(buf, PAGE_SIZE, "%u\n", b); 126b3b94faaSDavid Teigland } 127b3b94faaSDavid Teigland 128b3b94faaSDavid Teigland static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 129b3b94faaSDavid Teigland { 130e50ead48SFabian Frederick int error, val; 131e50ead48SFabian Frederick 132b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 13341735818SZhao Hongjiang return -EPERM; 134b3b94faaSDavid Teigland 135e50ead48SFabian Frederick error = kstrtoint(buf, 0, &val); 136e50ead48SFabian Frederick if (error) 137e50ead48SFabian Frederick return error; 138e50ead48SFabian Frederick 139e50ead48SFabian Frederick if (val != 1) 140b3b94faaSDavid Teigland return -EINVAL; 141b3b94faaSDavid Teigland 142cb94eb06SJoe Perches gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request\n"); 143cb94eb06SJoe Perches 144b3b94faaSDavid Teigland return len; 145b3b94faaSDavid Teigland } 146b3b94faaSDavid Teigland 147b3b94faaSDavid Teigland static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf, 148b3b94faaSDavid Teigland size_t len) 149b3b94faaSDavid Teigland { 150e50ead48SFabian Frederick int error, val; 151e50ead48SFabian Frederick 152b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 15341735818SZhao Hongjiang return -EPERM; 154b3b94faaSDavid Teigland 155e50ead48SFabian Frederick error = kstrtoint(buf, 0, &val); 156e50ead48SFabian Frederick if (error) 157e50ead48SFabian Frederick return error; 158e50ead48SFabian Frederick 159e50ead48SFabian Frederick if (val != 1) 160b3b94faaSDavid Teigland return -EINVAL; 161b3b94faaSDavid Teigland 1628c42d637SSteven Whitehouse gfs2_statfs_sync(sdp->sd_vfs, 0); 163b3b94faaSDavid Teigland return len; 164b3b94faaSDavid Teigland } 165b3b94faaSDavid Teigland 166b3b94faaSDavid Teigland static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, 167b3b94faaSDavid Teigland size_t len) 168b3b94faaSDavid Teigland { 169e50ead48SFabian Frederick int error, val; 170e50ead48SFabian Frederick 171b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 17241735818SZhao Hongjiang return -EPERM; 173b3b94faaSDavid Teigland 174e50ead48SFabian Frederick error = kstrtoint(buf, 0, &val); 175e50ead48SFabian Frederick if (error) 176e50ead48SFabian Frederick return error; 177e50ead48SFabian Frederick 178e50ead48SFabian Frederick if (val != 1) 179b3b94faaSDavid Teigland return -EINVAL; 180b3b94faaSDavid Teigland 181ceed1723SJan Kara gfs2_quota_sync(sdp->sd_vfs, 0); 182b3b94faaSDavid Teigland return len; 183b3b94faaSDavid Teigland } 184b3b94faaSDavid Teigland 185b3b94faaSDavid Teigland static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, 186b3b94faaSDavid Teigland size_t len) 187b3b94faaSDavid Teigland { 188ed87dabcSEric W. Biederman struct kqid qid; 189ea762338SSteven Whitehouse int error; 190cd915493SSteven Whitehouse u32 id; 191b3b94faaSDavid Teigland 192b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 19341735818SZhao Hongjiang return -EPERM; 194b3b94faaSDavid Teigland 195e50ead48SFabian Frederick error = kstrtou32(buf, 0, &id); 196e50ead48SFabian Frederick if (error) 197e50ead48SFabian Frederick return error; 198b3b94faaSDavid Teigland 199ed87dabcSEric W. Biederman qid = make_kqid(current_user_ns(), USRQUOTA, id); 200ed87dabcSEric W. Biederman if (!qid_valid(qid)) 201ed87dabcSEric W. Biederman return -EINVAL; 202ed87dabcSEric W. Biederman 203ed87dabcSEric W. Biederman error = gfs2_quota_refresh(sdp, qid); 204ea762338SSteven Whitehouse return error ? error : len; 205b3b94faaSDavid Teigland } 206b3b94faaSDavid Teigland 207b3b94faaSDavid Teigland static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, 208b3b94faaSDavid Teigland size_t len) 209b3b94faaSDavid Teigland { 210ed87dabcSEric W. Biederman struct kqid qid; 211ea762338SSteven Whitehouse int error; 212cd915493SSteven Whitehouse u32 id; 213b3b94faaSDavid Teigland 214b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 21541735818SZhao Hongjiang return -EPERM; 216b3b94faaSDavid Teigland 217e50ead48SFabian Frederick error = kstrtou32(buf, 0, &id); 218e50ead48SFabian Frederick if (error) 219e50ead48SFabian Frederick return error; 220b3b94faaSDavid Teigland 221ed87dabcSEric W. Biederman qid = make_kqid(current_user_ns(), GRPQUOTA, id); 222ed87dabcSEric W. Biederman if (!qid_valid(qid)) 223ed87dabcSEric W. Biederman return -EINVAL; 224ed87dabcSEric W. Biederman 225ed87dabcSEric W. Biederman error = gfs2_quota_refresh(sdp, qid); 226ea762338SSteven Whitehouse return error ? error : len; 227b3b94faaSDavid Teigland } 228b3b94faaSDavid Teigland 22964d576baSSteven Whitehouse static ssize_t demote_rq_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 23064d576baSSteven Whitehouse { 23164d576baSSteven Whitehouse struct gfs2_glock *gl; 23264d576baSSteven Whitehouse const struct gfs2_glock_operations *glops; 23364d576baSSteven Whitehouse unsigned int glmode; 23464d576baSSteven Whitehouse unsigned int gltype; 23564d576baSSteven Whitehouse unsigned long long glnum; 23664d576baSSteven Whitehouse char mode[16]; 23764d576baSSteven Whitehouse int rv; 23864d576baSSteven Whitehouse 23964d576baSSteven Whitehouse if (!capable(CAP_SYS_ADMIN)) 24041735818SZhao Hongjiang return -EPERM; 24164d576baSSteven Whitehouse 24264d576baSSteven Whitehouse rv = sscanf(buf, "%u:%llu %15s", &gltype, &glnum, 24364d576baSSteven Whitehouse mode); 24464d576baSSteven Whitehouse if (rv != 3) 24564d576baSSteven Whitehouse return -EINVAL; 24664d576baSSteven Whitehouse 24764d576baSSteven Whitehouse if (strcmp(mode, "EX") == 0) 24864d576baSSteven Whitehouse glmode = LM_ST_UNLOCKED; 24964d576baSSteven Whitehouse else if ((strcmp(mode, "CW") == 0) || (strcmp(mode, "DF") == 0)) 25064d576baSSteven Whitehouse glmode = LM_ST_DEFERRED; 25164d576baSSteven Whitehouse else if ((strcmp(mode, "PR") == 0) || (strcmp(mode, "SH") == 0)) 25264d576baSSteven Whitehouse glmode = LM_ST_SHARED; 25364d576baSSteven Whitehouse else 25464d576baSSteven Whitehouse return -EINVAL; 25564d576baSSteven Whitehouse 25664d576baSSteven Whitehouse if (gltype > LM_TYPE_JOURNAL) 25764d576baSSteven Whitehouse return -EINVAL; 25824972557SBenjamin Marzinski if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK) 25924972557SBenjamin Marzinski glops = &gfs2_freeze_glops; 26013466985SSteven Whitehouse else 26164d576baSSteven Whitehouse glops = gfs2_glops_list[gltype]; 26264d576baSSteven Whitehouse if (glops == NULL) 26364d576baSSteven Whitehouse return -EINVAL; 2646a99be5dSSteven Whitehouse if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags)) 265913a71d2SSteven Whitehouse fs_info(sdp, "demote interface used\n"); 26664d576baSSteven Whitehouse rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl); 26764d576baSSteven Whitehouse if (rv) 26864d576baSSteven Whitehouse return rv; 26964d576baSSteven Whitehouse gfs2_glock_cb(gl, glmode); 27064d576baSSteven Whitehouse gfs2_glock_put(gl); 27164d576baSSteven Whitehouse return len; 27264d576baSSteven Whitehouse } 27364d576baSSteven Whitehouse 274b3b94faaSDavid Teigland 275b3b94faaSDavid Teigland #define GFS2_ATTR(name, mode, show, store) \ 276b3b94faaSDavid Teigland static struct gfs2_attr gfs2_attr_##name = __ATTR(name, mode, show, store) 277b3b94faaSDavid Teigland 278b3b94faaSDavid Teigland GFS2_ATTR(id, 0444, id_show, NULL); 279b3b94faaSDavid Teigland GFS2_ATTR(fsname, 0444, fsname_show, NULL); 28002e3cc70SSteven Whitehouse GFS2_ATTR(uuid, 0444, uuid_show, NULL); 281b3b94faaSDavid Teigland GFS2_ATTR(freeze, 0644, freeze_show, freeze_store); 282b3b94faaSDavid Teigland GFS2_ATTR(withdraw, 0644, withdraw_show, withdraw_store); 283b3b94faaSDavid Teigland GFS2_ATTR(statfs_sync, 0200, NULL, statfs_sync_store); 284b3b94faaSDavid Teigland GFS2_ATTR(quota_sync, 0200, NULL, quota_sync_store); 285b3b94faaSDavid Teigland GFS2_ATTR(quota_refresh_user, 0200, NULL, quota_refresh_user_store); 286b3b94faaSDavid Teigland GFS2_ATTR(quota_refresh_group, 0200, NULL, quota_refresh_group_store); 28764d576baSSteven Whitehouse GFS2_ATTR(demote_rq, 0200, NULL, demote_rq_store); 288b3b94faaSDavid Teigland 289b3b94faaSDavid Teigland static struct attribute *gfs2_attrs[] = { 290b3b94faaSDavid Teigland &gfs2_attr_id.attr, 291b3b94faaSDavid Teigland &gfs2_attr_fsname.attr, 29202e3cc70SSteven Whitehouse &gfs2_attr_uuid.attr, 293b3b94faaSDavid Teigland &gfs2_attr_freeze.attr, 294b3b94faaSDavid Teigland &gfs2_attr_withdraw.attr, 295b3b94faaSDavid Teigland &gfs2_attr_statfs_sync.attr, 296b3b94faaSDavid Teigland &gfs2_attr_quota_sync.attr, 297b3b94faaSDavid Teigland &gfs2_attr_quota_refresh_user.attr, 298b3b94faaSDavid Teigland &gfs2_attr_quota_refresh_group.attr, 29964d576baSSteven Whitehouse &gfs2_attr_demote_rq.attr, 300b3b94faaSDavid Teigland NULL, 301b3b94faaSDavid Teigland }; 302b3b94faaSDavid Teigland 3030d515210SBob Peterson static void gfs2_sbd_release(struct kobject *kobj) 3040d515210SBob Peterson { 3050d515210SBob Peterson struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); 3060d515210SBob Peterson 3070d515210SBob Peterson kfree(sdp); 3080d515210SBob Peterson } 3090d515210SBob Peterson 310b3b94faaSDavid Teigland static struct kobj_type gfs2_ktype = { 3110d515210SBob Peterson .release = gfs2_sbd_release, 312b3b94faaSDavid Teigland .default_attrs = gfs2_attrs, 313b3b94faaSDavid Teigland .sysfs_ops = &gfs2_attr_ops, 314b3b94faaSDavid Teigland }; 315b3b94faaSDavid Teigland 316f057f6cdSSteven Whitehouse 317f057f6cdSSteven Whitehouse /* 318f057f6cdSSteven Whitehouse * lock_module. Originally from lock_dlm 319f057f6cdSSteven Whitehouse */ 320f057f6cdSSteven Whitehouse 321f057f6cdSSteven Whitehouse static ssize_t proto_name_show(struct gfs2_sbd *sdp, char *buf) 322f057f6cdSSteven Whitehouse { 323f057f6cdSSteven Whitehouse const struct lm_lockops *ops = sdp->sd_lockstruct.ls_ops; 324f057f6cdSSteven Whitehouse return sprintf(buf, "%s\n", ops->lm_proto_name); 325f057f6cdSSteven Whitehouse } 326f057f6cdSSteven Whitehouse 327f057f6cdSSteven Whitehouse static ssize_t block_show(struct gfs2_sbd *sdp, char *buf) 328f057f6cdSSteven Whitehouse { 329f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 330f057f6cdSSteven Whitehouse ssize_t ret; 331f057f6cdSSteven Whitehouse int val = 0; 332f057f6cdSSteven Whitehouse 333e0c2a9aaSDavid Teigland if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags)) 334f057f6cdSSteven Whitehouse val = 1; 335f057f6cdSSteven Whitehouse ret = sprintf(buf, "%d\n", val); 336f057f6cdSSteven Whitehouse return ret; 337f057f6cdSSteven Whitehouse } 338f057f6cdSSteven Whitehouse 339f057f6cdSSteven Whitehouse static ssize_t block_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 340f057f6cdSSteven Whitehouse { 341f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 342e50ead48SFabian Frederick int ret, val; 343f057f6cdSSteven Whitehouse 344e50ead48SFabian Frederick ret = kstrtoint(buf, 0, &val); 345e50ead48SFabian Frederick if (ret) 346e50ead48SFabian Frederick return ret; 347f057f6cdSSteven Whitehouse 348f057f6cdSSteven Whitehouse if (val == 1) 349e0c2a9aaSDavid Teigland set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags); 350f057f6cdSSteven Whitehouse else if (val == 0) { 351e0c2a9aaSDavid Teigland clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags); 3524e857c58SPeter Zijlstra smp_mb__after_atomic(); 353f057f6cdSSteven Whitehouse gfs2_glock_thaw(sdp); 354f057f6cdSSteven Whitehouse } else { 355e50ead48SFabian Frederick return -EINVAL; 356f057f6cdSSteven Whitehouse } 357e50ead48SFabian Frederick return len; 358f057f6cdSSteven Whitehouse } 359f057f6cdSSteven Whitehouse 360fd95e81cSSteven Whitehouse static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf) 361fd95e81cSSteven Whitehouse { 362fd95e81cSSteven Whitehouse int val = completion_done(&sdp->sd_wdack) ? 1 : 0; 363fd95e81cSSteven Whitehouse 364fd95e81cSSteven Whitehouse return sprintf(buf, "%d\n", val); 365fd95e81cSSteven Whitehouse } 366fd95e81cSSteven Whitehouse 367fd95e81cSSteven Whitehouse static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 368fd95e81cSSteven Whitehouse { 369e50ead48SFabian Frederick int ret, val; 370fd95e81cSSteven Whitehouse 371e50ead48SFabian Frederick ret = kstrtoint(buf, 0, &val); 372e50ead48SFabian Frederick if (ret) 373e50ead48SFabian Frederick return ret; 374fd95e81cSSteven Whitehouse 375fd95e81cSSteven Whitehouse if ((val == 1) && 376fd95e81cSSteven Whitehouse !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) 377fd95e81cSSteven Whitehouse complete(&sdp->sd_wdack); 378fd95e81cSSteven Whitehouse else 379e50ead48SFabian Frederick return -EINVAL; 380e50ead48SFabian Frederick return len; 381fd95e81cSSteven Whitehouse } 382fd95e81cSSteven Whitehouse 383f057f6cdSSteven Whitehouse static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) 384f057f6cdSSteven Whitehouse { 385f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 386f057f6cdSSteven Whitehouse return sprintf(buf, "%d\n", ls->ls_first); 387f057f6cdSSteven Whitehouse } 388f057f6cdSSteven Whitehouse 389ba6e9364SSteven Whitehouse static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 390ba6e9364SSteven Whitehouse { 391ba6e9364SSteven Whitehouse unsigned first; 392ba6e9364SSteven Whitehouse int rv; 393ba6e9364SSteven Whitehouse 394ba6e9364SSteven Whitehouse rv = sscanf(buf, "%u", &first); 395ba6e9364SSteven Whitehouse if (rv != 1 || first > 1) 396ba6e9364SSteven Whitehouse return -EINVAL; 3973942ae53SSteven Whitehouse rv = wait_for_completion_killable(&sdp->sd_locking_init); 3983942ae53SSteven Whitehouse if (rv) 3993942ae53SSteven Whitehouse return rv; 400ba6e9364SSteven Whitehouse spin_lock(&sdp->sd_jindex_spin); 401ba6e9364SSteven Whitehouse rv = -EBUSY; 402ba6e9364SSteven Whitehouse if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) 403ba6e9364SSteven Whitehouse goto out; 404ba6e9364SSteven Whitehouse rv = -EINVAL; 405ba6e9364SSteven Whitehouse if (sdp->sd_args.ar_spectator) 406ba6e9364SSteven Whitehouse goto out; 407ba6e9364SSteven Whitehouse if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) 408ba6e9364SSteven Whitehouse goto out; 409ba6e9364SSteven Whitehouse sdp->sd_lockstruct.ls_first = first; 410ba6e9364SSteven Whitehouse rv = 0; 411ba6e9364SSteven Whitehouse out: 412ba6e9364SSteven Whitehouse spin_unlock(&sdp->sd_jindex_spin); 413ba6e9364SSteven Whitehouse return rv ? rv : len; 414ba6e9364SSteven Whitehouse } 415ba6e9364SSteven Whitehouse 416f057f6cdSSteven Whitehouse static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) 417f057f6cdSSteven Whitehouse { 418f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 419e0c2a9aaSDavid Teigland return sprintf(buf, "%d\n", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags)); 420f057f6cdSSteven Whitehouse } 421f057f6cdSSteven Whitehouse 422e0c2a9aaSDavid Teigland int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid) 423f057f6cdSSteven Whitehouse { 424f057f6cdSSteven Whitehouse struct gfs2_jdesc *jd; 425fe64d517SSteven Whitehouse int rv; 426f057f6cdSSteven Whitehouse 4270e48e055SBob Peterson /* Wait for our primary journal to be initialized */ 4280e48e055SBob Peterson wait_for_completion(&sdp->sd_journal_ready); 4290e48e055SBob Peterson 430f057f6cdSSteven Whitehouse spin_lock(&sdp->sd_jindex_spin); 431fe64d517SSteven Whitehouse rv = -EBUSY; 432fe64d517SSteven Whitehouse if (sdp->sd_jdesc->jd_jid == jid) 433fe64d517SSteven Whitehouse goto out; 434fe64d517SSteven Whitehouse rv = -ENOENT; 435f057f6cdSSteven Whitehouse list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { 436f057f6cdSSteven Whitehouse if (jd->jd_jid != jid) 437f057f6cdSSteven Whitehouse continue; 4386ecd7c2dSTejun Heo rv = gfs2_recover_journal(jd, false); 439f057f6cdSSteven Whitehouse break; 440f057f6cdSSteven Whitehouse } 441fe64d517SSteven Whitehouse out: 442f057f6cdSSteven Whitehouse spin_unlock(&sdp->sd_jindex_spin); 443e0c2a9aaSDavid Teigland return rv; 444e0c2a9aaSDavid Teigland } 445e0c2a9aaSDavid Teigland 446e0c2a9aaSDavid Teigland static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 447e0c2a9aaSDavid Teigland { 448e0c2a9aaSDavid Teigland unsigned jid; 449e0c2a9aaSDavid Teigland int rv; 450e0c2a9aaSDavid Teigland 451e0c2a9aaSDavid Teigland rv = sscanf(buf, "%u", &jid); 452e0c2a9aaSDavid Teigland if (rv != 1) 453e0c2a9aaSDavid Teigland return -EINVAL; 454e0c2a9aaSDavid Teigland 4551a058f52SDavid Teigland if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) { 4561a058f52SDavid Teigland rv = -ESHUTDOWN; 4571a058f52SDavid Teigland goto out; 4581a058f52SDavid Teigland } 459e0c2a9aaSDavid Teigland 4601a058f52SDavid Teigland rv = gfs2_recover_set(sdp, jid); 4611a058f52SDavid Teigland out: 462fe64d517SSteven Whitehouse return rv ? rv : len; 463f057f6cdSSteven Whitehouse } 464f057f6cdSSteven Whitehouse 465f057f6cdSSteven Whitehouse static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf) 466f057f6cdSSteven Whitehouse { 467f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 468f057f6cdSSteven Whitehouse return sprintf(buf, "%d\n", ls->ls_recover_jid_done); 469f057f6cdSSteven Whitehouse } 470f057f6cdSSteven Whitehouse 471f057f6cdSSteven Whitehouse static ssize_t recover_status_show(struct gfs2_sbd *sdp, char *buf) 472f057f6cdSSteven Whitehouse { 473f057f6cdSSteven Whitehouse struct lm_lockstruct *ls = &sdp->sd_lockstruct; 474f057f6cdSSteven Whitehouse return sprintf(buf, "%d\n", ls->ls_recover_jid_status); 475f057f6cdSSteven Whitehouse } 476f057f6cdSSteven Whitehouse 477e1b28aabSSteven Whitehouse static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf) 478e1b28aabSSteven Whitehouse { 479feb47ca9SSteven Whitehouse return sprintf(buf, "%d\n", sdp->sd_lockstruct.ls_jid); 480e1b28aabSSteven Whitehouse } 481e1b28aabSSteven Whitehouse 482ba6e9364SSteven Whitehouse static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) 483ba6e9364SSteven Whitehouse { 484feb47ca9SSteven Whitehouse int jid; 485ba6e9364SSteven Whitehouse int rv; 486ba6e9364SSteven Whitehouse 487feb47ca9SSteven Whitehouse rv = sscanf(buf, "%d", &jid); 488ba6e9364SSteven Whitehouse if (rv != 1) 489ba6e9364SSteven Whitehouse return -EINVAL; 4903942ae53SSteven Whitehouse rv = wait_for_completion_killable(&sdp->sd_locking_init); 4913942ae53SSteven Whitehouse if (rv) 4923942ae53SSteven Whitehouse return rv; 493ba6e9364SSteven Whitehouse spin_lock(&sdp->sd_jindex_spin); 494ba6e9364SSteven Whitehouse rv = -EINVAL; 495ba6e9364SSteven Whitehouse if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) 496ba6e9364SSteven Whitehouse goto out; 497ba6e9364SSteven Whitehouse rv = -EBUSY; 498feb47ca9SSteven Whitehouse if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) 499ba6e9364SSteven Whitehouse goto out; 500feb47ca9SSteven Whitehouse rv = 0; 501feb47ca9SSteven Whitehouse if (sdp->sd_args.ar_spectator && jid > 0) 502feb47ca9SSteven Whitehouse rv = jid = -EINVAL; 503ba6e9364SSteven Whitehouse sdp->sd_lockstruct.ls_jid = jid; 504feb47ca9SSteven Whitehouse clear_bit(SDF_NOJOURNALID, &sdp->sd_flags); 5054e857c58SPeter Zijlstra smp_mb__after_atomic(); 506ba6e9364SSteven Whitehouse wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID); 507ba6e9364SSteven Whitehouse out: 508ba6e9364SSteven Whitehouse spin_unlock(&sdp->sd_jindex_spin); 509ba6e9364SSteven Whitehouse return rv ? rv : len; 510ba6e9364SSteven Whitehouse } 511ba6e9364SSteven Whitehouse 512f057f6cdSSteven Whitehouse #define GDLM_ATTR(_name,_mode,_show,_store) \ 51348c2b613SSteven Whitehouse static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) 514f057f6cdSSteven Whitehouse 515f057f6cdSSteven Whitehouse GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); 516f057f6cdSSteven Whitehouse GDLM_ATTR(block, 0644, block_show, block_store); 517fd95e81cSSteven Whitehouse GDLM_ATTR(withdraw, 0644, wdack_show, wdack_store); 518ba6e9364SSteven Whitehouse GDLM_ATTR(jid, 0644, jid_show, jid_store); 519ba6e9364SSteven Whitehouse GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store); 520f057f6cdSSteven Whitehouse GDLM_ATTR(first_done, 0444, first_done_show, NULL); 521d7e623daSSteven Whitehouse GDLM_ATTR(recover, 0600, NULL, recover_store); 522f057f6cdSSteven Whitehouse GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); 523f057f6cdSSteven Whitehouse GDLM_ATTR(recover_status, 0444, recover_status_show, NULL); 524f057f6cdSSteven Whitehouse 525f057f6cdSSteven Whitehouse static struct attribute *lock_module_attrs[] = { 526f057f6cdSSteven Whitehouse &gdlm_attr_proto_name.attr, 527f057f6cdSSteven Whitehouse &gdlm_attr_block.attr, 528f057f6cdSSteven Whitehouse &gdlm_attr_withdraw.attr, 529e1b28aabSSteven Whitehouse &gdlm_attr_jid.attr, 530f057f6cdSSteven Whitehouse &gdlm_attr_first.attr, 531f057f6cdSSteven Whitehouse &gdlm_attr_first_done.attr, 532f057f6cdSSteven Whitehouse &gdlm_attr_recover.attr, 533f057f6cdSSteven Whitehouse &gdlm_attr_recover_done.attr, 534f057f6cdSSteven Whitehouse &gdlm_attr_recover_status.attr, 535ea67eedbSSteven Whitehouse NULL, 536b3b94faaSDavid Teigland }; 537b3b94faaSDavid Teigland 538b3b94faaSDavid Teigland /* 539b3b94faaSDavid Teigland * get and set struct gfs2_tune fields 540b3b94faaSDavid Teigland */ 541b3b94faaSDavid Teigland 542b3b94faaSDavid Teigland static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf) 543b3b94faaSDavid Teigland { 5443204a6c0SDavid Teigland return snprintf(buf, PAGE_SIZE, "%u %u\n", 5453204a6c0SDavid Teigland sdp->sd_tune.gt_quota_scale_num, 546b3b94faaSDavid Teigland sdp->sd_tune.gt_quota_scale_den); 547b3b94faaSDavid Teigland } 548b3b94faaSDavid Teigland 549b3b94faaSDavid Teigland static ssize_t quota_scale_store(struct gfs2_sbd *sdp, const char *buf, 550b3b94faaSDavid Teigland size_t len) 551b3b94faaSDavid Teigland { 552b3b94faaSDavid Teigland struct gfs2_tune *gt = &sdp->sd_tune; 553b3b94faaSDavid Teigland unsigned int x, y; 554b3b94faaSDavid Teigland 555b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 55641735818SZhao Hongjiang return -EPERM; 557b3b94faaSDavid Teigland 558b3b94faaSDavid Teigland if (sscanf(buf, "%u %u", &x, &y) != 2 || !y) 559b3b94faaSDavid Teigland return -EINVAL; 560b3b94faaSDavid Teigland 561b3b94faaSDavid Teigland spin_lock(>->gt_spin); 562b3b94faaSDavid Teigland gt->gt_quota_scale_num = x; 563b3b94faaSDavid Teigland gt->gt_quota_scale_den = y; 564b3b94faaSDavid Teigland spin_unlock(>->gt_spin); 565b3b94faaSDavid Teigland return len; 566b3b94faaSDavid Teigland } 567b3b94faaSDavid Teigland 568b3b94faaSDavid Teigland static ssize_t tune_set(struct gfs2_sbd *sdp, unsigned int *field, 569b3b94faaSDavid Teigland int check_zero, const char *buf, size_t len) 570b3b94faaSDavid Teigland { 571b3b94faaSDavid Teigland struct gfs2_tune *gt = &sdp->sd_tune; 572b3b94faaSDavid Teigland unsigned int x; 573e50ead48SFabian Frederick int error; 574b3b94faaSDavid Teigland 575b3b94faaSDavid Teigland if (!capable(CAP_SYS_ADMIN)) 57641735818SZhao Hongjiang return -EPERM; 577b3b94faaSDavid Teigland 578e50ead48SFabian Frederick error = kstrtouint(buf, 0, &x); 579e50ead48SFabian Frederick if (error) 580e50ead48SFabian Frederick return error; 581b3b94faaSDavid Teigland 582b3b94faaSDavid Teigland if (check_zero && !x) 583b3b94faaSDavid Teigland return -EINVAL; 584b3b94faaSDavid Teigland 585b3b94faaSDavid Teigland spin_lock(>->gt_spin); 586b3b94faaSDavid Teigland *field = x; 587b3b94faaSDavid Teigland spin_unlock(>->gt_spin); 588b3b94faaSDavid Teigland return len; 589b3b94faaSDavid Teigland } 590b3b94faaSDavid Teigland 591b3b94faaSDavid Teigland #define TUNE_ATTR_3(name, show, store) \ 59248c2b613SSteven Whitehouse static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store) 593b3b94faaSDavid Teigland 594b3b94faaSDavid Teigland #define TUNE_ATTR_2(name, store) \ 595b3b94faaSDavid Teigland static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ 596b3b94faaSDavid Teigland { \ 5973204a6c0SDavid Teigland return snprintf(buf, PAGE_SIZE, "%u\n", sdp->sd_tune.gt_##name); \ 598b3b94faaSDavid Teigland } \ 599b3b94faaSDavid Teigland TUNE_ATTR_3(name, name##_show, store) 600b3b94faaSDavid Teigland 601b3b94faaSDavid Teigland #define TUNE_ATTR(name, check_zero) \ 602b3b94faaSDavid Teigland static ssize_t name##_store(struct gfs2_sbd *sdp, const char *buf, size_t len)\ 603b3b94faaSDavid Teigland { \ 604b3b94faaSDavid Teigland return tune_set(sdp, &sdp->sd_tune.gt_##name, check_zero, buf, len); \ 605b3b94faaSDavid Teigland } \ 606b3b94faaSDavid Teigland TUNE_ATTR_2(name, name##_store) 607b3b94faaSDavid Teigland 608b3b94faaSDavid Teigland TUNE_ATTR(quota_warn_period, 0); 609b3b94faaSDavid Teigland TUNE_ATTR(quota_quantum, 0); 610b3b94faaSDavid Teigland TUNE_ATTR(max_readahead, 0); 611b3b94faaSDavid Teigland TUNE_ATTR(complain_secs, 0); 612b3b94faaSDavid Teigland TUNE_ATTR(statfs_slow, 0); 613b3b94faaSDavid Teigland TUNE_ATTR(new_files_jdata, 0); 614b3b94faaSDavid Teigland TUNE_ATTR(statfs_quantum, 1); 615b3b94faaSDavid Teigland TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); 616b3b94faaSDavid Teigland 617b3b94faaSDavid Teigland static struct attribute *tune_attrs[] = { 618b3b94faaSDavid Teigland &tune_attr_quota_warn_period.attr, 619b3b94faaSDavid Teigland &tune_attr_quota_quantum.attr, 620b3b94faaSDavid Teigland &tune_attr_max_readahead.attr, 621b3b94faaSDavid Teigland &tune_attr_complain_secs.attr, 622b3b94faaSDavid Teigland &tune_attr_statfs_slow.attr, 623b3b94faaSDavid Teigland &tune_attr_statfs_quantum.attr, 624b3b94faaSDavid Teigland &tune_attr_quota_scale.attr, 625b3b94faaSDavid Teigland &tune_attr_new_files_jdata.attr, 626ea67eedbSSteven Whitehouse NULL, 627b3b94faaSDavid Teigland }; 628b3b94faaSDavid Teigland 62929695254SArvind Yadav static const struct attribute_group tune_group = { 630b3b94faaSDavid Teigland .name = "tune", 631ea67eedbSSteven Whitehouse .attrs = tune_attrs, 632b3b94faaSDavid Teigland }; 633b3b94faaSDavid Teigland 63429695254SArvind Yadav static const struct attribute_group lock_module_group = { 635f057f6cdSSteven Whitehouse .name = "lock_module", 636f057f6cdSSteven Whitehouse .attrs = lock_module_attrs, 637f057f6cdSSteven Whitehouse }; 638f057f6cdSSteven Whitehouse 639b3b94faaSDavid Teigland int gfs2_sys_fs_add(struct gfs2_sbd *sdp) 640b3b94faaSDavid Teigland { 641440d6da2SSteven Whitehouse struct super_block *sb = sdp->sd_vfs; 642b3b94faaSDavid Teigland int error; 643440d6da2SSteven Whitehouse char ro[20]; 644440d6da2SSteven Whitehouse char spectator[20]; 645440d6da2SSteven Whitehouse char *envp[] = { ro, spectator, NULL }; 6460d515210SBob Peterson int sysfs_frees_sdp = 0; 647440d6da2SSteven Whitehouse 648bc98a42cSDavid Howells sprintf(ro, "RDONLY=%d", sb_rdonly(sb)); 649440d6da2SSteven Whitehouse sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); 650b3b94faaSDavid Teigland 6519bec101aSGreg Kroah-Hartman sdp->sd_kobj.kset = gfs2_kset; 652901195edSGreg Kroah-Hartman error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, 653901195edSGreg Kroah-Hartman "%s", sdp->sd_table_name); 654b3b94faaSDavid Teigland if (error) 6550d515210SBob Peterson goto fail_reg; 656b3b94faaSDavid Teigland 6570d515210SBob Peterson sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling 6580d515210SBob Peterson function gfs2_sbd_release. */ 659b3b94faaSDavid Teigland error = sysfs_create_group(&sdp->sd_kobj, &tune_group); 660b3b94faaSDavid Teigland if (error) 661f6eb5349SSteven Whitehouse goto fail_reg; 662b3b94faaSDavid Teigland 663f057f6cdSSteven Whitehouse error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group); 664f057f6cdSSteven Whitehouse if (error) 665f057f6cdSSteven Whitehouse goto fail_tune; 666f057f6cdSSteven Whitehouse 66731e54b01SSteven Whitehouse error = sysfs_create_link(&sdp->sd_kobj, 66831e54b01SSteven Whitehouse &disk_to_dev(sb->s_bdev->bd_disk)->kobj, 66931e54b01SSteven Whitehouse "device"); 67031e54b01SSteven Whitehouse if (error) 67131e54b01SSteven Whitehouse goto fail_lock_module; 67231e54b01SSteven Whitehouse 673440d6da2SSteven Whitehouse kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp); 674b3b94faaSDavid Teigland return 0; 675b3b94faaSDavid Teigland 67631e54b01SSteven Whitehouse fail_lock_module: 67731e54b01SSteven Whitehouse sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); 678f057f6cdSSteven Whitehouse fail_tune: 679f057f6cdSSteven Whitehouse sysfs_remove_group(&sdp->sd_kobj, &tune_group); 680b3b94faaSDavid Teigland fail_reg: 6810d515210SBob Peterson free_percpu(sdp->sd_lkstats); 682*af38816eSAndreas Gruenbacher fs_err(sdp, "error %d adding sysfs files\n", error); 6830d515210SBob Peterson if (sysfs_frees_sdp) 6840d515210SBob Peterson kobject_put(&sdp->sd_kobj); 6850d515210SBob Peterson else 6860d515210SBob Peterson kfree(sdp); 6870d515210SBob Peterson sb->s_fs_info = NULL; 688b3b94faaSDavid Teigland return error; 689b3b94faaSDavid Teigland } 690b3b94faaSDavid Teigland 691b3b94faaSDavid Teigland void gfs2_sys_fs_del(struct gfs2_sbd *sdp) 692b3b94faaSDavid Teigland { 69331e54b01SSteven Whitehouse sysfs_remove_link(&sdp->sd_kobj, "device"); 694b3b94faaSDavid Teigland sysfs_remove_group(&sdp->sd_kobj, &tune_group); 695f057f6cdSSteven Whitehouse sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); 696197b12d6SGreg Kroah-Hartman kobject_put(&sdp->sd_kobj); 697b3b94faaSDavid Teigland } 698b3b94faaSDavid Teigland 699fdd1062eSSteven Whitehouse static int gfs2_uevent(struct kset *kset, struct kobject *kobj, 700fdd1062eSSteven Whitehouse struct kobj_uevent_env *env) 701fdd1062eSSteven Whitehouse { 702fdd1062eSSteven Whitehouse struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); 70332e471efSSteven Whitehouse struct super_block *s = sdp->sd_vfs; 70402e3cc70SSteven Whitehouse 705fdd1062eSSteven Whitehouse add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); 706fdd1062eSSteven Whitehouse add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); 707ba6e9364SSteven Whitehouse if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) 708feb47ca9SSteven Whitehouse add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid); 70985787090SChristoph Hellwig if (!uuid_is_null(&s->s_uuid)) 71085787090SChristoph Hellwig add_uevent_var(env, "UUID=%pUB", &s->s_uuid); 711fdd1062eSSteven Whitehouse return 0; 712fdd1062eSSteven Whitehouse } 713fdd1062eSSteven Whitehouse 7149cd43611SEmese Revfy static const struct kset_uevent_ops gfs2_uevent_ops = { 715fdd1062eSSteven Whitehouse .uevent = gfs2_uevent, 716fdd1062eSSteven Whitehouse }; 717fdd1062eSSteven Whitehouse 718b3b94faaSDavid Teigland int gfs2_sys_init(void) 719b3b94faaSDavid Teigland { 720fdd1062eSSteven Whitehouse gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj); 7219bec101aSGreg Kroah-Hartman if (!gfs2_kset) 7229bec101aSGreg Kroah-Hartman return -ENOMEM; 7239bec101aSGreg Kroah-Hartman return 0; 724b3b94faaSDavid Teigland } 725b3b94faaSDavid Teigland 726b3b94faaSDavid Teigland void gfs2_sys_uninit(void) 727b3b94faaSDavid Teigland { 7289bec101aSGreg Kroah-Hartman kset_unregister(gfs2_kset); 729b3b94faaSDavid Teigland } 730b3b94faaSDavid Teigland 731