提交 45d65ca0 编写于 作者: Y yangerkun 提交者: Xie XiuQi

ext4: stop IO for page without buffer_head

hulk inclusion
category: bugfix
bugzilla: 27600
CVE: NA
---------------------------

dio_bio_complete will set page dirty without consider is there still
buffer_head valid with this page. This will trigger some problem while
ext4 try to writeback this page. For ext4, we fix it by skip writeback
the page without buffer_head.

[1] https://lwn.net/Articles/774411/ : "DMA and get_user_pages()"
[2] https://lwn.net/Articles/753027/ : "The Trouble with get_user_pages()"
[3] https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=fc1d8e7cca2daa18Signed-off-by: Nyangerkun <yangerkun@huawei.com>
Reviewed-by: Nzhangyi (F) <yi.zhang@huawei.com>
Signed-off-by: NYang Yingliang <yangyingliang@huawei.com>
Signed-off-by: NXie XiuQi <xiexiuqi@huawei.com>
上级 44d6e907
...@@ -2075,6 +2075,20 @@ static int __ext4_journalled_writepage(struct page *page, ...@@ -2075,6 +2075,20 @@ static int __ext4_journalled_writepage(struct page *page,
return ret; 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 * 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 * 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, ...@@ -2133,6 +2147,12 @@ static int ext4_writepage(struct page *page,
return -EIO; return -EIO;
} }
if (WARN_ON(!page_has_buffers(page))) {
cancel_page_dirty_status(page);
unlock_page(page);
return 0;
}
trace_ext4_writepage(page); trace_ext4_writepage(page);
size = i_size_read(inode); size = i_size_read(inode);
if (page->index == size >> PAGE_SHIFT) if (page->index == size >> PAGE_SHIFT)
...@@ -2686,6 +2706,12 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd) ...@@ -2686,6 +2706,12 @@ static int mpage_prepare_extent_to_map(struct mpage_da_data *mpd)
continue; continue;
} }
if (WARN_ON(!page_has_buffers(page))) {
cancel_page_dirty_status(page);
unlock_page(page);
continue;
}
wait_on_page_writeback(page); wait_on_page_writeback(page);
BUG_ON(PageWriteback(page)); BUG_ON(PageWriteback(page));
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册