Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

GFS2: Clean up log flush header writing

We already send both a pre and post flush to the block device
when writing a journal header. There is no need to wait for
the previous I/O specifically when we do this, unless we've
turned "barriers" off.

As a side effect, this also cleans up the code path for flushing
the journal and makes it more readable.

Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>

+66 -65
+66 -65
fs/gfs2/log.c
··· 491 491 sdp->sd_log_tail = new_tail; 492 492 } 493 493 494 - /** 495 - * log_write_header - Get and initialize a journal header buffer 496 - * @sdp: The GFS2 superblock 497 - * 498 - * Returns: the initialized log buffer descriptor 499 - */ 500 494 501 - static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) 502 - { 503 - u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head); 504 - struct buffer_head *bh; 505 - struct gfs2_log_header *lh; 506 - unsigned int tail; 507 - u32 hash; 508 - 509 - bh = sb_getblk(sdp->sd_vfs, blkno); 510 - lock_buffer(bh); 511 - memset(bh->b_data, 0, bh->b_size); 512 - set_buffer_uptodate(bh); 513 - clear_buffer_dirty(bh); 514 - 515 - gfs2_ail1_empty(sdp); 516 - tail = current_tail(sdp); 517 - 518 - lh = (struct gfs2_log_header *)bh->b_data; 519 - memset(lh, 0, sizeof(struct gfs2_log_header)); 520 - lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 521 - lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 522 - lh->lh_header.__pad0 = cpu_to_be64(0); 523 - lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 524 - lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 525 - lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 526 - lh->lh_flags = cpu_to_be32(flags); 527 - lh->lh_tail = cpu_to_be32(tail); 528 - lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 529 - hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); 530 - lh->lh_hash = cpu_to_be32(hash); 531 - 532 - bh->b_end_io = end_buffer_write_sync; 533 - get_bh(bh); 534 - if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) 535 - submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh); 536 - else 537 - submit_bh(WRITE_FLUSH_FUA | REQ_META, bh); 538 - wait_on_buffer(bh); 539 - 540 - if (!buffer_uptodate(bh)) 541 - gfs2_io_error_bh(sdp, bh); 542 - brelse(bh); 543 - 544 - if (sdp->sd_log_tail != tail) 545 - log_pull_tail(sdp, tail); 546 - else 547 - gfs2_assert_withdraw(sdp, !pull); 548 - 549 - sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 550 - gfs2_log_incr_head(sdp); 551 - } 552 - 553 - static void log_flush_commit(struct gfs2_sbd *sdp) 495 + static void log_flush_wait(struct gfs2_sbd *sdp) 554 496 { 555 497 DEFINE_WAIT(wait); 556 498 ··· 505 563 } while(atomic_read(&sdp->sd_log_in_flight)); 506 564 finish_wait(&sdp->sd_log_flush_wait, &wait); 507 565 } 508 - 509 - log_write_header(sdp, 0, 0); 510 566 } 511 567 512 568 static int bd_cmp(void *priv, struct list_head *a, struct list_head *b) ··· 574 634 } 575 635 576 636 /** 637 + * log_write_header - Get and initialize a journal header buffer 638 + * @sdp: The GFS2 superblock 639 + * 640 + * Returns: the initialized log buffer descriptor 641 + */ 642 + 643 + static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) 644 + { 645 + u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head); 646 + struct buffer_head *bh; 647 + struct gfs2_log_header *lh; 648 + unsigned int tail; 649 + u32 hash; 650 + 651 + bh = sb_getblk(sdp->sd_vfs, blkno); 652 + lock_buffer(bh); 653 + memset(bh->b_data, 0, bh->b_size); 654 + set_buffer_uptodate(bh); 655 + clear_buffer_dirty(bh); 656 + 657 + gfs2_ail1_empty(sdp); 658 + tail = current_tail(sdp); 659 + 660 + lh = (struct gfs2_log_header *)bh->b_data; 661 + memset(lh, 0, sizeof(struct gfs2_log_header)); 662 + lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC); 663 + lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH); 664 + lh->lh_header.__pad0 = cpu_to_be64(0); 665 + lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH); 666 + lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid); 667 + lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++); 668 + lh->lh_flags = cpu_to_be32(flags); 669 + lh->lh_tail = cpu_to_be32(tail); 670 + lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head); 671 + hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header)); 672 + lh->lh_hash = cpu_to_be32(hash); 673 + 674 + bh->b_end_io = end_buffer_write_sync; 675 + get_bh(bh); 676 + if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) { 677 + gfs2_ordered_wait(sdp); 678 + log_flush_wait(sdp); 679 + submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh); 680 + } else { 681 + submit_bh(WRITE_FLUSH_FUA | REQ_META, bh); 682 + } 683 + wait_on_buffer(bh); 684 + 685 + if (!buffer_uptodate(bh)) 686 + gfs2_io_error_bh(sdp, bh); 687 + brelse(bh); 688 + 689 + if (sdp->sd_log_tail != tail) 690 + log_pull_tail(sdp, tail); 691 + else 692 + gfs2_assert_withdraw(sdp, !pull); 693 + 694 + sdp->sd_log_idle = (tail == sdp->sd_log_flush_head); 695 + gfs2_log_incr_head(sdp); 696 + } 697 + 698 + /** 577 699 * gfs2_log_flush - flush incore transaction(s) 578 700 * @sdp: the filesystem 579 701 * @gl: The glock structure to flush. If NULL, flush the whole incore log ··· 678 676 679 677 gfs2_ordered_write(sdp); 680 678 lops_before_commit(sdp); 681 - gfs2_ordered_wait(sdp); 682 679 683 - if (sdp->sd_log_head != sdp->sd_log_flush_head) 684 - log_flush_commit(sdp); 685 - else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 680 + if (sdp->sd_log_head != sdp->sd_log_flush_head) { 681 + log_write_header(sdp, 0, 0); 682 + } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 686 683 gfs2_log_lock(sdp); 687 684 atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ 688 685 trace_gfs2_log_blocks(sdp, -1);