aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2008-04-18 16:11:30 -0400
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:04:02 -0400
commit9ad6b7bc2e00ba02f915cffd5b6bcd6564bb2c75 (patch)
tree8a07ab45a145ac723bdfe011a187d09eb0cc2803 /fs/btrfs
parent0afbaf8c8216a0de64b55c2d455de2b6c9dde5eb (diff)
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: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/disk-io.c12
-rw-r--r--fs/btrfs/inode.c6
2 files changed, 18 insertions, 0 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 9d648f2f41a5..b479cdfe3ee8 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -533,6 +533,12 @@ static void btree_invalidatepage(struct page *page, unsigned long offset)
533 tree = &BTRFS_I(page->mapping->host)->io_tree; 533 tree = &BTRFS_I(page->mapping->host)->io_tree;
534 extent_invalidatepage(tree, page, offset); 534 extent_invalidatepage(tree, page, offset);
535 btree_releasepage(page, GFP_NOFS); 535 btree_releasepage(page, GFP_NOFS);
536 if (PagePrivate(page)) {
537 printk("2invalidate page cleaning up after releasepage\n");
538 ClearPagePrivate(page);
539 set_page_private(page, 0);
540 page_cache_release(page);
541 }
536} 542}
537 543
538#if 0 544#if 0
@@ -1484,6 +1490,8 @@ int close_ctree(struct btrfs_root *root)
1484 write_ctree_super(NULL, root); 1490 write_ctree_super(NULL, root);
1485 mutex_unlock(&fs_info->fs_mutex); 1491 mutex_unlock(&fs_info->fs_mutex);
1486 1492
1493 btrfs_transaction_flush_work(root);
1494
1487 if (fs_info->delalloc_bytes) { 1495 if (fs_info->delalloc_bytes) {
1488 printk("btrfs: at unmount delalloc count %Lu\n", 1496 printk("btrfs: at unmount delalloc count %Lu\n",
1489 fs_info->delalloc_bytes); 1497 fs_info->delalloc_bytes);
@@ -1514,7 +1522,11 @@ int close_ctree(struct btrfs_root *root)
1514 extent_io_tree_empty_lru(&fs_info->extent_ins); 1522 extent_io_tree_empty_lru(&fs_info->extent_ins);
1515 extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree); 1523 extent_io_tree_empty_lru(&BTRFS_I(fs_info->btree_inode)->io_tree);
1516 1524
1525 flush_workqueue(end_io_workqueue);
1526 flush_workqueue(async_submit_workqueue);
1527
1517 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0); 1528 truncate_inode_pages(fs_info->btree_inode->i_mapping, 0);
1529
1518 flush_workqueue(end_io_workqueue); 1530 flush_workqueue(end_io_workqueue);
1519 destroy_workqueue(end_io_workqueue); 1531 destroy_workqueue(end_io_workqueue);
1520 1532
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 40f8da884090..347cd85db128 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2524,6 +2524,12 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
2524 tree = &BTRFS_I(page->mapping->host)->io_tree; 2524 tree = &BTRFS_I(page->mapping->host)->io_tree;
2525 extent_invalidatepage(tree, page, offset); 2525 extent_invalidatepage(tree, page, offset);
2526 btrfs_releasepage(page, GFP_NOFS); 2526 btrfs_releasepage(page, GFP_NOFS);
2527 if (PagePrivate(page)) {
2528 printk("invalidate page cleaning up after releasepage\n");
2529 ClearPagePrivate(page);
2530 set_page_private(page, 0);
2531 page_cache_release(page);
2532 }
2527} 2533}
2528 2534
2529/* 2535/*