aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/reiserfs/journal.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c
index ca8d9e86571f..6c1d0c35f9e9 100644
--- a/fs/reiserfs/journal.c
+++ b/fs/reiserfs/journal.c
@@ -615,6 +615,31 @@ static int journal_list_still_alive(struct super_block *s,
615 return 0; 615 return 0;
616} 616}
617 617
618/*
619 * If page->mapping was null, we failed to truncate this page for
620 * some reason. Most likely because it was truncated after being
621 * logged via data=journal.
622 *
623 * This does a check to see if the buffer belongs to one of these
624 * lost pages before doing the final put_bh. If page->mapping was
625 * null, it tries to free buffers on the page, which should make the
626 * final page_cache_release drop the page from the lru.
627 */
628static void release_buffer_page(struct buffer_head *bh)
629{
630 struct page *page = bh->b_page;
631 if (!page->mapping && !TestSetPageLocked(page)) {
632 page_cache_get(page);
633 put_bh(bh);
634 if (!page->mapping)
635 try_to_free_buffers(page);
636 unlock_page(page);
637 page_cache_release(page);
638 } else {
639 put_bh(bh);
640 }
641}
642
618static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate) 643static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
619{ 644{
620 char b[BDEVNAME_SIZE]; 645 char b[BDEVNAME_SIZE];
@@ -628,8 +653,9 @@ static void reiserfs_end_buffer_io_sync(struct buffer_head *bh, int uptodate)
628 set_buffer_uptodate(bh); 653 set_buffer_uptodate(bh);
629 else 654 else
630 clear_buffer_uptodate(bh); 655 clear_buffer_uptodate(bh);
656
631 unlock_buffer(bh); 657 unlock_buffer(bh);
632 put_bh(bh); 658 release_buffer_page(bh);
633} 659}
634 660
635static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate) 661static void reiserfs_end_ordered_io(struct buffer_head *bh, int uptodate)
@@ -1547,9 +1573,10 @@ static int flush_journal_list(struct super_block *s,
1547 BUG_ON(!test_clear_buffer_journal_dirty 1573 BUG_ON(!test_clear_buffer_journal_dirty
1548 (cn->bh)); 1574 (cn->bh));
1549 1575
1550 /* undo the inc from journal_mark_dirty */ 1576 /* drop one ref for us */
1551 put_bh(cn->bh); 1577 put_bh(cn->bh);
1552 brelse(cn->bh); 1578 /* drop one ref for journal_mark_dirty */
1579 release_buffer_page(cn->bh);
1553 } 1580 }
1554 cn = cn->next; 1581 cn = cn->next;
1555 } 1582 }
@@ -3709,13 +3736,8 @@ int journal_mark_freed(struct reiserfs_transaction_handle *th,
3709 } 3736 }
3710 } 3737 }
3711 3738
3712 if (bh) { 3739 if (bh)
3713 put_bh(bh); /* get_hash grabs the buffer */ 3740 release_buffer_page(bh); /* get_hash grabs the buffer */
3714 if (atomic_read(&(bh->b_count)) < 0) {
3715 reiserfs_warning(p_s_sb,
3716 "journal-2165: bh->b_count < 0");
3717 }
3718 }
3719 return 0; 3741 return 0;
3720} 3742}
3721 3743