aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r--fs/gfs2/log.c57
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
623static 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
652static 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);