Blame view
fs/gfs2/sys.c
17.5 KB
b3b94faa5 [GFS2] The core o... |
1 2 |
/* * Copyright (C) Sistina Software, Inc. 1997-2003 All rights reserved. |
3a8a9a103 [GFS2] Update cop... |
3 |
* Copyright (C) 2004-2006 Red Hat, Inc. All rights reserved. |
b3b94faa5 [GFS2] The core o... |
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 |
e9fc2aa09 [GFS2] Update cop... |
7 |
* of the GNU General Public License version 2. |
b3b94faa5 [GFS2] The core o... |
8 |
*/ |
d77d1b58a GFS2: Use pr_<lev... |
9 |
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
b3b94faa5 [GFS2] The core o... |
10 |
#include <linux/sched.h> |
5b825c3af sched/headers: Pr... |
11 |
#include <linux/cred.h> |
b3b94faa5 [GFS2] The core o... |
12 13 14 15 16 |
#include <linux/spinlock.h> #include <linux/completion.h> #include <linux/buffer_head.h> #include <linux/module.h> #include <linux/kobject.h> |
7c0f6ba68 Replace <asm/uacc... |
17 |
#include <linux/uaccess.h> |
f057f6cdf GFS2: Merge lock_... |
18 |
#include <linux/gfs2_ondisk.h> |
31e54b01f GFS2: Add sysfs l... |
19 |
#include <linux/genhd.h> |
b3b94faa5 [GFS2] The core o... |
20 21 |
#include "gfs2.h" |
5c676f6d3 [GFS2] Macros rem... |
22 |
#include "incore.h" |
b3b94faa5 [GFS2] The core o... |
23 24 25 26 |
#include "sys.h" #include "super.h" #include "glock.h" #include "quota.h" |
5c676f6d3 [GFS2] Macros rem... |
27 |
#include "util.h" |
64d576ba2 GFS2: Add a "demo... |
28 |
#include "glops.h" |
6ecd7c2dd gfs2: use workque... |
29 |
#include "recovery.h" |
b3b94faa5 [GFS2] The core o... |
30 |
|
48c2b6136 GFS2: Add commit=... |
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
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; } |
52cf25d0a Driver core: Cons... |
52 |
static const struct sysfs_ops gfs2_attr_ops = { |
48c2b6136 GFS2: Add commit=... |
53 54 55 56 57 58 |
.show = gfs2_attr_show, .store = gfs2_attr_store, }; static struct kset *gfs2_kset; |
b3b94faa5 [GFS2] The core o... |
59 60 |
static ssize_t id_show(struct gfs2_sbd *sdp, char *buf) { |
c7227e464 [GFS2] Given devi... |
61 62 63 |
return snprintf(buf, PAGE_SIZE, "%u:%u ", MAJOR(sdp->sd_vfs->s_dev), MINOR(sdp->sd_vfs->s_dev)); |
b3b94faa5 [GFS2] The core o... |
64 65 66 67 |
} static ssize_t fsname_show(struct gfs2_sbd *sdp, char *buf) { |
3204a6c05 [GFS2] use snprin... |
68 69 |
return snprintf(buf, PAGE_SIZE, "%s ", sdp->sd_fsname); |
b3b94faa5 [GFS2] The core o... |
70 |
} |
02e3cc70e GFS2: Expose UUID... |
71 72 |
static ssize_t uuid_show(struct gfs2_sbd *sdp, char *buf) { |
32e471ef1 GFS2: Use UUID fi... |
73 |
struct super_block *s = sdp->sd_vfs; |
85787090a fs: switch ->s_uu... |
74 |
|
02e3cc70e GFS2: Expose UUID... |
75 |
buf[0] = '\0'; |
85787090a fs: switch ->s_uu... |
76 |
if (uuid_is_null(&s->s_uuid)) |
02e3cc70e GFS2: Expose UUID... |
77 |
return 0; |
85787090a fs: switch ->s_uu... |
78 79 |
return snprintf(buf, PAGE_SIZE, "%pUB ", &s->s_uuid); |
02e3cc70e GFS2: Expose UUID... |
80 |
} |
b3b94faa5 [GFS2] The core o... |
81 82 |
static ssize_t freeze_show(struct gfs2_sbd *sdp, char *buf) { |
d564053f0 GFS2: Clean up fr... |
83 84 |
struct super_block *sb = sdp->sd_vfs; int frozen = (sb->s_writers.frozen == SB_UNFROZEN) ? 0 : 1; |
b3b94faa5 [GFS2] The core o... |
85 |
|
3566c9647 GFS2: fix sprintf... |
86 87 |
return snprintf(buf, PAGE_SIZE, "%d ", frozen); |
b3b94faa5 [GFS2] The core o... |
88 89 90 91 |
} static ssize_t freeze_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
e50ead480 gfs2: convert sim... |
92 93 94 95 96 |
int error, n; error = kstrtoint(buf, 0, &n); if (error) return error; |
b3b94faa5 [GFS2] The core o... |
97 98 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
99 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
100 101 102 |
switch (n) { case 0: |
d564053f0 GFS2: Clean up fr... |
103 |
error = thaw_super(sdp->sd_vfs); |
b3b94faa5 [GFS2] The core o... |
104 105 |
break; case 1: |
d564053f0 GFS2: Clean up fr... |
106 |
error = freeze_super(sdp->sd_vfs); |
b3b94faa5 [GFS2] The core o... |
107 108 |
break; default: |
d564053f0 GFS2: Clean up fr... |
109 |
return -EINVAL; |
b3b94faa5 [GFS2] The core o... |
110 |
} |
d564053f0 GFS2: Clean up fr... |
111 |
if (error) { |
b3b94faa5 [GFS2] The core o... |
112 |
fs_warn(sdp, "freeze %d error %d", n, error); |
d564053f0 GFS2: Clean up fr... |
113 114 |
return error; } |
b3b94faa5 [GFS2] The core o... |
115 |
|
d564053f0 GFS2: Clean up fr... |
116 |
return len; |
b3b94faa5 [GFS2] The core o... |
117 118 119 120 121 |
} static ssize_t withdraw_show(struct gfs2_sbd *sdp, char *buf) { unsigned int b = test_bit(SDF_SHUTDOWN, &sdp->sd_flags); |
3204a6c05 [GFS2] use snprin... |
122 123 |
return snprintf(buf, PAGE_SIZE, "%u ", b); |
b3b94faa5 [GFS2] The core o... |
124 125 126 127 |
} static ssize_t withdraw_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
e50ead480 gfs2: convert sim... |
128 |
int error, val; |
b3b94faa5 [GFS2] The core o... |
129 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
130 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
131 |
|
e50ead480 gfs2: convert sim... |
132 133 134 135 136 |
error = kstrtoint(buf, 0, &val); if (error) return error; if (val != 1) |
b3b94faa5 [GFS2] The core o... |
137 |
return -EINVAL; |
cb94eb066 GFS2: Convert gfs... |
138 139 |
gfs2_lm_withdraw(sdp, "withdrawing from cluster at user's request "); |
b3b94faa5 [GFS2] The core o... |
140 141 142 143 144 145 |
return len; } static ssize_t statfs_sync_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
e50ead480 gfs2: convert sim... |
146 |
int error, val; |
b3b94faa5 [GFS2] The core o... |
147 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
148 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
149 |
|
e50ead480 gfs2: convert sim... |
150 151 152 153 154 |
error = kstrtoint(buf, 0, &val); if (error) return error; if (val != 1) |
b3b94faa5 [GFS2] The core o... |
155 |
return -EINVAL; |
8c42d637f GFS2: Alter argum... |
156 |
gfs2_statfs_sync(sdp->sd_vfs, 0); |
b3b94faa5 [GFS2] The core o... |
157 158 |
return len; } |
b3b94faa5 [GFS2] The core o... |
159 160 161 |
static ssize_t quota_sync_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
e50ead480 gfs2: convert sim... |
162 |
int error, val; |
b3b94faa5 [GFS2] The core o... |
163 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
164 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
165 |
|
e50ead480 gfs2: convert sim... |
166 167 168 169 170 |
error = kstrtoint(buf, 0, &val); if (error) return error; if (val != 1) |
b3b94faa5 [GFS2] The core o... |
171 |
return -EINVAL; |
ceed17236 quota: Split dquo... |
172 |
gfs2_quota_sync(sdp->sd_vfs, 0); |
b3b94faa5 [GFS2] The core o... |
173 174 175 176 177 178 |
return len; } static ssize_t quota_refresh_user_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
ed87dabcc gfs2: Convert gfs... |
179 |
struct kqid qid; |
ea7623385 GFS2: Add proper ... |
180 |
int error; |
cd915493f [GFS2] Change all... |
181 |
u32 id; |
b3b94faa5 [GFS2] The core o... |
182 183 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
184 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
185 |
|
e50ead480 gfs2: convert sim... |
186 187 188 |
error = kstrtou32(buf, 0, &id); if (error) return error; |
b3b94faa5 [GFS2] The core o... |
189 |
|
ed87dabcc gfs2: Convert gfs... |
190 191 192 193 194 |
qid = make_kqid(current_user_ns(), USRQUOTA, id); if (!qid_valid(qid)) return -EINVAL; error = gfs2_quota_refresh(sdp, qid); |
ea7623385 GFS2: Add proper ... |
195 |
return error ? error : len; |
b3b94faa5 [GFS2] The core o... |
196 197 198 199 200 |
} static ssize_t quota_refresh_group_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
ed87dabcc gfs2: Convert gfs... |
201 |
struct kqid qid; |
ea7623385 GFS2: Add proper ... |
202 |
int error; |
cd915493f [GFS2] Change all... |
203 |
u32 id; |
b3b94faa5 [GFS2] The core o... |
204 205 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
206 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
207 |
|
e50ead480 gfs2: convert sim... |
208 209 210 |
error = kstrtou32(buf, 0, &id); if (error) return error; |
b3b94faa5 [GFS2] The core o... |
211 |
|
ed87dabcc gfs2: Convert gfs... |
212 213 214 215 216 |
qid = make_kqid(current_user_ns(), GRPQUOTA, id); if (!qid_valid(qid)) return -EINVAL; error = gfs2_quota_refresh(sdp, qid); |
ea7623385 GFS2: Add proper ... |
217 |
return error ? error : len; |
b3b94faa5 [GFS2] The core o... |
218 |
} |
64d576ba2 GFS2: Add a "demo... |
219 220 221 222 223 224 225 226 227 228 229 |
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)) |
417358187 fs: change return... |
230 |
return -EPERM; |
64d576ba2 GFS2: Add a "demo... |
231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
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; |
24972557b GFS2: remove tran... |
248 249 |
if (gltype == LM_TYPE_NONDISK && glnum == GFS2_FREEZE_LOCK) glops = &gfs2_freeze_glops; |
134669854 GFS2: Fix type ma... |
250 251 |
else glops = gfs2_glops_list[gltype]; |
64d576ba2 GFS2: Add a "demo... |
252 253 |
if (glops == NULL) return -EINVAL; |
6a99be5d7 GFS2: Fix typo |
254 |
if (!test_and_set_bit(SDF_DEMOTE, &sdp->sd_flags)) |
913a71d25 GFS2: Add some us... |
255 256 |
fs_info(sdp, "demote interface used "); |
64d576ba2 GFS2: Add a "demo... |
257 258 259 260 261 262 263 |
rv = gfs2_glock_get(sdp, glnum, glops, 0, &gl); if (rv) return rv; gfs2_glock_cb(gl, glmode); gfs2_glock_put(gl); return len; } |
b3b94faa5 [GFS2] The core o... |
264 265 266 267 268 269 |
#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); |
02e3cc70e GFS2: Expose UUID... |
270 |
GFS2_ATTR(uuid, 0444, uuid_show, NULL); |
b3b94faa5 [GFS2] The core o... |
271 |
GFS2_ATTR(freeze, 0644, freeze_show, freeze_store); |
b3b94faa5 [GFS2] The core o... |
272 273 274 275 276 |
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); |
64d576ba2 GFS2: Add a "demo... |
277 |
GFS2_ATTR(demote_rq, 0200, NULL, demote_rq_store); |
b3b94faa5 [GFS2] The core o... |
278 279 280 281 |
static struct attribute *gfs2_attrs[] = { &gfs2_attr_id.attr, &gfs2_attr_fsname.attr, |
02e3cc70e GFS2: Expose UUID... |
282 |
&gfs2_attr_uuid.attr, |
b3b94faa5 [GFS2] The core o... |
283 |
&gfs2_attr_freeze.attr, |
b3b94faa5 [GFS2] The core o... |
284 285 286 287 288 |
&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, |
64d576ba2 GFS2: Add a "demo... |
289 |
&gfs2_attr_demote_rq.attr, |
b3b94faa5 [GFS2] The core o... |
290 291 |
NULL, }; |
0d515210b GFS2: Add kobject... |
292 293 294 295 296 297 |
static void gfs2_sbd_release(struct kobject *kobj) { struct gfs2_sbd *sdp = container_of(kobj, struct gfs2_sbd, sd_kobj); kfree(sdp); } |
b3b94faa5 [GFS2] The core o... |
298 |
static struct kobj_type gfs2_ktype = { |
0d515210b GFS2: Add kobject... |
299 |
.release = gfs2_sbd_release, |
b3b94faa5 [GFS2] The core o... |
300 301 302 |
.default_attrs = gfs2_attrs, .sysfs_ops = &gfs2_attr_ops, }; |
f057f6cdf GFS2: Merge lock_... |
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 |
/* * 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 ", 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; |
e0c2a9aa1 GFS2: dlm based r... |
320 |
if (test_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags)) |
f057f6cdf GFS2: Merge lock_... |
321 322 323 324 325 326 327 328 329 |
val = 1; ret = sprintf(buf, "%d ", 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; |
e50ead480 gfs2: convert sim... |
330 |
int ret, val; |
f057f6cdf GFS2: Merge lock_... |
331 |
|
e50ead480 gfs2: convert sim... |
332 333 334 |
ret = kstrtoint(buf, 0, &val); if (ret) return ret; |
f057f6cdf GFS2: Merge lock_... |
335 336 |
if (val == 1) |
e0c2a9aa1 GFS2: dlm based r... |
337 |
set_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags); |
f057f6cdf GFS2: Merge lock_... |
338 |
else if (val == 0) { |
e0c2a9aa1 GFS2: dlm based r... |
339 |
clear_bit(DFL_BLOCK_LOCKS, &ls->ls_recover_flags); |
4e857c58e arch: Mass conver... |
340 |
smp_mb__after_atomic(); |
f057f6cdf GFS2: Merge lock_... |
341 342 |
gfs2_glock_thaw(sdp); } else { |
e50ead480 gfs2: convert sim... |
343 |
return -EINVAL; |
f057f6cdf GFS2: Merge lock_... |
344 |
} |
e50ead480 gfs2: convert sim... |
345 |
return len; |
f057f6cdf GFS2: Merge lock_... |
346 |
} |
fd95e81cb GFS2: Reinstate w... |
347 348 349 350 351 352 353 354 355 356 |
static ssize_t wdack_show(struct gfs2_sbd *sdp, char *buf) { int val = completion_done(&sdp->sd_wdack) ? 1 : 0; return sprintf(buf, "%d ", val); } static ssize_t wdack_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
e50ead480 gfs2: convert sim... |
357 |
int ret, val; |
fd95e81cb GFS2: Reinstate w... |
358 |
|
e50ead480 gfs2: convert sim... |
359 360 361 |
ret = kstrtoint(buf, 0, &val); if (ret) return ret; |
fd95e81cb GFS2: Reinstate w... |
362 363 364 365 366 |
if ((val == 1) && !strcmp(sdp->sd_lockstruct.ls_ops->lm_proto_name, "lock_dlm")) complete(&sdp->sd_wdack); else |
e50ead480 gfs2: convert sim... |
367 368 |
return -EINVAL; return len; |
fd95e81cb GFS2: Reinstate w... |
369 |
} |
f057f6cdf GFS2: Merge lock_... |
370 371 372 373 374 375 |
static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; return sprintf(buf, "%d ", ls->ls_first); } |
ba6e93645 GFS2: Wait for jo... |
376 377 378 379 380 381 382 383 |
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; |
3942ae531 GFS2: Fix race du... |
384 385 386 |
rv = wait_for_completion_killable(&sdp->sd_locking_init); if (rv) return rv; |
ba6e93645 GFS2: Wait for jo... |
387 388 389 390 391 392 393 394 395 |
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; |
e0c2a9aa1 GFS2: dlm based r... |
396 397 |
sdp->sd_lockstruct.ls_first = first; rv = 0; |
ba6e93645 GFS2: Wait for jo... |
398 399 400 401 |
out: spin_unlock(&sdp->sd_jindex_spin); return rv ? rv : len; } |
f057f6cdf GFS2: Merge lock_... |
402 403 404 |
static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
e0c2a9aa1 GFS2: dlm based r... |
405 406 |
return sprintf(buf, "%d ", !!test_bit(DFL_FIRST_MOUNT_DONE, &ls->ls_recover_flags)); |
f057f6cdf GFS2: Merge lock_... |
407 |
} |
e0c2a9aa1 GFS2: dlm based r... |
408 |
int gfs2_recover_set(struct gfs2_sbd *sdp, unsigned jid) |
f057f6cdf GFS2: Merge lock_... |
409 410 |
{ struct gfs2_jdesc *jd; |
fe64d517d GFS2: Umount reco... |
411 |
int rv; |
0e48e055a GFS2: Prevent rec... |
412 413 |
/* Wait for our primary journal to be initialized */ wait_for_completion(&sdp->sd_journal_ready); |
f057f6cdf GFS2: Merge lock_... |
414 |
spin_lock(&sdp->sd_jindex_spin); |
fe64d517d GFS2: Umount reco... |
415 416 417 418 |
rv = -EBUSY; if (sdp->sd_jdesc->jd_jid == jid) goto out; rv = -ENOENT; |
f057f6cdf GFS2: Merge lock_... |
419 420 421 |
list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { if (jd->jd_jid != jid) continue; |
6ecd7c2dd gfs2: use workque... |
422 |
rv = gfs2_recover_journal(jd, false); |
f057f6cdf GFS2: Merge lock_... |
423 424 |
break; } |
fe64d517d GFS2: Umount reco... |
425 |
out: |
f057f6cdf GFS2: Merge lock_... |
426 |
spin_unlock(&sdp->sd_jindex_spin); |
e0c2a9aa1 GFS2: dlm based r... |
427 428 429 430 431 432 433 434 435 436 437 |
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; |
1a058f528 gfs2: fix recover... |
438 439 440 441 |
if (test_bit(SDF_NORECOVERY, &sdp->sd_flags)) { rv = -ESHUTDOWN; goto out; } |
e0c2a9aa1 GFS2: dlm based r... |
442 |
|
1a058f528 gfs2: fix recover... |
443 444 |
rv = gfs2_recover_set(sdp, jid); out: |
fe64d517d GFS2: Umount reco... |
445 |
return rv ? rv : len; |
f057f6cdf GFS2: Merge lock_... |
446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 |
} static ssize_t recover_done_show(struct gfs2_sbd *sdp, char *buf) { struct lm_lockstruct *ls = &sdp->sd_lockstruct; return sprintf(buf, "%d ", 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 ", ls->ls_recover_jid_status); } |
e1b28aab5 GFS2: Remove lock... |
461 462 |
static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf) { |
feb47ca93 GFS2: Improve jou... |
463 464 |
return sprintf(buf, "%d ", sdp->sd_lockstruct.ls_jid); |
e1b28aab5 GFS2: Remove lock... |
465 |
} |
ba6e93645 GFS2: Wait for jo... |
466 467 |
static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) { |
feb47ca93 GFS2: Improve jou... |
468 |
int jid; |
ba6e93645 GFS2: Wait for jo... |
469 |
int rv; |
feb47ca93 GFS2: Improve jou... |
470 |
rv = sscanf(buf, "%d", &jid); |
ba6e93645 GFS2: Wait for jo... |
471 472 |
if (rv != 1) return -EINVAL; |
3942ae531 GFS2: Fix race du... |
473 474 475 |
rv = wait_for_completion_killable(&sdp->sd_locking_init); if (rv) return rv; |
ba6e93645 GFS2: Wait for jo... |
476 477 |
spin_lock(&sdp->sd_jindex_spin); rv = -EINVAL; |
ba6e93645 GFS2: Wait for jo... |
478 479 480 |
if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) goto out; rv = -EBUSY; |
feb47ca93 GFS2: Improve jou... |
481 |
if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) |
ba6e93645 GFS2: Wait for jo... |
482 |
goto out; |
feb47ca93 GFS2: Improve jou... |
483 484 485 |
rv = 0; if (sdp->sd_args.ar_spectator && jid > 0) rv = jid = -EINVAL; |
ba6e93645 GFS2: Wait for jo... |
486 |
sdp->sd_lockstruct.ls_jid = jid; |
feb47ca93 GFS2: Improve jou... |
487 |
clear_bit(SDF_NOJOURNALID, &sdp->sd_flags); |
4e857c58e arch: Mass conver... |
488 |
smp_mb__after_atomic(); |
ba6e93645 GFS2: Wait for jo... |
489 |
wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID); |
ba6e93645 GFS2: Wait for jo... |
490 491 492 493 |
out: spin_unlock(&sdp->sd_jindex_spin); return rv ? rv : len; } |
f057f6cdf GFS2: Merge lock_... |
494 |
#define GDLM_ATTR(_name,_mode,_show,_store) \ |
48c2b6136 GFS2: Add commit=... |
495 |
static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) |
f057f6cdf GFS2: Merge lock_... |
496 |
|
d7e623da1 GFS2: Fix permiss... |
497 498 |
GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); GDLM_ATTR(block, 0644, block_show, block_store); |
fd95e81cb GFS2: Reinstate w... |
499 |
GDLM_ATTR(withdraw, 0644, wdack_show, wdack_store); |
ba6e93645 GFS2: Wait for jo... |
500 501 |
GDLM_ATTR(jid, 0644, jid_show, jid_store); GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store); |
d7e623da1 GFS2: Fix permiss... |
502 503 504 505 |
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); |
f057f6cdf GFS2: Merge lock_... |
506 507 508 509 510 |
static struct attribute *lock_module_attrs[] = { &gdlm_attr_proto_name.attr, &gdlm_attr_block.attr, &gdlm_attr_withdraw.attr, |
e1b28aab5 GFS2: Remove lock... |
511 |
&gdlm_attr_jid.attr, |
f057f6cdf GFS2: Merge lock_... |
512 513 514 515 516 |
&gdlm_attr_first.attr, &gdlm_attr_first_done.attr, &gdlm_attr_recover.attr, &gdlm_attr_recover_done.attr, &gdlm_attr_recover_status.attr, |
ea67eedb2 [GFS2] Fix end of... |
517 |
NULL, |
b3b94faa5 [GFS2] The core o... |
518 |
}; |
b3b94faa5 [GFS2] The core o... |
519 |
/* |
b3b94faa5 [GFS2] The core o... |
520 521 522 523 524 |
* get and set struct gfs2_tune fields */ static ssize_t quota_scale_show(struct gfs2_sbd *sdp, char *buf) { |
3204a6c05 [GFS2] use snprin... |
525 526 527 528 |
return snprintf(buf, PAGE_SIZE, "%u %u ", sdp->sd_tune.gt_quota_scale_num, sdp->sd_tune.gt_quota_scale_den); |
b3b94faa5 [GFS2] The core o... |
529 530 531 532 533 534 535 536 537 |
} 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)) |
417358187 fs: change return... |
538 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
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_spin); gt->gt_quota_scale_num = x; gt->gt_quota_scale_den = y; spin_unlock(>->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; |
e50ead480 gfs2: convert sim... |
555 |
int error; |
b3b94faa5 [GFS2] The core o... |
556 557 |
if (!capable(CAP_SYS_ADMIN)) |
417358187 fs: change return... |
558 |
return -EPERM; |
b3b94faa5 [GFS2] The core o... |
559 |
|
e50ead480 gfs2: convert sim... |
560 561 562 |
error = kstrtouint(buf, 0, &x); if (error) return error; |
b3b94faa5 [GFS2] The core o... |
563 564 565 566 567 568 569 570 571 |
if (check_zero && !x) return -EINVAL; spin_lock(>->gt_spin); *field = x; spin_unlock(>->gt_spin); return len; } |
b3b94faa5 [GFS2] The core o... |
572 |
#define TUNE_ATTR_3(name, show, store) \ |
48c2b6136 GFS2: Add commit=... |
573 |
static struct gfs2_attr tune_attr_##name = __ATTR(name, 0644, show, store) |
b3b94faa5 [GFS2] The core o... |
574 575 576 577 |
#define TUNE_ATTR_2(name, store) \ static ssize_t name##_show(struct gfs2_sbd *sdp, char *buf) \ { \ |
3204a6c05 [GFS2] use snprin... |
578 579 |
return snprintf(buf, PAGE_SIZE, "%u ", sdp->sd_tune.gt_##name); \ |
b3b94faa5 [GFS2] The core o... |
580 581 582 583 584 585 586 587 588 |
} \ 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) |
b3b94faa5 [GFS2] The core o... |
589 590 |
TUNE_ATTR(quota_warn_period, 0); TUNE_ATTR(quota_quantum, 0); |
b3b94faa5 [GFS2] The core o... |
591 592 |
TUNE_ATTR(max_readahead, 0); TUNE_ATTR(complain_secs, 0); |
b3b94faa5 [GFS2] The core o... |
593 594 |
TUNE_ATTR(statfs_slow, 0); TUNE_ATTR(new_files_jdata, 0); |
b3b94faa5 [GFS2] The core o... |
595 |
TUNE_ATTR(statfs_quantum, 1); |
b3b94faa5 [GFS2] The core o... |
596 597 598 |
TUNE_ATTR_3(quota_scale, quota_scale_show, quota_scale_store); static struct attribute *tune_attrs[] = { |
b3b94faa5 [GFS2] The core o... |
599 600 |
&tune_attr_quota_warn_period.attr, &tune_attr_quota_quantum.attr, |
b3b94faa5 [GFS2] The core o... |
601 602 |
&tune_attr_max_readahead.attr, &tune_attr_complain_secs.attr, |
b3b94faa5 [GFS2] The core o... |
603 |
&tune_attr_statfs_slow.attr, |
b3b94faa5 [GFS2] The core o... |
604 |
&tune_attr_statfs_quantum.attr, |
b3b94faa5 [GFS2] The core o... |
605 606 |
&tune_attr_quota_scale.attr, &tune_attr_new_files_jdata.attr, |
ea67eedb2 [GFS2] Fix end of... |
607 |
NULL, |
b3b94faa5 [GFS2] The core o... |
608 |
}; |
29695254e GFS2: constify at... |
609 |
static const struct attribute_group tune_group = { |
b3b94faa5 [GFS2] The core o... |
610 |
.name = "tune", |
ea67eedb2 [GFS2] Fix end of... |
611 |
.attrs = tune_attrs, |
b3b94faa5 [GFS2] The core o... |
612 |
}; |
29695254e GFS2: constify at... |
613 |
static const struct attribute_group lock_module_group = { |
f057f6cdf GFS2: Merge lock_... |
614 615 616 |
.name = "lock_module", .attrs = lock_module_attrs, }; |
b3b94faa5 [GFS2] The core o... |
617 618 |
int gfs2_sys_fs_add(struct gfs2_sbd *sdp) { |
440d6da20 GFS2: Add some mo... |
619 |
struct super_block *sb = sdp->sd_vfs; |
b3b94faa5 [GFS2] The core o... |
620 |
int error; |
440d6da20 GFS2: Add some mo... |
621 622 623 |
char ro[20]; char spectator[20]; char *envp[] = { ro, spectator, NULL }; |
0d515210b GFS2: Add kobject... |
624 |
int sysfs_frees_sdp = 0; |
440d6da20 GFS2: Add some mo... |
625 |
|
bc98a42c1 VFS: Convert sb->... |
626 |
sprintf(ro, "RDONLY=%d", sb_rdonly(sb)); |
440d6da20 GFS2: Add some mo... |
627 |
sprintf(spectator, "SPECTATOR=%d", sdp->sd_args.ar_spectator ? 1 : 0); |
b3b94faa5 [GFS2] The core o... |
628 |
|
9bec101a0 kset: convert gfs... |
629 |
sdp->sd_kobj.kset = gfs2_kset; |
901195ed7 Kobject: change G... |
630 631 |
error = kobject_init_and_add(&sdp->sd_kobj, &gfs2_ktype, NULL, "%s", sdp->sd_table_name); |
b3b94faa5 [GFS2] The core o... |
632 |
if (error) |
0d515210b GFS2: Add kobject... |
633 |
goto fail_reg; |
b3b94faa5 [GFS2] The core o... |
634 |
|
0d515210b GFS2: Add kobject... |
635 636 |
sysfs_frees_sdp = 1; /* Freeing sdp is now done by sysfs calling function gfs2_sbd_release. */ |
b3b94faa5 [GFS2] The core o... |
637 638 |
error = sysfs_create_group(&sdp->sd_kobj, &tune_group); if (error) |
f6eb53498 GFS2: Remove args... |
639 |
goto fail_reg; |
b3b94faa5 [GFS2] The core o... |
640 |
|
f057f6cdf GFS2: Merge lock_... |
641 642 643 |
error = sysfs_create_group(&sdp->sd_kobj, &lock_module_group); if (error) goto fail_tune; |
31e54b01f GFS2: Add sysfs l... |
644 645 646 647 648 |
error = sysfs_create_link(&sdp->sd_kobj, &disk_to_dev(sb->s_bdev->bd_disk)->kobj, "device"); if (error) goto fail_lock_module; |
440d6da20 GFS2: Add some mo... |
649 |
kobject_uevent_env(&sdp->sd_kobj, KOBJ_ADD, envp); |
b3b94faa5 [GFS2] The core o... |
650 |
return 0; |
31e54b01f GFS2: Add sysfs l... |
651 652 |
fail_lock_module: sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); |
f057f6cdf GFS2: Merge lock_... |
653 654 |
fail_tune: sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
a91ea69ff [GFS2] Align all ... |
655 |
fail_reg: |
0d515210b GFS2: Add kobject... |
656 |
free_percpu(sdp->sd_lkstats); |
65952fb4e [GFS2] print moun... |
657 |
fs_err(sdp, "error %d adding sysfs files", error); |
0d515210b GFS2: Add kobject... |
658 659 660 661 662 |
if (sysfs_frees_sdp) kobject_put(&sdp->sd_kobj); else kfree(sdp); sb->s_fs_info = NULL; |
b3b94faa5 [GFS2] The core o... |
663 664 665 666 667 |
return error; } void gfs2_sys_fs_del(struct gfs2_sbd *sdp) { |
31e54b01f GFS2: Add sysfs l... |
668 |
sysfs_remove_link(&sdp->sd_kobj, "device"); |
b3b94faa5 [GFS2] The core o... |
669 |
sysfs_remove_group(&sdp->sd_kobj, &tune_group); |
f057f6cdf GFS2: Merge lock_... |
670 |
sysfs_remove_group(&sdp->sd_kobj, &lock_module_group); |
197b12d67 Kobject: convert ... |
671 |
kobject_put(&sdp->sd_kobj); |
b3b94faa5 [GFS2] The core o... |
672 |
} |
fdd1062eb GFS2: Send some s... |
673 674 675 676 |
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); |
32e471ef1 GFS2: Use UUID fi... |
677 |
struct super_block *s = sdp->sd_vfs; |
02e3cc70e GFS2: Expose UUID... |
678 |
|
fdd1062eb GFS2: Send some s... |
679 680 |
add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); |
ba6e93645 GFS2: Wait for jo... |
681 |
if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) |
feb47ca93 GFS2: Improve jou... |
682 |
add_uevent_var(env, "JOURNALID=%d", sdp->sd_lockstruct.ls_jid); |
85787090a fs: switch ->s_uu... |
683 684 |
if (!uuid_is_null(&s->s_uuid)) add_uevent_var(env, "UUID=%pUB", &s->s_uuid); |
fdd1062eb GFS2: Send some s... |
685 686 |
return 0; } |
9cd43611c kobject: Constify... |
687 |
static const struct kset_uevent_ops gfs2_uevent_ops = { |
fdd1062eb GFS2: Send some s... |
688 689 |
.uevent = gfs2_uevent, }; |
b3b94faa5 [GFS2] The core o... |
690 691 |
int gfs2_sys_init(void) { |
fdd1062eb GFS2: Send some s... |
692 |
gfs2_kset = kset_create_and_add("gfs2", &gfs2_uevent_ops, fs_kobj); |
9bec101a0 kset: convert gfs... |
693 694 695 |
if (!gfs2_kset) return -ENOMEM; return 0; |
b3b94faa5 [GFS2] The core o... |
696 697 698 699 |
} void gfs2_sys_uninit(void) { |
9bec101a0 kset: convert gfs... |
700 |
kset_unregister(gfs2_kset); |
b3b94faa5 [GFS2] The core o... |
701 |
} |