From 8146502820231da924ca22d147cdcf733ac9a057 Mon Sep 17 00:00:00 2001 From: Liu Bo Date: Tue, 23 Sep 2014 22:22:33 +0800 Subject: Btrfs: fix crash of btrfs_release_extent_buffer_page This is actually inspired by Filipe's patch. When write_one_eb() fails on submit_extent_page(), it'll give up writing this eb and mark it with EXTENT_BUFFER_IOERR. So if it's not the last page that encounter the failure, there are some left pages which remain DIRTY, and if a later COW on this eb happens, ie. eb is COWed and freed, it'd run into BUG_ON in btrfs_release_extent_buffer_page() for the DIRTY page, ie. BUG_ON(PageDirty(page)); This adds the missing clear_page_dirty_for_io() for the rest pages of eb. Signed-off-by: Liu Bo Reviewed-by: Filipe Manana Signed-off-by: Chris Mason --- fs/btrfs/extent_io.c | 1 + 1 file changed, 1 insertion(+) (limited to 'fs/btrfs') diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 828aded0f8aa..4267a054b9c1 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c @@ -3677,6 +3677,7 @@ static noinline_for_stack int write_one_eb(struct extent_buffer *eb, if (unlikely(ret)) { for (; i < num_pages; i++) { struct page *p = extent_buffer_page(eb, i); + clear_page_dirty_for_io(p); unlock_page(p); } } -- cgit v1.2.3