提交 9ad6b7bc 编写于 作者: C Chris Mason

Force page->private removal in btrfs_invalidatepage

btrfs_invalidatepage is not allowed to leave pages around on the lru.
Any such pages will trigger an oops later on because the VM will see
page->private and assume it is a buffer head.

This also forces extra flushes of the async work queues before
dropping all the pages on the btree inode during unmount.  Left over
items on the work queues are one possible cause of busy state ranges
during truncate_inode_pages.
Signed-off-by: NChris Mason <chris.mason@oracle.com>
上级 0afbaf8c
...@@ -533,6 +533,12 @@ static void btree_invalidatepage(struct page *page, unsigned long offset) ...@@ -533,6 +533,12 @@ static void btree_invalidatepage(struct page *page, unsigned long offset)
tree = &BTRFS_I(page->mapping->host)->io_tree; tree = &BTRFS_I(page->mapping->host)->io_tree;
extent_invalidatepage(tree, page, offset); extent_invalidatepage(tree, page, offset);
btree_releasepage(page, GFP_NOFS); btree_releasepage(page, GFP_NOFS);
if (PagePrivate(page)) {
printk("2invalidate page cleaning up after releasepage\n");
ClearPagePrivate(page);
set_page_private(page, 0);
page_cache_release(page);
}
} }
#if 0 #if 0
...@@ -1484,6 +1490,8 @@ int close_ctree(struct btrfs_root *root) ...@@ -1484,6 +1490,8 @@ int close_ctree(struct btrfs_root *root)
write_ctree_super(NULL, root); write_ctree_super(NULL, root);
mutex_unlock(&fs_info->fs_mutex); mutex_unlock(&fs_info->fs_mutex);
btrfs_transaction_flush_work(root);
if (fs_info->delalloc_bytes) { if (fs_info->delalloc_bytes) {
printk("btrfs: at unmount delalloc count %Lu\n", printk("btrfs: at unmount delalloc count %Lu\n",
fs_info->delalloc_bytes); fs_info->delalloc_bytes);
...@@ -1514,7 +1522,11 @@ int close_ctree(struct btrfs_root *root) ...@@ -1514,7 +1522,11 @@ int close_ctree(struct btrfs_root *root)
extent_io_tree_empty_lru(&fs_info->extent_ins); extent_io_tree_empty_lru(&fs_info->extent_ins);
extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree);
flush_workqueue(end_io_workqueue);
flush_workqueue(async_submit_workqueue);
truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
flush_workqueue(end_io_workqueue); flush_workqueue(end_io_workqueue);
destroy_workqueue(end_io_workqueue); destroy_workqueue(end_io_workqueue);
......
...@@ -2524,6 +2524,12 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) ...@@ -2524,6 +2524,12 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
tree = &BTRFS_I(page->mapping->host)->io_tree; tree = &BTRFS_I(page->mapping->host)->io_tree;
extent_invalidatepage(tree, page, offset); extent_invalidatepage(tree, page, offset);
btrfs_releasepage(page, GFP_NOFS); btrfs_releasepage(page, GFP_NOFS);
if (PagePrivate(page)) {
printk("invalidate page cleaning up after releasepage\n");
ClearPagePrivate(page);
set_page_private(page, 0);
page_cache_release(page);
}
} }
/* /*
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册