diff options
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 57 |
1 files changed, 55 insertions, 2 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index d8232ec25397..20fa528d457d 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -620,6 +620,57 @@ static void log_flush_commit(struct gfs2_sbd *sdp) | |||
620 | } | 620 | } |
621 | } | 621 | } |
622 | 622 | ||
623 | static void gfs2_ordered_write(struct gfs2_sbd *sdp) | ||
624 | { | ||
625 | struct gfs2_bufdata *bd; | ||
626 | struct buffer_head *bh; | ||
627 | LIST_HEAD(written); | ||
628 | |||
629 | gfs2_log_lock(sdp); | ||
630 | while (!list_empty(&sdp->sd_log_le_ordered)) { | ||
631 | bd = list_entry(sdp->sd_log_le_ordered.next, struct gfs2_bufdata, bd_le.le_list); | ||
632 | list_move(&bd->bd_le.le_list, &written); | ||
633 | bh = bd->bd_bh; | ||
634 | if (!buffer_dirty(bh)) | ||
635 | continue; | ||
636 | get_bh(bh); | ||
637 | gfs2_log_unlock(sdp); | ||
638 | lock_buffer(bh); | ||
639 | if (test_clear_buffer_dirty(bh)) { | ||
640 | bh->b_end_io = end_buffer_write_sync; | ||
641 | submit_bh(WRITE, bh); | ||
642 | } else { | ||
643 | unlock_buffer(bh); | ||
644 | brelse(bh); | ||
645 | } | ||
646 | gfs2_log_lock(sdp); | ||
647 | } | ||
648 | list_splice(&written, &sdp->sd_log_le_ordered); | ||
649 | gfs2_log_unlock(sdp); | ||
650 | } | ||
651 | |||
652 | static void gfs2_ordered_wait(struct gfs2_sbd *sdp) | ||
653 | { | ||
654 | struct gfs2_bufdata *bd; | ||
655 | struct buffer_head *bh; | ||
656 | |||
657 | gfs2_log_lock(sdp); | ||
658 | while (!list_empty(&sdp->sd_log_le_ordered)) { | ||
659 | bd = list_entry(sdp->sd_log_le_ordered.prev, struct gfs2_bufdata, bd_le.le_list); | ||
660 | bh = bd->bd_bh; | ||
661 | if (buffer_locked(bh)) { | ||
662 | get_bh(bh); | ||
663 | gfs2_log_unlock(sdp); | ||
664 | wait_on_buffer(bh); | ||
665 | brelse(bh); | ||
666 | gfs2_log_lock(sdp); | ||
667 | continue; | ||
668 | } | ||
669 | list_del_init(&bd->bd_le.le_list); | ||
670 | } | ||
671 | gfs2_log_unlock(sdp); | ||
672 | } | ||
673 | |||
623 | /** | 674 | /** |
624 | * gfs2_log_flush - flush incore transaction(s) | 675 | * gfs2_log_flush - flush incore transaction(s) |
625 | * @sdp: the filesystem | 676 | * @sdp: the filesystem |
@@ -648,7 +699,7 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
648 | INIT_LIST_HEAD(&ai->ai_ail2_list); | 699 | INIT_LIST_HEAD(&ai->ai_ail2_list); |
649 | 700 | ||
650 | gfs2_assert_withdraw(sdp, | 701 | gfs2_assert_withdraw(sdp, |
651 | sdp->sd_log_num_buf + sdp->sd_log_num_jdata == | 702 | sdp->sd_log_num_buf + sdp->sd_log_num_databuf == |
652 | sdp->sd_log_commited_buf + | 703 | sdp->sd_log_commited_buf + |
653 | sdp->sd_log_commited_databuf); | 704 | sdp->sd_log_commited_databuf); |
654 | gfs2_assert_withdraw(sdp, | 705 | gfs2_assert_withdraw(sdp, |
@@ -658,7 +709,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl) | |||
658 | sdp->sd_log_flush_wrapped = 0; | 709 | sdp->sd_log_flush_wrapped = 0; |
659 | ai->ai_first = sdp->sd_log_flush_head; | 710 | ai->ai_first = sdp->sd_log_flush_head; |
660 | 711 | ||
712 | gfs2_ordered_write(sdp); | ||
661 | lops_before_commit(sdp); | 713 | lops_before_commit(sdp); |
714 | gfs2_ordered_wait(sdp); | ||
715 | |||
662 | if (!list_empty(&sdp->sd_log_flush_list)) | 716 | if (!list_empty(&sdp->sd_log_flush_list)) |
663 | log_flush_commit(sdp); | 717 | log_flush_commit(sdp); |
664 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ | 718 | else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ |
@@ -751,7 +805,6 @@ void gfs2_log_shutdown(struct gfs2_sbd *sdp) | |||
751 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); | 805 | gfs2_assert_withdraw(sdp, !sdp->sd_log_blks_reserved); |
752 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_gl); | 806 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_gl); |
753 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); | 807 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_buf); |
754 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_jdata); | ||
755 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); | 808 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_revoke); |
756 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); | 809 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_rg); |
757 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); | 810 | gfs2_assert_withdraw(sdp, !sdp->sd_log_num_databuf); |