diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 5abbb915f4e3f234f73c3d57e2d27983bcbaa506..be8e89720735b9f99fba8a5e9495ceab7cb42830 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -2075,6 +2075,20 @@ static int __ext4_journalled_writepage(struct page *page, return ret; } +static void cancel_page_dirty_status(struct page *page) +{ + struct address_space *mapping = page_mapping(page); + unsigned long flags; + + cancel_dirty_page(page); + xa_lock_irqsave(&mapping->i_pages, flags); + radix_tree_tag_clear(&mapping->i_pages, page_index(page), + PAGECACHE_TAG_DIRTY); + radix_tree_tag_clear(&mapping->i_pages, page_index(page), + PAGECACHE_TAG_TOWRITE); + xa_unlock_irqrestore(&mapping->i_pages, flags); +} + /* * Note that we don't need to start a transaction unless we're journaling data * because we should have holes filled from ext4_page_mkwrite(). We even don't @@ -2133,6 +2147,12 @@ static int ext4_writepage(struct page *page, return -EIO; } + if (WARN_ON(!page_has_buffers(page))) { + cancel_page_dirty_status(page); + unlock_page(page); + return 0; + } + trace_ext4_writepage(page); size = i_size_read(inode); if (page->index == size >> PAGE_SHIFT) @@ -2686,6 +2706,12 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd) continue; } + if (WARN_ON(!page_has_buffers(page))) { + cancel_page_dirty_status(page); + unlock_page(page); + continue; + } + wait_on_page_writeback(page); BUG_ON(PageWriteback(page));