diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/disk-io.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 8d03e4a3c4e9..c8dcb47b6d7d 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -518,7 +518,6 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
518 | extent_submit_bio_hook_t *submit_bio_done) | 518 | extent_submit_bio_hook_t *submit_bio_done) |
519 | { | 519 | { |
520 | struct async_submit_bio *async; | 520 | struct async_submit_bio *async; |
521 | int limit = btrfs_async_submit_limit(fs_info); | ||
522 | 521 | ||
523 | async = kmalloc(sizeof(*async), GFP_NOFS); | 522 | async = kmalloc(sizeof(*async), GFP_NOFS); |
524 | if (!async) | 523 | if (!async) |
@@ -541,6 +540,7 @@ int btrfs_wq_submit_bio(struct btrfs_fs_info *fs_info, struct inode *inode, | |||
541 | atomic_inc(&fs_info->nr_async_submits); | 540 | atomic_inc(&fs_info->nr_async_submits); |
542 | btrfs_queue_worker(&fs_info->workers, &async->work); | 541 | btrfs_queue_worker(&fs_info->workers, &async->work); |
543 | #if 0 | 542 | #if 0 |
543 | int limit = btrfs_async_submit_limit(fs_info); | ||
544 | if (atomic_read(&fs_info->nr_async_submits) > limit) { | 544 | if (atomic_read(&fs_info->nr_async_submits) > limit) { |
545 | wait_event_timeout(fs_info->async_submit_wait, | 545 | wait_event_timeout(fs_info->async_submit_wait, |
546 | (atomic_read(&fs_info->nr_async_submits) < limit), | 546 | (atomic_read(&fs_info->nr_async_submits) < limit), |
@@ -1732,13 +1732,15 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1732 | if (!fs_info->transaction_kthread) | 1732 | if (!fs_info->transaction_kthread) |
1733 | goto fail_cleaner; | 1733 | goto fail_cleaner; |
1734 | 1734 | ||
1735 | if (sb->s_flags & MS_RDONLY) | ||
1736 | goto read_fs_root; | ||
1737 | |||
1738 | if (btrfs_super_log_root(disk_super) != 0) { | 1735 | if (btrfs_super_log_root(disk_super) != 0) { |
1739 | u32 blocksize; | 1736 | u32 blocksize; |
1740 | u64 bytenr = btrfs_super_log_root(disk_super); | 1737 | u64 bytenr = btrfs_super_log_root(disk_super); |
1741 | 1738 | ||
1739 | if (fs_devices->rw_devices == 0) { | ||
1740 | printk("Btrfs log replay required on RO media\n"); | ||
1741 | err = -EIO; | ||
1742 | goto fail_trans_kthread; | ||
1743 | } | ||
1742 | blocksize = | 1744 | blocksize = |
1743 | btrfs_level_size(tree_root, | 1745 | btrfs_level_size(tree_root, |
1744 | btrfs_super_log_root_level(disk_super)); | 1746 | btrfs_super_log_root_level(disk_super)); |
@@ -1756,21 +1758,32 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1756 | BUG_ON(ret); | 1758 | BUG_ON(ret); |
1757 | } | 1759 | } |
1758 | 1760 | ||
1759 | ret = btrfs_cleanup_reloc_trees(tree_root); | 1761 | if (!(sb->s_flags & MS_RDONLY)) { |
1760 | BUG_ON(ret); | 1762 | ret = btrfs_cleanup_reloc_trees(tree_root); |
1763 | BUG_ON(ret); | ||
1764 | } | ||
1761 | 1765 | ||
1762 | read_fs_root: | ||
1763 | location.objectid = BTRFS_FS_TREE_OBJECTID; | 1766 | location.objectid = BTRFS_FS_TREE_OBJECTID; |
1764 | location.type = BTRFS_ROOT_ITEM_KEY; | 1767 | location.type = BTRFS_ROOT_ITEM_KEY; |
1765 | location.offset = (u64)-1; | 1768 | location.offset = (u64)-1; |
1766 | 1769 | ||
1767 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); | 1770 | fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location); |
1768 | if (!fs_info->fs_root) | 1771 | if (!fs_info->fs_root) |
1769 | goto fail_cleaner; | 1772 | goto fail_trans_kthread; |
1770 | return tree_root; | 1773 | return tree_root; |
1771 | 1774 | ||
1775 | fail_trans_kthread: | ||
1776 | kthread_stop(fs_info->transaction_kthread); | ||
1772 | fail_cleaner: | 1777 | fail_cleaner: |
1773 | kthread_stop(fs_info->cleaner_kthread); | 1778 | kthread_stop(fs_info->cleaner_kthread); |
1779 | |||
1780 | /* | ||
1781 | * make sure we're done with the btree inode before we stop our | ||
1782 | * kthreads | ||
1783 | */ | ||
1784 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | ||
1785 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | ||
1786 | |||
1774 | fail_extent_root: | 1787 | fail_extent_root: |
1775 | free_extent_buffer(extent_root->node); | 1788 | free_extent_buffer(extent_root->node); |
1776 | fail_tree_root: | 1789 | fail_tree_root: |
@@ -1778,6 +1791,7 @@ fail_tree_root: | |||
1778 | fail_chunk_root: | 1791 | fail_chunk_root: |
1779 | free_extent_buffer(chunk_root->node); | 1792 | free_extent_buffer(chunk_root->node); |
1780 | fail_sys_array: | 1793 | fail_sys_array: |
1794 | free_extent_buffer(dev_root->node); | ||
1781 | fail_sb_buffer: | 1795 | fail_sb_buffer: |
1782 | btrfs_stop_workers(&fs_info->fixup_workers); | 1796 | btrfs_stop_workers(&fs_info->fixup_workers); |
1783 | btrfs_stop_workers(&fs_info->delalloc_workers); | 1797 | btrfs_stop_workers(&fs_info->delalloc_workers); |
@@ -1786,6 +1800,7 @@ fail_sb_buffer: | |||
1786 | btrfs_stop_workers(&fs_info->endio_write_workers); | 1800 | btrfs_stop_workers(&fs_info->endio_write_workers); |
1787 | btrfs_stop_workers(&fs_info->submit_workers); | 1801 | btrfs_stop_workers(&fs_info->submit_workers); |
1788 | fail_iput: | 1802 | fail_iput: |
1803 | invalidate_inode_pages2(fs_info->btree_inode->i_mapping); | ||
1789 | iput(fs_info->btree_inode); | 1804 | iput(fs_info->btree_inode); |
1790 | fail: | 1805 | fail: |
1791 | btrfs_close_devices(fs_info->fs_devices); | 1806 | btrfs_close_devices(fs_info->fs_devices); |