aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/lops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/gfs2/lops.c')
-rw-r--r--fs/gfs2/lops.c160
1 files changed, 40 insertions, 120 deletions
diff --git a/fs/gfs2/lops.c b/fs/gfs2/lops.c
index 3ec587135d46..7e2d4e692b50 100644
--- a/fs/gfs2/lops.c
+++ b/fs/gfs2/lops.c
@@ -555,10 +555,11 @@ static void databuf_lo_add(struct gfs2_sbd *sdp, struct gfs2_log_element *le)
555 if (gfs2_is_jdata(ip)) { 555 if (gfs2_is_jdata(ip)) {
556 gfs2_pin(sdp, bd->bd_bh); 556 gfs2_pin(sdp, bd->bd_bh);
557 tr->tr_num_databuf_new++; 557 tr->tr_num_databuf_new++;
558 sdp->sd_log_num_jdata++; 558 sdp->sd_log_num_databuf++;
559 list_add(&le->le_list, &sdp->sd_log_le_databuf);
560 } else {
561 list_add(&le->le_list, &sdp->sd_log_le_ordered);
559 } 562 }
560 sdp->sd_log_num_databuf++;
561 list_add(&le->le_list, &sdp->sd_log_le_databuf);
562out: 563out:
563 gfs2_log_unlock(sdp); 564 gfs2_log_unlock(sdp);
564 unlock_buffer(bd->bd_bh); 565 unlock_buffer(bd->bd_bh);
@@ -583,114 +584,59 @@ static int gfs2_check_magic(struct buffer_head *bh)
583/** 584/**
584 * databuf_lo_before_commit - Scan the data buffers, writing as we go 585 * databuf_lo_before_commit - Scan the data buffers, writing as we go
585 * 586 *
586 * Here we scan through the lists of buffers and make the assumption
587 * that any buffer thats been pinned is being journaled, and that
588 * any unpinned buffer is an ordered write data buffer and therefore
589 * will be written back rather than journaled.
590 */ 587 */
588
591static void databuf_lo_before_commit(struct gfs2_sbd *sdp) 589static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
592{ 590{
593 LIST_HEAD(started); 591 struct gfs2_bufdata *bd1 = NULL, *bd2;
594 struct gfs2_bufdata *bd1 = NULL, *bd2, *bdt;
595 struct buffer_head *bh = NULL,*bh1 = NULL; 592 struct buffer_head *bh = NULL,*bh1 = NULL;
596 struct gfs2_log_descriptor *ld; 593 struct gfs2_log_descriptor *ld;
597 unsigned int limit; 594 unsigned int limit;
598 unsigned int total_dbuf; 595 unsigned int total;
599 unsigned int total_jdata;
600 unsigned int num, n; 596 unsigned int num, n;
601 __be64 *ptr = NULL; 597 __be64 *ptr = NULL;
598 int magic;
599
602 600
603 limit = databuf_limit(sdp); 601 limit = databuf_limit(sdp);
604 602
605 /*
606 * Start writing ordered buffers, write journaled buffers
607 * into the log along with a header
608 */
609 gfs2_log_lock(sdp); 603 gfs2_log_lock(sdp);
610 total_dbuf = sdp->sd_log_num_databuf; 604 total = sdp->sd_log_num_databuf;
611 total_jdata = sdp->sd_log_num_jdata;
612 bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf, 605 bd2 = bd1 = list_prepare_entry(bd1, &sdp->sd_log_le_databuf,
613 bd_le.le_list); 606 bd_le.le_list);
614 while(total_dbuf) { 607 while(total) {
615 num = total_jdata; 608 num = total;
616 if (num > limit) 609 if (num > limit)
617 num = limit; 610 num = limit;
611
612 gfs2_log_unlock(sdp);
613 bh = gfs2_log_get_buf(sdp);
614 gfs2_log_lock(sdp);
615
616 ld = (struct gfs2_log_descriptor *)bh->b_data;
617 ptr = (__be64 *)(bh->b_data + DATABUF_OFFSET);
618 ld->ld_header.mh_magic = cpu_to_be32(GFS2_MAGIC);
619 ld->ld_header.mh_type = cpu_to_be32(GFS2_METATYPE_LD);
620 ld->ld_header.mh_format = cpu_to_be32(GFS2_FORMAT_LD);
621 ld->ld_type = cpu_to_be32(GFS2_LOG_DESC_JDATA);
622 ld->ld_length = cpu_to_be32(num + 1);
623 ld->ld_data1 = cpu_to_be32(num);
624 ld->ld_data2 = cpu_to_be32(0);
625 memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved));
626
618 n = 0; 627 n = 0;
619 list_for_each_entry_safe_continue(bd1, bdt, 628 list_for_each_entry_continue(bd1, &sdp->sd_log_le_databuf,
620 &sdp->sd_log_le_databuf, 629 bd_le.le_list) {
621 bd_le.le_list) {
622 /* store off the buffer head in a local ptr since
623 * gfs2_bufdata might change when we drop the log lock
624 */
625 bh1 = bd1->bd_bh; 630 bh1 = bd1->bd_bh;
626 631
627 /* An ordered write buffer */ 632 magic = gfs2_check_magic(bh1);
628 if (bh1 && !buffer_pinned(bh1)) { 633 *ptr++ = cpu_to_be64(bh1->b_blocknr);
629 list_move(&bd1->bd_le.le_list, &started); 634 *ptr++ = cpu_to_be64((__u64)magic);
630 if (bd1 == bd2) { 635 clear_buffer_escaped(bh1);
631 bd2 = NULL; 636 if (unlikely(magic != 0))
632 bd2 = list_prepare_entry(bd2, 637 set_buffer_escaped(bh1);
633 &sdp->sd_log_le_databuf, 638 if (++n >= num)
634 bd_le.le_list); 639 break;
635 }
636 total_dbuf--;
637 if (bh1) {
638 if (buffer_dirty(bh1)) {
639 get_bh(bh1);
640
641 gfs2_log_unlock(sdp);
642
643 ll_rw_block(SWRITE, 1, &bh1);
644 brelse(bh1);
645
646 gfs2_log_lock(sdp);
647 }
648 continue;
649 }
650 continue;
651 } else if (bh1) { /* A journaled buffer */
652 int magic;
653 gfs2_log_unlock(sdp);
654 if (!bh) {
655 bh = gfs2_log_get_buf(sdp);
656 ld = (struct gfs2_log_descriptor *)
657 bh->b_data;
658 ptr = (__be64 *)(bh->b_data +
659 DATABUF_OFFSET);
660 ld->ld_header.mh_magic =
661 cpu_to_be32(GFS2_MAGIC);
662 ld->ld_header.mh_type =
663 cpu_to_be32(GFS2_METATYPE_LD);
664 ld->ld_header.mh_format =
665 cpu_to_be32(GFS2_FORMAT_LD);
666 ld->ld_type =
667 cpu_to_be32(GFS2_LOG_DESC_JDATA);
668 ld->ld_length = cpu_to_be32(num + 1);
669 ld->ld_data1 = cpu_to_be32(num);
670 ld->ld_data2 = cpu_to_be32(0);
671 memset(ld->ld_reserved, 0, sizeof(ld->ld_reserved));
672 }
673 magic = gfs2_check_magic(bh1);
674 *ptr++ = cpu_to_be64(bh1->b_blocknr);
675 *ptr++ = cpu_to_be64((__u64)magic);
676 clear_buffer_escaped(bh1);
677 if (unlikely(magic != 0))
678 set_buffer_escaped(bh1);
679 gfs2_log_lock(sdp);
680 if (++n >= num)
681 break;
682 } else if (!bh1) {
683 total_dbuf--;
684 sdp->sd_log_num_databuf--;
685 list_del_init(&bd1->bd_le.le_list);
686 if (bd1 == bd2) {
687 bd2 = NULL;
688 bd2 = list_prepare_entry(bd2,
689 &sdp->sd_log_le_databuf,
690 bd_le.le_list);
691 }
692 kmem_cache_free(gfs2_bufdata_cachep, bd1);
693 }
694 } 640 }
695 gfs2_log_unlock(sdp); 641 gfs2_log_unlock(sdp);
696 if (bh) { 642 if (bh) {
@@ -727,34 +673,10 @@ static void databuf_lo_before_commit(struct gfs2_sbd *sdp)
727 break; 673 break;
728 } 674 }
729 bh = NULL; 675 bh = NULL;
730 BUG_ON(total_dbuf < num); 676 BUG_ON(total < num);
731 total_dbuf -= num; 677 total -= num;
732 total_jdata -= num;
733 } 678 }
734 gfs2_log_unlock(sdp); 679 gfs2_log_unlock(sdp);
735
736 /* Wait on all ordered buffers */
737 while (!list_empty(&started)) {
738 gfs2_log_lock(sdp);
739 bd1 = list_entry(started.next, struct gfs2_bufdata,
740 bd_le.le_list);
741 list_del_init(&bd1->bd_le.le_list);
742 sdp->sd_log_num_databuf--;
743 bh = bd1->bd_bh;
744 if (bh) {
745 bh->b_private = NULL;
746 get_bh(bh);
747 gfs2_log_unlock(sdp);
748 wait_on_buffer(bh);
749 brelse(bh);
750 } else
751 gfs2_log_unlock(sdp);
752
753 kmem_cache_free(gfs2_bufdata_cachep, bd1);
754 }
755
756 /* We've removed all the ordered write bufs here, so only jdata left */
757 gfs2_assert_warn(sdp, sdp->sd_log_num_databuf == sdp->sd_log_num_jdata);
758} 680}
759 681
760static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start, 682static int databuf_lo_scan_elements(struct gfs2_jdesc *jd, unsigned int start,
@@ -838,11 +760,9 @@ static void databuf_lo_after_commit(struct gfs2_sbd *sdp, struct gfs2_ail *ai)
838 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list); 760 bd = list_entry(head->next, struct gfs2_bufdata, bd_le.le_list);
839 list_del_init(&bd->bd_le.le_list); 761 list_del_init(&bd->bd_le.le_list);
840 sdp->sd_log_num_databuf--; 762 sdp->sd_log_num_databuf--;
841 sdp->sd_log_num_jdata--;
842 gfs2_unpin(sdp, bd->bd_bh, ai); 763 gfs2_unpin(sdp, bd->bd_bh, ai);
843 } 764 }
844 gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf); 765 gfs2_assert_warn(sdp, !sdp->sd_log_num_databuf);
845 gfs2_assert_warn(sdp, !sdp->sd_log_num_jdata);
846} 766}
847 767
848 768