aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <jbacik@fusionio.com>2013-04-17 10:17:05 -0400
committerJosef Bacik <jbacik@fusionio.com>2013-05-06 15:54:57 -0400
commitb8d7f3ac10a865ca727f9373a796ef8537e3a474 (patch)
tree13474b2dd380cfe289a6e28c546d9a058138053a
parentccf7f29d1a23696ca69a981adbf7eda2e13c8635 (diff)
Btrfs: don't force pages under writeback to finish when aborting
Dave reported a BUG_ON() that happened in end_page_writeback() after an abort. This happened because we unconditionally call end_page_writeback() in the endio case, which is right. However when we abort the transaction we will call end_page_writeback() on any writeback pages we find, which is wrong. We need to lock the page and wait on page writeback to complete if it is. There is nothing unsafe about this since we are discarding the transaction anyway. Thanks, Reported-by: David Sterba <dsterba@suse.cz> Signed-off-by: Josef Bacik <jbacik@fusionio.com>
-rw-r--r--fs/btrfs/disk-io.c5
1 files changed, 2 insertions, 3 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 8a7a366267ec..aab7d89f3ff0 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -3763,10 +3763,9 @@ static int btrfs_destroy_marked_extents(struct btrfs_root *root,
3763 if (eb) 3763 if (eb)
3764 ret = test_and_clear_bit(EXTENT_BUFFER_DIRTY, 3764 ret = test_and_clear_bit(EXTENT_BUFFER_DIRTY,
3765 &eb->bflags); 3765 &eb->bflags);
3766 if (PageWriteback(page))
3767 end_page_writeback(page);
3768
3769 lock_page(page); 3766 lock_page(page);
3767
3768 wait_on_page_writeback(page);
3770 if (PageDirty(page)) { 3769 if (PageDirty(page)) {
3771 clear_page_dirty_for_io(page); 3770 clear_page_dirty_for_io(page);
3772 spin_lock_irq(&page->mapping->tree_lock); 3771 spin_lock_irq(&page->mapping->tree_lock);