aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2012-03-09 05:45:56 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2012-03-09 09:07:06 -0500
commit34cc1781c2ae921107e89f6633cfab7436e355ba (patch)
treee9577ab5ca926d6f2aaa8f0a0b28222c87071088 /fs
parent75ca61c101601a7071d93571920be9697b3fda9b (diff)
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/log.c131
1 files changed, 66 insertions, 65 deletions
diff --git a/fs/gfs2/log.c b/fs/gfs2/log.c
index 2b9f0d9b1b28..4752eadc7f6e 100644
--- a/fs/gfs2/log.c
+++ b/fs/gfs2/log.c
@@ -491,66 +491,8 @@ static void log_pull_tail(struct gfs2_sbd *sdp, unsigned int new_tail)
491 sdp->sd_log_tail = new_tail; 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
501static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) 495static void log_flush_wait(struct gfs2_sbd *sdp)
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
553static void log_flush_commit(struct gfs2_sbd *sdp)
554{ 496{
555 DEFINE_WAIT(wait); 497 DEFINE_WAIT(wait);
556 498
@@ -563,8 +505,6 @@ static void log_flush_commit(struct gfs2_sbd *sdp)
563 } while(atomic_read(&sdp->sd_log_in_flight)); 505 } while(atomic_read(&sdp->sd_log_in_flight));
564 finish_wait(&sdp->sd_log_flush_wait, &wait); 506 finish_wait(&sdp->sd_log_flush_wait, &wait);
565 } 507 }
566
567 log_write_header(sdp, 0, 0);
568} 508}
569 509
570static int bd_cmp(void *priv, struct list_head *a, struct list_head *b) 510static int bd_cmp(void *priv, struct list_head *a, struct list_head *b)
@@ -634,6 +574,68 @@ static void gfs2_ordered_wait(struct gfs2_sbd *sdp)
634} 574}
635 575
636/** 576/**
577 * log_write_header - Get and initialize a journal header buffer
578 * @sdp: The GFS2 superblock
579 *
580 * Returns: the initialized log buffer descriptor
581 */
582
583static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull)
584{
585 u64 blkno = gfs2_log_bmap(sdp, sdp->sd_log_flush_head);
586 struct buffer_head *bh;
587 struct gfs2_log_header *lh;
588 unsigned int tail;
589 u32 hash;
590
591 bh = sb_getblk(sdp->sd_vfs, blkno);
592 lock_buffer(bh);
593 memset(bh->b_data, 0, bh->b_size);
594 set_buffer_uptodate(bh);
595 clear_buffer_dirty(bh);
596
597 gfs2_ail1_empty(sdp);
598 tail = current_tail(sdp);
599
600 lh = (struct gfs2_log_header *)bh->b_data;
601 memset(lh, 0, sizeof(struct gfs2_log_header));
602 lh->lh_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
603 lh->lh_header.mh_type = cpu_to_be32(GFS2_METATYPE_LH);
604 lh->lh_header.__pad0 = cpu_to_be64(0);
605 lh->lh_header.mh_format = cpu_to_be32(GFS2_FORMAT_LH);
606 lh->lh_header.mh_jid = cpu_to_be32(sdp->sd_jdesc->jd_jid);
607 lh->lh_sequence = cpu_to_be64(sdp->sd_log_sequence++);
608 lh->lh_flags = cpu_to_be32(flags);
609 lh->lh_tail = cpu_to_be32(tail);
610 lh->lh_blkno = cpu_to_be32(sdp->sd_log_flush_head);
611 hash = gfs2_disk_hash(bh->b_data, sizeof(struct gfs2_log_header));
612 lh->lh_hash = cpu_to_be32(hash);
613
614 bh->b_end_io = end_buffer_write_sync;
615 get_bh(bh);
616 if (test_bit(SDF_NOBARRIERS, &sdp->sd_flags)) {
617 gfs2_ordered_wait(sdp);
618 log_flush_wait(sdp);
619 submit_bh(WRITE_SYNC | REQ_META | REQ_PRIO, bh);
620 } else {
621 submit_bh(WRITE_FLUSH_FUA | REQ_META, bh);
622 }
623 wait_on_buffer(bh);
624
625 if (!buffer_uptodate(bh))
626 gfs2_io_error_bh(sdp, bh);
627 brelse(bh);
628
629 if (sdp->sd_log_tail != tail)
630 log_pull_tail(sdp, tail);
631 else
632 gfs2_assert_withdraw(sdp, !pull);
633
634 sdp->sd_log_idle = (tail == sdp->sd_log_flush_head);
635 gfs2_log_incr_head(sdp);
636}
637
638/**
637 * gfs2_log_flush - flush incore transaction(s) 639 * gfs2_log_flush - flush incore transaction(s)
638 * @sdp: the filesystem 640 * @sdp: the filesystem
639 * @gl: The glock structure to flush. If NULL, flush the whole incore log 641 * @gl: The glock structure to flush. If NULL, flush the whole incore log
@@ -676,11 +678,10 @@ void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl)
676 678
677 gfs2_ordered_write(sdp); 679 gfs2_ordered_write(sdp);
678 lops_before_commit(sdp); 680 lops_before_commit(sdp);
679 gfs2_ordered_wait(sdp);
680 681
681 if (sdp->sd_log_head != sdp->sd_log_flush_head) 682 if (sdp->sd_log_head != sdp->sd_log_flush_head) {
682 log_flush_commit(sdp); 683 log_write_header(sdp, 0, 0);
683 else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){ 684 } else if (sdp->sd_log_tail != current_tail(sdp) && !sdp->sd_log_idle){
684 gfs2_log_lock(sdp); 685 gfs2_log_lock(sdp);
685 atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */ 686 atomic_dec(&sdp->sd_log_blks_free); /* Adjust for unreserved buffer */
686 trace_gfs2_log_blocks(sdp, -1); 687 trace_gfs2_log_blocks(sdp, -1);