diff options
author | Steven Whitehouse <swhiteho@redhat.com> | 2012-03-09 05:45:56 -0500 |
---|---|---|
committer | Steven Whitehouse <swhiteho@redhat.com> | 2012-03-09 09:07:06 -0500 |
commit | 34cc1781c2ae921107e89f6633cfab7436e355ba (patch) | |
tree | e9577ab5ca926d6f2aaa8f0a0b28222c87071088 /fs | |
parent | 75ca61c101601a7071d93571920be9697b3fda9b (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.c | 131 |
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 | ||
501 | static void log_write_header(struct gfs2_sbd *sdp, u32 flags, int pull) | 495 | static 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 | |||
553 | static 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 | ||
570 | static int bd_cmp(void *priv, struct list_head *a, struct list_head *b) | 510 | static 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 | |||
583 | static 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); |