diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 56 |
1 files changed, 35 insertions, 21 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index c599f0ee997a..82833e5d84b6 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -345,6 +345,25 @@ out: | |||
345 | return 0; | 345 | return 0; |
346 | } | 346 | } |
347 | 347 | ||
348 | static int check_tree_block_fsid(struct btrfs_root *root, | ||
349 | struct extent_buffer *eb) | ||
350 | { | ||
351 | struct btrfs_fs_devices *fs_devices = root->fs_info->fs_devices; | ||
352 | u8 fsid[BTRFS_UUID_SIZE]; | ||
353 | int ret = 1; | ||
354 | |||
355 | read_extent_buffer(eb, fsid, (unsigned long)btrfs_header_fsid(eb), | ||
356 | BTRFS_FSID_SIZE); | ||
357 | while (fs_devices) { | ||
358 | if (!memcmp(fsid, fs_devices->fsid, BTRFS_FSID_SIZE)) { | ||
359 | ret = 0; | ||
360 | break; | ||
361 | } | ||
362 | fs_devices = fs_devices->seed; | ||
363 | } | ||
364 | return ret; | ||
365 | } | ||
366 | |||
348 | int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | 367 | int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, |
349 | struct extent_state *state) | 368 | struct extent_state *state) |
350 | { | 369 | { |
@@ -382,9 +401,7 @@ int btree_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
382 | ret = -EIO; | 401 | ret = -EIO; |
383 | goto err; | 402 | goto err; |
384 | } | 403 | } |
385 | if (memcmp_extent_buffer(eb, root->fs_info->fsid, | 404 | if (check_tree_block_fsid(root, eb)) { |
386 | (unsigned long)btrfs_header_fsid(eb), | ||
387 | BTRFS_FSID_SIZE)) { | ||
388 | printk("bad fsid on block %Lu\n", eb->start); | 405 | printk("bad fsid on block %Lu\n", eb->start); |
389 | ret = -EIO; | 406 | ret = -EIO; |
390 | goto err; | 407 | goto err; |
@@ -1558,9 +1575,11 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1558 | if (!btrfs_super_root(disk_super)) | 1575 | if (!btrfs_super_root(disk_super)) |
1559 | goto fail_sb_buffer; | 1576 | goto fail_sb_buffer; |
1560 | 1577 | ||
1561 | err = btrfs_parse_options(tree_root, options); | 1578 | ret = btrfs_parse_options(tree_root, options); |
1562 | if (err) | 1579 | if (ret) { |
1580 | err = ret; | ||
1563 | goto fail_sb_buffer; | 1581 | goto fail_sb_buffer; |
1582 | } | ||
1564 | 1583 | ||
1565 | /* | 1584 | /* |
1566 | * we need to start all the end_io workers up front because the | 1585 | * we need to start all the end_io workers up front because the |
@@ -1610,18 +1629,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1610 | btrfs_start_workers(&fs_info->endio_write_workers, | 1629 | btrfs_start_workers(&fs_info->endio_write_workers, |
1611 | fs_info->thread_pool_size); | 1630 | fs_info->thread_pool_size); |
1612 | 1631 | ||
1613 | err = -EINVAL; | ||
1614 | if (btrfs_super_num_devices(disk_super) > fs_devices->open_devices) { | ||
1615 | printk("Btrfs: wanted %llu devices, but found %llu\n", | ||
1616 | (unsigned long long)btrfs_super_num_devices(disk_super), | ||
1617 | (unsigned long long)fs_devices->open_devices); | ||
1618 | if (btrfs_test_opt(tree_root, DEGRADED)) | ||
1619 | printk("continuing in degraded mode\n"); | ||
1620 | else { | ||
1621 | goto fail_sb_buffer; | ||
1622 | } | ||
1623 | } | ||
1624 | |||
1625 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); | 1632 | fs_info->bdi.ra_pages *= btrfs_super_num_devices(disk_super); |
1626 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, | 1633 | fs_info->bdi.ra_pages = max(fs_info->bdi.ra_pages, |
1627 | 4 * 1024 * 1024 / PAGE_CACHE_SIZE); | 1634 | 4 * 1024 * 1024 / PAGE_CACHE_SIZE); |
@@ -1672,7 +1679,10 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1672 | mutex_lock(&fs_info->chunk_mutex); | 1679 | mutex_lock(&fs_info->chunk_mutex); |
1673 | ret = btrfs_read_chunk_tree(chunk_root); | 1680 | ret = btrfs_read_chunk_tree(chunk_root); |
1674 | mutex_unlock(&fs_info->chunk_mutex); | 1681 | mutex_unlock(&fs_info->chunk_mutex); |
1675 | BUG_ON(ret); | 1682 | if (ret) { |
1683 | printk("btrfs: failed to read chunk tree on %s\n", sb->s_id); | ||
1684 | goto fail_chunk_root; | ||
1685 | } | ||
1676 | 1686 | ||
1677 | btrfs_close_extra_devices(fs_devices); | 1687 | btrfs_close_extra_devices(fs_devices); |
1678 | 1688 | ||
@@ -1684,7 +1694,7 @@ struct btrfs_root *open_ctree(struct super_block *sb, | |||
1684 | btrfs_super_root(disk_super), | 1694 | btrfs_super_root(disk_super), |
1685 | blocksize, generation); | 1695 | blocksize, generation); |
1686 | if (!tree_root->node) | 1696 | if (!tree_root->node) |
1687 | goto fail_sb_buffer; | 1697 | goto fail_chunk_root; |
1688 | 1698 | ||
1689 | 1699 | ||
1690 | ret = find_and_setup_root(tree_root, fs_info, | 1700 | ret = find_and_setup_root(tree_root, fs_info, |
@@ -1753,6 +1763,8 @@ fail_extent_root: | |||
1753 | free_extent_buffer(extent_root->node); | 1763 | free_extent_buffer(extent_root->node); |
1754 | fail_tree_root: | 1764 | fail_tree_root: |
1755 | free_extent_buffer(tree_root->node); | 1765 | free_extent_buffer(tree_root->node); |
1766 | fail_chunk_root: | ||
1767 | free_extent_buffer(chunk_root->node); | ||
1756 | fail_sys_array: | 1768 | fail_sys_array: |
1757 | fail_sb_buffer: | 1769 | fail_sb_buffer: |
1758 | btrfs_stop_workers(&fs_info->fixup_workers); | 1770 | btrfs_stop_workers(&fs_info->fixup_workers); |
@@ -1823,9 +1835,10 @@ int write_all_supers(struct btrfs_root *root) | |||
1823 | total_errors++; | 1835 | total_errors++; |
1824 | continue; | 1836 | continue; |
1825 | } | 1837 | } |
1826 | if (!dev->in_fs_metadata) | 1838 | if (!dev->in_fs_metadata || !dev->writeable) |
1827 | continue; | 1839 | continue; |
1828 | 1840 | ||
1841 | btrfs_set_stack_device_generation(dev_item, 0); | ||
1829 | btrfs_set_stack_device_type(dev_item, dev->type); | 1842 | btrfs_set_stack_device_type(dev_item, dev->type); |
1830 | btrfs_set_stack_device_id(dev_item, dev->devid); | 1843 | btrfs_set_stack_device_id(dev_item, dev->devid); |
1831 | btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes); | 1844 | btrfs_set_stack_device_total_bytes(dev_item, dev->total_bytes); |
@@ -1834,6 +1847,7 @@ int write_all_supers(struct btrfs_root *root) | |||
1834 | btrfs_set_stack_device_io_width(dev_item, dev->io_width); | 1847 | btrfs_set_stack_device_io_width(dev_item, dev->io_width); |
1835 | btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); | 1848 | btrfs_set_stack_device_sector_size(dev_item, dev->sector_size); |
1836 | memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); | 1849 | memcpy(dev_item->uuid, dev->uuid, BTRFS_UUID_SIZE); |
1850 | memcpy(dev_item->fsid, dev->fs_devices->fsid, BTRFS_UUID_SIZE); | ||
1837 | flags = btrfs_super_flags(sb); | 1851 | flags = btrfs_super_flags(sb); |
1838 | btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); | 1852 | btrfs_set_super_flags(sb, flags | BTRFS_HEADER_FLAG_WRITTEN); |
1839 | 1853 | ||
@@ -1881,7 +1895,7 @@ int write_all_supers(struct btrfs_root *root) | |||
1881 | dev = list_entry(cur, struct btrfs_device, dev_list); | 1895 | dev = list_entry(cur, struct btrfs_device, dev_list); |
1882 | if (!dev->bdev) | 1896 | if (!dev->bdev) |
1883 | continue; | 1897 | continue; |
1884 | if (!dev->in_fs_metadata) | 1898 | if (!dev->in_fs_metadata || !dev->writeable) |
1885 | continue; | 1899 | continue; |
1886 | 1900 | ||
1887 | BUG_ON(!dev->pending_io); | 1901 | BUG_ON(!dev->pending_io); |