diff options
Diffstat (limited to 'fs/gfs2/log.c')
-rw-r--r-- | fs/gfs2/log.c | 46 |
1 files changed, 32 insertions, 14 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c index f72c44231406..27e97d3de1e0 100644 --- a/fs/gfs2/log.c +++ b/fs/gfs2/log.c | |||
@@ -648,49 +648,67 @@ out_of_blocks: | |||
648 | } | 648 | } |
649 | 649 | ||
650 | /** | 650 | /** |
651 | * log_write_header - Get and initialize a journal header buffer | 651 | * write_log_header - Write a journal log header buffer at sd_log_flush_head |
652 | * @sdp: The GFS2 superblock | 652 | * @sdp: The GFS2 superblock |
653 | * @seq: sequence number | ||
654 | * @tail: tail of the log | ||
655 | * @flags: log header flags | ||
656 | * @op_flags: flags to pass to the bio | ||
653 | * | 657 | * |
654 | * Returns: the initialized log buffer descriptor | 658 | * Returns: the initialized log buffer descriptor |
655 | */ | 659 | */ |
656 | 660 | ||
657 | static void log_write_header(struct gfs2_sbd *sdp, u32 flags) | 661 | void gfs2_write_log_header(struct gfs2_sbd *sdp, u64 seq, u32 tail, |
662 | u32 flags, int op_flags) | ||
658 | { | 663 | { |
659 | struct gfs2_log_header *lh; | 664 | struct gfs2_log_header *lh; |
660 | unsigned int tail; | ||
661 | u32 hash; | 665 | u32 hash; |
662 | int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC; | ||
663 | struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); | 666 | struct page *page = mempool_alloc(gfs2_page_pool, GFP_NOIO); |
664 | enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); | 667 | |
665 | lh = page_address(page); | 668 | lh = page_address(page); |
666 | clear_page(lh); | 669 | clear_page(lh); |
667 | 670 | ||
668 | gfs2_assert_withdraw(sdp, (state != SFS_FROZEN)); | ||
669 | |||
670 | tail = current_tail(sdp); | ||
671 | |||
672 | lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); | 671 | lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); |
673 | lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); | 672 | lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); |
674 | lh->lh_header.__pad0 = cpu_to_be64(0); | 673 | lh->lh_header.__pad0 = cpu_to_be64(0); |
675 | lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); | 674 | lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); |
676 | lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); | 675 | lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); |
677 | lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); | 676 | lh->lh_sequence = cpu_to_be64(seq); |
678 | lh->lh_flags = cpu_to_be32(flags); | 677 | lh->lh_flags = cpu_to_be32(flags); |
679 | lh->lh_tail = cpu_to_be32(tail); | 678 | lh->lh_tail = cpu_to_be32(tail); |
680 | lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); | 679 | lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); |
681 | hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); | 680 | hash = gfs2_disk_hash(page_address(page), sizeof(struct gfs2_log_header)); |
682 | lh->lh_hash = cpu_to_be32(hash); | 681 | lh->lh_hash = cpu_to_be32(hash); |
683 | 682 | ||
683 | gfs2_log_write_page(sdp, page); | ||
684 | gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); | ||
685 | log_flush_wait(sdp); | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * log_write_header - Get and initialize a journal header buffer | ||
690 | * @sdp: The GFS2 superblock | ||
691 | * | ||
692 | * Returns: the initialized log buffer descriptor | ||
693 | */ | ||
694 | |||
695 | static void log_write_header(struct gfs2_sbd *sdp, u32 flags) | ||
696 | { | ||
697 | unsigned int tail; | ||
698 | int op_flags = REQ_PREFLUSH | REQ_FUA | REQ_META | REQ_SYNC; | ||
699 | enum gfs2_freeze_state state = atomic_read(&sdp->sd_freeze_state); | ||
700 | |||
701 | gfs2_assert_withdraw(sdp, (state != SFS_FROZEN)); | ||
702 | tail = current_tail(sdp); | ||
703 | |||
684 | if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { | 704 | if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { |
685 | gfs2_ordered_wait(sdp); | 705 | gfs2_ordered_wait(sdp); |
686 | log_flush_wait(sdp); | 706 | log_flush_wait(sdp); |
687 | op_flags = REQ_SYNC | REQ_META | REQ_PRIO; | 707 | op_flags = REQ_SYNC | REQ_META | REQ_PRIO; |
688 | } | 708 | } |
689 | |||
690 | sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); | 709 | sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); |
691 | gfs2_log_write_page(sdp, page); | 710 | gfs2_write_log_header(sdp, sdp->sd_log_sequence++, tail, flags, |
692 | gfs2_log_flush_bio(sdp, REQ_OP_WRITE, op_flags); | 711 | op_flags); |
693 | log_flush_wait(sdp); | ||
694 | 712 | ||
695 | if (sdp->sd_log_tail != tail) | 713 | if (sdp->sd_log_tail != tail) |
696 | log_pull_tail(sdp, tail); | 714 | log_pull_tail(sdp, tail); |