aboutsummaryrefslogtreecommitdiffstats
path: root/fs/gfs2/ops_address.c
diff options
context:
space:
mode:
authorSteven Whitehouse <swhiteho@redhat.com>2007-09-02 05:48:13 -0400
committerSteven Whitehouse <swhiteho@redhat.com>2007-10-10 03:56:03 -0400
commitd7b616e252b125f12b007c392f7644053bb6f140 (patch)
tree0794272905a1876ef74144a993f7a76400893813 /fs/gfs2/ops_address.c
parent9b9107a5a8b190e6cf09bbdf893869c6a9c482cc (diff)
[GFS2] Clean up ordered write code
The following patch removes the ordered write processing from databuf_lo_before_commit() and moves it to log.c. This has the effect of greatly simplyfying databuf_lo_before_commit() and well as potentially making the ordered write code more efficient. As a side effect of this, its now possible to remove ordered buffers from the ordered buffer list at any time, so we now make use of this in invalidatepage and releasepage to ensure timely release of these buffers. Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs/gfs2/ops_address.c')
-rw-r--r--fs/gfs2/ops_address.c50
1 files changed, 46 insertions, 4 deletions
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 8407d1db4eac..dd1ea491ddcb 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -616,13 +616,50 @@ static sector_t gfs2_bmap(struct address_space *mapping, sector_t lblock)
616 return dblock; 616 return dblock;
617} 617}
618 618
619static void gfs2_discard(struct gfs2_sbd *sdp, struct buffer_head *bh)
620{
621 struct gfs2_bufdata *bd;
622
623 lock_buffer(bh);
624 gfs2_log_lock(sdp);
625 clear_buffer_dirty(bh);
626 bd = bh->b_private;
627 if (bd) {
628 if (!list_empty(&bd->bd_le.le_list)) {
629 if (!buffer_pinned(bh))
630 list_del_init(&bd->bd_le.le_list);
631 }
632 }
633 bh->b_bdev = NULL;
634 clear_buffer_mapped(bh);
635 clear_buffer_req(bh);
636 clear_buffer_new(bh);
637 gfs2_log_unlock(sdp);
638 unlock_buffer(bh);
639}
640
619static void gfs2_invalidatepage(struct page *page, unsigned long offset) 641static void gfs2_invalidatepage(struct page *page, unsigned long offset)
620{ 642{
643 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host);
644 struct buffer_head *bh, *head;
645 unsigned long pos = 0;
646
621 BUG_ON(!PageLocked(page)); 647 BUG_ON(!PageLocked(page));
622 if (offset == 0) 648 if (offset == 0)
623 ClearPageChecked(page); 649 ClearPageChecked(page);
650 if (!page_has_buffers(page))
651 goto out;
624 652
625 block_invalidatepage(page, offset); 653 bh = head = page_buffers(page);
654 do {
655 if (offset <= pos)
656 gfs2_discard(sdp, bh);
657 pos += bh->b_size;
658 bh = bh->b_this_page;
659 } while (bh != head);
660out:
661 if (offset == 0)
662 try_to_release_page(page, 0);
626} 663}
627 664
628/** 665/**
@@ -732,9 +769,14 @@ int gfs2_releasepage(struct page *page, gfp_t gfp_mask)
732 if (bd) { 769 if (bd) {
733 gfs2_assert_warn(sdp, bd->bd_bh == bh); 770 gfs2_assert_warn(sdp, bd->bd_bh == bh);
734 gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr)); 771 gfs2_assert_warn(sdp, list_empty(&bd->bd_list_tr));
735 bd->bd_bh = NULL; 772 if (!list_empty(&bd->bd_le.le_list)) {
736 if (!list_empty(&bd->bd_le.le_list)) 773 if (!buffer_pinned(bh))
737 bd = NULL; 774 list_del_init(&bd->bd_le.le_list);
775 else
776 bd = NULL;
777 }
778 if (bd)
779 bd->bd_bh = NULL;
738 bh->b_private = NULL; 780 bh->b_private = NULL;
739 } 781 }
740 gfs2_log_unlock(sdp); 782 gfs2_log_unlock(sdp);