diff options
Diffstat (limited to 'fs/gfs2/sys.c')
-rw-r--r-- | fs/gfs2/sys.c | 60 |
1 files changed, 56 insertions, 4 deletions
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 37f5393e68e6..ccacffd2faaa 100644 --- a/fs/gfs2/sys.c +++ b/fs/gfs2/sys.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include "quota.h" | 25 | #include "quota.h" |
26 | #include "util.h" | 26 | #include "util.h" |
27 | #include "glops.h" | 27 | #include "glops.h" |
28 | #include "recovery.h" | ||
28 | 29 | ||
29 | struct gfs2_attr { | 30 | struct gfs2_attr { |
30 | struct attribute attr; | 31 | struct attribute attr; |
@@ -325,6 +326,30 @@ static ssize_t lkfirst_show(struct gfs2_sbd *sdp, char *buf) | |||
325 | return sprintf(buf, "%d\n", ls->ls_first); | 326 | return sprintf(buf, "%d\n", ls->ls_first); |
326 | } | 327 | } |
327 | 328 | ||
329 | static ssize_t lkfirst_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
330 | { | ||
331 | unsigned first; | ||
332 | int rv; | ||
333 | |||
334 | rv = sscanf(buf, "%u", &first); | ||
335 | if (rv != 1 || first > 1) | ||
336 | return -EINVAL; | ||
337 | spin_lock(&sdp->sd_jindex_spin); | ||
338 | rv = -EBUSY; | ||
339 | if (test_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) | ||
340 | goto out; | ||
341 | rv = -EINVAL; | ||
342 | if (sdp->sd_args.ar_spectator) | ||
343 | goto out; | ||
344 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) | ||
345 | goto out; | ||
346 | sdp->sd_lockstruct.ls_first = first; | ||
347 | rv = 0; | ||
348 | out: | ||
349 | spin_unlock(&sdp->sd_jindex_spin); | ||
350 | return rv ? rv : len; | ||
351 | } | ||
352 | |||
328 | static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) | 353 | static ssize_t first_done_show(struct gfs2_sbd *sdp, char *buf) |
329 | { | 354 | { |
330 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; | 355 | struct lm_lockstruct *ls = &sdp->sd_lockstruct; |
@@ -352,7 +377,7 @@ static ssize_t recover_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | |||
352 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { | 377 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
353 | if (jd->jd_jid != jid) | 378 | if (jd->jd_jid != jid) |
354 | continue; | 379 | continue; |
355 | rv = slow_work_enqueue(&jd->jd_work); | 380 | rv = gfs2_recover_journal(jd, false); |
356 | break; | 381 | break; |
357 | } | 382 | } |
358 | out: | 383 | out: |
@@ -377,14 +402,41 @@ static ssize_t jid_show(struct gfs2_sbd *sdp, char *buf) | |||
377 | return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid); | 402 | return sprintf(buf, "%u\n", sdp->sd_lockstruct.ls_jid); |
378 | } | 403 | } |
379 | 404 | ||
405 | static ssize_t jid_store(struct gfs2_sbd *sdp, const char *buf, size_t len) | ||
406 | { | ||
407 | unsigned jid; | ||
408 | int rv; | ||
409 | |||
410 | rv = sscanf(buf, "%u", &jid); | ||
411 | if (rv != 1) | ||
412 | return -EINVAL; | ||
413 | |||
414 | spin_lock(&sdp->sd_jindex_spin); | ||
415 | rv = -EINVAL; | ||
416 | if (sdp->sd_args.ar_spectator) | ||
417 | goto out; | ||
418 | if (sdp->sd_lockstruct.ls_ops->lm_mount == NULL) | ||
419 | goto out; | ||
420 | rv = -EBUSY; | ||
421 | if (test_and_clear_bit(SDF_NOJOURNALID, &sdp->sd_flags) == 0) | ||
422 | goto out; | ||
423 | sdp->sd_lockstruct.ls_jid = jid; | ||
424 | smp_mb__after_clear_bit(); | ||
425 | wake_up_bit(&sdp->sd_flags, SDF_NOJOURNALID); | ||
426 | rv = 0; | ||
427 | out: | ||
428 | spin_unlock(&sdp->sd_jindex_spin); | ||
429 | return rv ? rv : len; | ||
430 | } | ||
431 | |||
380 | #define GDLM_ATTR(_name,_mode,_show,_store) \ | 432 | #define GDLM_ATTR(_name,_mode,_show,_store) \ |
381 | static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) | 433 | static struct gfs2_attr gdlm_attr_##_name = __ATTR(_name,_mode,_show,_store) |
382 | 434 | ||
383 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); | 435 | GDLM_ATTR(proto_name, 0444, proto_name_show, NULL); |
384 | GDLM_ATTR(block, 0644, block_show, block_store); | 436 | GDLM_ATTR(block, 0644, block_show, block_store); |
385 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); | 437 | GDLM_ATTR(withdraw, 0644, withdraw_show, withdraw_store); |
386 | GDLM_ATTR(jid, 0444, jid_show, NULL); | 438 | GDLM_ATTR(jid, 0644, jid_show, jid_store); |
387 | GDLM_ATTR(first, 0444, lkfirst_show, NULL); | 439 | GDLM_ATTR(first, 0644, lkfirst_show, lkfirst_store); |
388 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); | 440 | GDLM_ATTR(first_done, 0444, first_done_show, NULL); |
389 | GDLM_ATTR(recover, 0600, NULL, recover_store); | 441 | GDLM_ATTR(recover, 0600, NULL, recover_store); |
390 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); | 442 | GDLM_ATTR(recover_done, 0444, recover_done_show, NULL); |
@@ -564,7 +616,7 @@ static int gfs2_uevent(struct kset *kset, struct kobject *kobj, | |||
564 | 616 | ||
565 | add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); | 617 | add_uevent_var(env, "LOCKTABLE=%s", sdp->sd_table_name); |
566 | add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); | 618 | add_uevent_var(env, "LOCKPROTO=%s", sdp->sd_proto_name); |
567 | if (!sdp->sd_args.ar_spectator) | 619 | if (!test_bit(SDF_NOJOURNALID, &sdp->sd_flags)) |
568 | add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid); | 620 | add_uevent_var(env, "JOURNALID=%u", sdp->sd_lockstruct.ls_jid); |
569 | if (gfs2_uuid_valid(uuid)) | 621 | if (gfs2_uuid_valid(uuid)) |
570 | add_uevent_var(env, "UUID=%pUB", uuid); | 622 | add_uevent_var(env, "UUID=%pUB", uuid); |