diff options
| -rw-r--r-- | fs/gfs2/Kconfig | 1 | ||||
| -rw-r--r-- | fs/gfs2/incore.h | 3 | ||||
| -rw-r--r-- | fs/gfs2/main.c | 14 | ||||
| -rw-r--r-- | fs/gfs2/ops_fstype.c | 8 | ||||
| -rw-r--r-- | fs/gfs2/recovery.c | 54 | ||||
| -rw-r--r-- | fs/gfs2/recovery.h | 6 | ||||
| -rw-r--r-- | fs/gfs2/sys.c | 3 |
7 files changed, 40 insertions, 49 deletions
diff --git a/fs/gfs2/Kconfig b/fs/gfs2/Kconfig index a47b43107112..cc9665522148 100644 --- a/fs/gfs2/Kconfig +++ b/fs/gfs2/Kconfig | |||
| @@ -7,7 +7,6 @@ config GFS2_FS | |||
| 7 | select IP_SCTP if DLM_SCTP | 7 | select IP_SCTP if DLM_SCTP |
| 8 | select FS_POSIX_ACL | 8 | select FS_POSIX_ACL |
| 9 | select CRC32 | 9 | select CRC32 |
| 10 | select SLOW_WORK | ||
| 11 | select QUOTACTL | 10 | select QUOTACTL |
| 12 | help | 11 | help |
| 13 | A cluster filesystem. | 12 | A cluster filesystem. |
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h index b5d7363b22da..dd8f2e63d15a 100644 --- a/fs/gfs2/incore.h +++ b/fs/gfs2/incore.h | |||
| @@ -12,7 +12,6 @@ | |||
| 12 | 12 | ||
| 13 | #include <linux/fs.h> | 13 | #include <linux/fs.h> |
| 14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
| 15 | #include <linux/slow-work.h> | ||
| 16 | #include <linux/dlm.h> | 15 | #include <linux/dlm.h> |
| 17 | #include <linux/buffer_head.h> | 16 | #include <linux/buffer_head.h> |
| 18 | 17 | ||
| @@ -383,7 +382,7 @@ struct gfs2_journal_extent { | |||
| 383 | struct gfs2_jdesc { | 382 | struct gfs2_jdesc { |
| 384 | struct list_head jd_list; | 383 | struct list_head jd_list; |
| 385 | struct list_head extent_list; | 384 | struct list_head extent_list; |
| 386 | struct slow_work jd_work; | 385 | struct work_struct jd_work; |
| 387 | struct inode *jd_inode; | 386 | struct inode *jd_inode; |
| 388 | unsigned long jd_flags; | 387 | unsigned long jd_flags; |
| 389 | #define JDF_RECOVERY 1 | 388 | #define JDF_RECOVERY 1 |
diff --git a/fs/gfs2/main.c b/fs/gfs2/main.c index fb2a5f93b7c3..b1e9630eb46a 100644 --- a/fs/gfs2/main.c +++ b/fs/gfs2/main.c | |||
| @@ -15,7 +15,6 @@ | |||
| 15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
| 16 | #include <linux/gfs2_ondisk.h> | 16 | #include <linux/gfs2_ondisk.h> |
| 17 | #include <asm/atomic.h> | 17 | #include <asm/atomic.h> |
| 18 | #include <linux/slow-work.h> | ||
| 19 | 18 | ||
| 20 | #include "gfs2.h" | 19 | #include "gfs2.h" |
| 21 | #include "incore.h" | 20 | #include "incore.h" |
| @@ -24,6 +23,7 @@ | |||
| 24 | #include "util.h" | 23 | #include "util.h" |
| 25 | #include "glock.h" | 24 | #include "glock.h" |
| 26 | #include "quota.h" | 25 | #include "quota.h" |
| 26 | #include "recovery.h" | ||
| 27 | 27 | ||
| 28 | static struct shrinker qd_shrinker = { | 28 | static struct shrinker qd_shrinker = { |
| 29 | .shrink = gfs2_shrink_qd_memory, | 29 | .shrink = gfs2_shrink_qd_memory, |
| @@ -138,9 +138,11 @@ static int __init init_gfs2_fs(void) | |||
| 138 | if (error) | 138 | if (error) |
| 139 | goto fail_unregister; | 139 | goto fail_unregister; |
| 140 | 140 | ||
| 141 | error = slow_work_register_user(THIS_MODULE); | 141 | error = -ENOMEM; |
| 142 | if (error) | 142 | gfs_recovery_wq = alloc_workqueue("gfs_recovery", |
| 143 | goto fail_slow; | 143 | WQ_NON_REENTRANT | WQ_RESCUER, 0); |
| 144 | if (!gfs_recovery_wq) | ||
| 145 | goto fail_wq; | ||
| 144 | 146 | ||
| 145 | gfs2_register_debugfs(); | 147 | gfs2_register_debugfs(); |
| 146 | 148 | ||
| @@ -148,7 +150,7 @@ static int __init init_gfs2_fs(void) | |||
| 148 | 150 | ||
| 149 | return 0; | 151 | return 0; |
| 150 | 152 | ||
| 151 | fail_slow: | 153 | fail_wq: |
| 152 | unregister_filesystem(&gfs2meta_fs_type); | 154 | unregister_filesystem(&gfs2meta_fs_type); |
| 153 | fail_unregister: | 155 | fail_unregister: |
| 154 | unregister_filesystem(&gfs2_fs_type); | 156 | unregister_filesystem(&gfs2_fs_type); |
| @@ -190,7 +192,7 @@ static void __exit exit_gfs2_fs(void) | |||
| 190 | gfs2_unregister_debugfs(); | 192 | gfs2_unregister_debugfs(); |
| 191 | unregister_filesystem(&gfs2_fs_type); | 193 | unregister_filesystem(&gfs2_fs_type); |
| 192 | unregister_filesystem(&gfs2meta_fs_type); | 194 | unregister_filesystem(&gfs2meta_fs_type); |
| 193 | slow_work_unregister_user(THIS_MODULE); | 195 | destroy_workqueue(gfs_recovery_wq); |
| 194 | 196 | ||
| 195 | kmem_cache_destroy(gfs2_quotad_cachep); | 197 | kmem_cache_destroy(gfs2_quotad_cachep); |
| 196 | kmem_cache_destroy(gfs2_rgrpd_cachep); | 198 | kmem_cache_destroy(gfs2_rgrpd_cachep); |
diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index 3593b3a7290e..9a08e1bd6fbd 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c | |||
| @@ -17,7 +17,6 @@ | |||
| 17 | #include <linux/namei.h> | 17 | #include <linux/namei.h> |
| 18 | #include <linux/mount.h> | 18 | #include <linux/mount.h> |
| 19 | #include <linux/gfs2_ondisk.h> | 19 | #include <linux/gfs2_ondisk.h> |
| 20 | #include <linux/slow-work.h> | ||
| 21 | #include <linux/quotaops.h> | 20 | #include <linux/quotaops.h> |
| 22 | 21 | ||
| 23 | #include "gfs2.h" | 22 | #include "gfs2.h" |
| @@ -673,7 +672,7 @@ static int gfs2_jindex_hold(struct gfs2_sbd *sdp, struct gfs2_holder *ji_gh) | |||
| 673 | break; | 672 | break; |
| 674 | 673 | ||
| 675 | INIT_LIST_HEAD(&jd->extent_list); | 674 | INIT_LIST_HEAD(&jd->extent_list); |
| 676 | slow_work_init(&jd->jd_work, &gfs2_recover_ops); | 675 | INIT_WORK(&jd->jd_work, gfs2_recover_func); |
| 677 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); | 676 | jd->jd_inode = gfs2_lookupi(sdp->sd_jindex, &name, 1); |
| 678 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { | 677 | if (!jd->jd_inode || IS_ERR(jd->jd_inode)) { |
| 679 | if (!jd->jd_inode) | 678 | if (!jd->jd_inode) |
| @@ -782,7 +781,8 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
| 782 | if (sdp->sd_lockstruct.ls_first) { | 781 | if (sdp->sd_lockstruct.ls_first) { |
| 783 | unsigned int x; | 782 | unsigned int x; |
| 784 | for (x = 0; x < sdp->sd_journals; x++) { | 783 | for (x = 0; x < sdp->sd_journals; x++) { |
| 785 | error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x)); | 784 | error = gfs2_recover_journal(gfs2_jdesc_find(sdp, x), |
| 785 | true); | ||
| 786 | if (error) { | 786 | if (error) { |
| 787 | fs_err(sdp, "error recovering journal %u: %d\n", | 787 | fs_err(sdp, "error recovering journal %u: %d\n", |
| 788 | x, error); | 788 | x, error); |
| @@ -792,7 +792,7 @@ static int init_journal(struct gfs2_sbd *sdp, int undo) | |||
| 792 | 792 | ||
| 793 | gfs2_others_may_mount(sdp); | 793 | gfs2_others_may_mount(sdp); |
| 794 | } else if (!sdp->sd_args.ar_spectator) { | 794 | } else if (!sdp->sd_args.ar_spectator) { |
| 795 | error = gfs2_recover_journal(sdp->sd_jdesc); | 795 | error = gfs2_recover_journal(sdp->sd_jdesc, true); |
| 796 | if (error) { | 796 | if (error) { |
| 797 | fs_err(sdp, "error recovering my journal: %d\n", error); | 797 | fs_err(sdp, "error recovering my journal: %d\n", error); |
| 798 | goto fail_jinode_gh; | 798 | goto fail_jinode_gh; |
diff --git a/fs/gfs2/recovery.c b/fs/gfs2/recovery.c index 4b9bece3d437..f7f89a94a5a4 100644 --- a/fs/gfs2/recovery.c +++ b/fs/gfs2/recovery.c | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include <linux/buffer_head.h> | 14 | #include <linux/buffer_head.h> |
| 15 | #include <linux/gfs2_ondisk.h> | 15 | #include <linux/gfs2_ondisk.h> |
| 16 | #include <linux/crc32.h> | 16 | #include <linux/crc32.h> |
| 17 | #include <linux/slow-work.h> | ||
| 18 | 17 | ||
| 19 | #include "gfs2.h" | 18 | #include "gfs2.h" |
| 20 | #include "incore.h" | 19 | #include "incore.h" |
| @@ -28,6 +27,8 @@ | |||
| 28 | #include "util.h" | 27 | #include "util.h" |
| 29 | #include "dir.h" | 28 | #include "dir.h" |
| 30 | 29 | ||
| 30 | struct workqueue_struct *gfs_recovery_wq; | ||
| 31 | |||
| 31 | int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, | 32 | int gfs2_replay_read_block(struct gfs2_jdesc *jd, unsigned int blk, |
| 32 | struct buffer_head **bh) | 33 | struct buffer_head **bh) |
| 33 | { | 34 | { |
| @@ -443,23 +444,7 @@ static void gfs2_recovery_done(struct gfs2_sbd *sdp, unsigned int jid, | |||
| 443 | kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp); | 444 | kobject_uevent_env(&sdp->sd_kobj, KOBJ_CHANGE, envp); |
| 444 | } | 445 | } |
| 445 | 446 | ||
| 446 | static int gfs2_recover_get_ref(struct slow_work *work) | 447 | void gfs2_recover_func(struct work_struct *work) |
| 447 | { | ||
| 448 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); | ||
| 449 | if (test_and_set_bit(JDF_RECOVERY, &jd->jd_flags)) | ||
| 450 | return -EBUSY; | ||
| 451 | return 0; | ||
| 452 | } | ||
| 453 | |||
| 454 | static void gfs2_recover_put_ref(struct slow_work *work) | ||
| 455 | { | ||
| 456 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); | ||
| 457 | clear_bit(JDF_RECOVERY, &jd->jd_flags); | ||
| 458 | smp_mb__after_clear_bit(); | ||
| 459 | wake_up_bit(&jd->jd_flags, JDF_RECOVERY); | ||
| 460 | } | ||
| 461 | |||
| 462 | static void gfs2_recover_work(struct slow_work *work) | ||
| 463 | { | 448 | { |
| 464 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); | 449 | struct gfs2_jdesc *jd = container_of(work, struct gfs2_jdesc, jd_work); |
| 465 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); | 450 | struct gfs2_inode *ip = GFS2_I(jd->jd_inode); |
| @@ -578,7 +563,7 @@ static void gfs2_recover_work(struct slow_work *work) | |||
| 578 | gfs2_glock_dq_uninit(&j_gh); | 563 | gfs2_glock_dq_uninit(&j_gh); |
| 579 | 564 | ||
| 580 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); | 565 | fs_info(sdp, "jid=%u: Done\n", jd->jd_jid); |
| 581 | return; | 566 | goto done; |
| 582 | 567 | ||
| 583 | fail_gunlock_tr: | 568 | fail_gunlock_tr: |
| 584 | gfs2_glock_dq_uninit(&t_gh); | 569 | gfs2_glock_dq_uninit(&t_gh); |
| @@ -590,32 +575,35 @@ fail_gunlock_j: | |||
| 590 | } | 575 | } |
| 591 | 576 | ||
| 592 | fs_info(sdp, "jid=%u: %s\n", jd->jd_jid, (error) ? "Failed" : "Done"); | 577 | fs_info(sdp, "jid=%u: %s\n", jd->jd_jid, (error) ? "Failed" : "Done"); |
| 593 | |||
| 594 | fail: | 578 | fail: |
| 595 | gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP); | 579 | gfs2_recovery_done(sdp, jd->jd_jid, LM_RD_GAVEUP); |
| 580 | done: | ||
| 581 | clear_bit(JDF_RECOVERY, &jd->jd_flags); | ||
| 582 | smp_mb__after_clear_bit(); | ||
| 583 | wake_up_bit(&jd->jd_flags, JDF_RECOVERY); | ||
| 596 | } | 584 | } |
| 597 | 585 | ||
| 598 | struct slow_work_ops gfs2_recover_ops = { | ||
| 599 | .owner = THIS_MODULE, | ||
| 600 | .get_ref = gfs2_recover_get_ref, | ||
| 601 | .put_ref = gfs2_recover_put_ref, | ||
| 602 | .execute = gfs2_recover_work, | ||
| 603 | }; | ||
| 604 | |||
| 605 | |||
| 606 | static int gfs2_recovery_wait(void *word) | 586 | static int gfs2_recovery_wait(void *word) |
| 607 | { | 587 | { |
| 608 | schedule(); | 588 | schedule(); |
| 609 | return 0; | 589 | return 0; |
| 610 | } | 590 | } |
| 611 | 591 | ||
| 612 | int gfs2_recover_journal(struct gfs2_jdesc *jd) | 592 | int gfs2_recover_journal(struct gfs2_jdesc *jd, bool wait) |
| 613 | { | 593 | { |
| 614 | int rv; | 594 | int rv; |
| 615 | rv = slow_work_enqueue(&jd->jd_work); | 595 | |
| 616 | if (rv) | 596 | if (test_and_set_bit(JDF_RECOVERY, &jd->jd_flags)) |
| 617 | return rv; | 597 | return -EBUSY; |
| 618 | wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait, TASK_UNINTERRUPTIBLE); | 598 | |
| 599 | /* we have JDF_RECOVERY, queue should always succeed */ | ||
| 600 | rv = queue_work(gfs_recovery_wq, &jd->jd_work); | ||
| 601 | BUG_ON(!rv); | ||
| 602 | |||
| 603 | if (wait) | ||
| 604 | wait_on_bit(&jd->jd_flags, JDF_RECOVERY, gfs2_recovery_wait, | ||
| 605 | TASK_UNINTERRUPTIBLE); | ||
| 606 | |||
| 619 | return 0; | 607 | return 0; |
| 620 | } | 608 | } |
| 621 | 609 | ||
diff --git a/fs/gfs2/recovery.h b/fs/gfs2/recovery.h index 1616ac22569a..2226136c7647 100644 --- a/fs/gfs2/recovery.h +++ b/fs/gfs2/recovery.h | |||
| @@ -12,6 +12,8 @@ | |||
| 12 | 12 | ||
| 13 | #include "incore.h" | 13 | #include "incore.h" |
| 14 | 14 | ||
| 15 | extern struct workqueue_struct *gfs_recovery_wq; | ||
| 16 | |||
| 15 | static inline void gfs2_replay_incr_blk(struct gfs2_sbd *sdp, unsigned int *blk) | 17 | static inline void gfs2_replay_incr_blk(struct gfs2_sbd *sdp, unsigned int *blk) |
| 16 | { | 18 | { |
| 17 | if (++*blk == sdp->sd_jdesc->jd_blocks) | 19 | if (++*blk == sdp->sd_jdesc->jd_blocks) |
| @@ -27,8 +29,8 @@ extern void gfs2_revoke_clean(struct gfs2_sbd *sdp); | |||
| 27 | 29 | ||
| 28 | extern int gfs2_find_jhead(struct gfs2_jdesc *jd, | 30 | extern int gfs2_find_jhead(struct gfs2_jdesc *jd, |
| 29 | struct gfs2_log_header_host *head); | 31 | struct gfs2_log_header_host *head); |
| 30 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd); | 32 | extern int gfs2_recover_journal(struct gfs2_jdesc *gfs2_jd, bool wait); |
| 31 | extern struct slow_work_ops gfs2_recover_ops; | 33 | extern void gfs2_recover_func(struct work_struct *work); |
| 32 | 34 | ||
| 33 | #endif /* __RECOVERY_DOT_H__ */ | 35 | #endif /* __RECOVERY_DOT_H__ */ |
| 34 | 36 | ||
diff --git a/fs/gfs2/sys.c b/fs/gfs2/sys.c index 37f5393e68e6..6b60316ae327 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; |
| @@ -352,7 +353,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) { | 353 | list_for_each_entry(jd, &sdp->sd_jindex_list, jd_list) { |
| 353 | if (jd->jd_jid != jid) | 354 | if (jd->jd_jid != jid) |
| 354 | continue; | 355 | continue; |
| 355 | rv = slow_work_enqueue(&jd->jd_work); | 356 | rv = gfs2_recover_journal(jd, false); |
| 356 | break; | 357 | break; |
| 357 | } | 358 | } |
| 358 | out: | 359 | out: |
