diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-22 14:49:21 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-22 14:49:21 -0500 |
commit | 2101ae42899a14fe7caa73114e2161e778328661 (patch) | |
tree | a8ee78aabbcaa5c9549e8eda9883dad0347ddc43 /fs/btrfs/disk-io.c | |
parent | 391f2a16b74b95da2f05a607f53213fc8ed24b8e (diff) | |
parent | a6111d11b8b5364d02ea2e881c81ce39d004eb32 (diff) |
Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull more btrfs updates from Chris Mason:
"These are mostly fixes that we've been testing, but also we grabbed
and tested a few small cleanups that had been on the list for a while.
Zhao Lei's patchset also fixes some early ENOSPC buglets"
* 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (21 commits)
btrfs: raid56: Use raid_write_end_io for scrub
btrfs: Remove unnecessary ClearPageUptodate for raid56
btrfs: use rbio->nr_pages to reduce calculation
btrfs: Use unified stripe_page's index calculation
btrfs: Fix calculation of rbio->dbitmap's size calculation
btrfs: Fix no_space in write and rm loop
btrfs: merge functions for wait snapshot creation
btrfs: delete unused argument in btrfs_copy_from_user
btrfs: Use direct way to determine raid56 write/recover mode
btrfs: Small cleanup for get index_srcdev loop
btrfs: Enhance chunk validation check
btrfs: Enhance super validation check
Btrfs: fix deadlock running delayed iputs at transaction commit time
Btrfs: fix typo in log message when starting a balance
btrfs: remove duplicate const specifier
btrfs: initialize the seq counter in struct btrfs_device
Btrfs: clean up an error code in btrfs_init_space_info()
btrfs: fix iterator with update error in backref.c
Btrfs: fix output of compression message in btrfs_parse_options()
Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots
...
Diffstat (limited to 'fs/btrfs/disk-io.c')
-rw-r--r-- | fs/btrfs/disk-io.c | 129 |
1 files changed, 79 insertions, 50 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e99ccd6ffb2c..dd08e29f5117 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -55,6 +55,12 @@ | |||
55 | #include <asm/cpufeature.h> | 55 | #include <asm/cpufeature.h> |
56 | #endif | 56 | #endif |
57 | 57 | ||
58 | #define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\ | ||
59 | BTRFS_HEADER_FLAG_RELOC |\ | ||
60 | BTRFS_SUPER_FLAG_ERROR |\ | ||
61 | BTRFS_SUPER_FLAG_SEEDING |\ | ||
62 | BTRFS_SUPER_FLAG_METADUMP) | ||
63 | |||
58 | static const struct extent_io_ops btree_extent_io_ops; | 64 | static const struct extent_io_ops btree_extent_io_ops; |
59 | static void end_workqueue_fn(struct btrfs_work *work); | 65 | static void end_workqueue_fn(struct btrfs_work *work); |
60 | static void free_fs_root(struct btrfs_root *root); | 66 | static void free_fs_root(struct btrfs_root *root); |
@@ -1583,8 +1589,23 @@ int btrfs_init_fs_root(struct btrfs_root *root) | |||
1583 | ret = get_anon_bdev(&root->anon_dev); | 1589 | ret = get_anon_bdev(&root->anon_dev); |
1584 | if (ret) | 1590 | if (ret) |
1585 | goto free_writers; | 1591 | goto free_writers; |
1592 | |||
1593 | mutex_lock(&root->objectid_mutex); | ||
1594 | ret = btrfs_find_highest_objectid(root, | ||
1595 | &root->highest_objectid); | ||
1596 | if (ret) { | ||
1597 | mutex_unlock(&root->objectid_mutex); | ||
1598 | goto free_root_dev; | ||
1599 | } | ||
1600 | |||
1601 | ASSERT(root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID); | ||
1602 | |||
1603 | mutex_unlock(&root->objectid_mutex); | ||
1604 | |||
1586 | return 0; | 1605 | return 0; |
1587 | 1606 | ||
1607 | free_root_dev: | ||
1608 | free_anon_bdev(root->anon_dev); | ||
1588 | free_writers: | 1609 | free_writers: |
1589 | btrfs_free_subvolume_writers(root->subv_writers); | 1610 | btrfs_free_subvolume_writers(root->subv_writers); |
1590 | fail: | 1611 | fail: |
@@ -1786,7 +1807,10 @@ static int cleaner_kthread(void *arg) | |||
1786 | goto sleep; | 1807 | goto sleep; |
1787 | } | 1808 | } |
1788 | 1809 | ||
1810 | mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex); | ||
1789 | btrfs_run_delayed_iputs(root); | 1811 | btrfs_run_delayed_iputs(root); |
1812 | mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex); | ||
1813 | |||
1790 | again = btrfs_clean_one_deleted_snapshot(root); | 1814 | again = btrfs_clean_one_deleted_snapshot(root); |
1791 | mutex_unlock(&root->fs_info->cleaner_mutex); | 1815 | mutex_unlock(&root->fs_info->cleaner_mutex); |
1792 | 1816 | ||
@@ -2556,8 +2580,8 @@ int open_ctree(struct super_block *sb, | |||
2556 | mutex_init(&fs_info->delete_unused_bgs_mutex); | 2580 | mutex_init(&fs_info->delete_unused_bgs_mutex); |
2557 | mutex_init(&fs_info->reloc_mutex); | 2581 | mutex_init(&fs_info->reloc_mutex); |
2558 | mutex_init(&fs_info->delalloc_root_mutex); | 2582 | mutex_init(&fs_info->delalloc_root_mutex); |
2583 | mutex_init(&fs_info->cleaner_delayed_iput_mutex); | ||
2559 | seqlock_init(&fs_info->profiles_lock); | 2584 | seqlock_init(&fs_info->profiles_lock); |
2560 | init_rwsem(&fs_info->delayed_iput_sem); | ||
2561 | 2585 | ||
2562 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); | 2586 | INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots); |
2563 | INIT_LIST_HEAD(&fs_info->space_info); | 2587 | INIT_LIST_HEAD(&fs_info->space_info); |
@@ -2742,26 +2766,6 @@ int open_ctree(struct super_block *sb, | |||
2742 | goto fail_alloc; | 2766 | goto fail_alloc; |
2743 | } | 2767 | } |
2744 | 2768 | ||
2745 | /* | ||
2746 | * Leafsize and nodesize were always equal, this is only a sanity check. | ||
2747 | */ | ||
2748 | if (le32_to_cpu(disk_super->__unused_leafsize) != | ||
2749 | btrfs_super_nodesize(disk_super)) { | ||
2750 | printk(KERN_ERR "BTRFS: couldn't mount because metadata " | ||
2751 | "blocksizes don't match. node %d leaf %d\n", | ||
2752 | btrfs_super_nodesize(disk_super), | ||
2753 | le32_to_cpu(disk_super->__unused_leafsize)); | ||
2754 | err = -EINVAL; | ||
2755 | goto fail_alloc; | ||
2756 | } | ||
2757 | if (btrfs_super_nodesize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) { | ||
2758 | printk(KERN_ERR "BTRFS: couldn't mount because metadata " | ||
2759 | "blocksize (%d) was too large\n", | ||
2760 | btrfs_super_nodesize(disk_super)); | ||
2761 | err = -EINVAL; | ||
2762 | goto fail_alloc; | ||
2763 | } | ||
2764 | |||
2765 | features = btrfs_super_incompat_flags(disk_super); | 2769 | features = btrfs_super_incompat_flags(disk_super); |
2766 | features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; | 2770 | features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF; |
2767 | if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO) | 2771 | if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO) |
@@ -2833,17 +2837,6 @@ int open_ctree(struct super_block *sb, | |||
2833 | sb->s_blocksize = sectorsize; | 2837 | sb->s_blocksize = sectorsize; |
2834 | sb->s_blocksize_bits = blksize_bits(sectorsize); | 2838 | sb->s_blocksize_bits = blksize_bits(sectorsize); |
2835 | 2839 | ||
2836 | if (btrfs_super_magic(disk_super) != BTRFS_MAGIC) { | ||
2837 | printk(KERN_ERR "BTRFS: valid FS not found on %s\n", sb->s_id); | ||
2838 | goto fail_sb_buffer; | ||
2839 | } | ||
2840 | |||
2841 | if (sectorsize != PAGE_SIZE) { | ||
2842 | printk(KERN_ERR "BTRFS: incompatible sector size (%lu) " | ||
2843 | "found on %s\n", (unsigned long)sectorsize, sb->s_id); | ||
2844 | goto fail_sb_buffer; | ||
2845 | } | ||
2846 | |||
2847 | mutex_lock(&fs_info->chunk_mutex); | 2840 | mutex_lock(&fs_info->chunk_mutex); |
2848 | ret = btrfs_read_sys_array(tree_root); | 2841 | ret = btrfs_read_sys_array(tree_root); |
2849 | mutex_unlock(&fs_info->chunk_mutex); | 2842 | mutex_unlock(&fs_info->chunk_mutex); |
@@ -2915,6 +2908,18 @@ retry_root_backup: | |||
2915 | tree_root->commit_root = btrfs_root_node(tree_root); | 2908 | tree_root->commit_root = btrfs_root_node(tree_root); |
2916 | btrfs_set_root_refs(&tree_root->root_item, 1); | 2909 | btrfs_set_root_refs(&tree_root->root_item, 1); |
2917 | 2910 | ||
2911 | mutex_lock(&tree_root->objectid_mutex); | ||
2912 | ret = btrfs_find_highest_objectid(tree_root, | ||
2913 | &tree_root->highest_objectid); | ||
2914 | if (ret) { | ||
2915 | mutex_unlock(&tree_root->objectid_mutex); | ||
2916 | goto recovery_tree_root; | ||
2917 | } | ||
2918 | |||
2919 | ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID); | ||
2920 | |||
2921 | mutex_unlock(&tree_root->objectid_mutex); | ||
2922 | |||
2918 | ret = btrfs_read_roots(fs_info, tree_root); | 2923 | ret = btrfs_read_roots(fs_info, tree_root); |
2919 | if (ret) | 2924 | if (ret) |
2920 | goto recovery_tree_root; | 2925 | goto recovery_tree_root; |
@@ -4018,8 +4023,17 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | |||
4018 | int read_only) | 4023 | int read_only) |
4019 | { | 4024 | { |
4020 | struct btrfs_super_block *sb = fs_info->super_copy; | 4025 | struct btrfs_super_block *sb = fs_info->super_copy; |
4026 | u64 nodesize = btrfs_super_nodesize(sb); | ||
4027 | u64 sectorsize = btrfs_super_sectorsize(sb); | ||
4021 | int ret = 0; | 4028 | int ret = 0; |
4022 | 4029 | ||
4030 | if (btrfs_super_magic(sb) != BTRFS_MAGIC) { | ||
4031 | printk(KERN_ERR "BTRFS: no valid FS found\n"); | ||
4032 | ret = -EINVAL; | ||
4033 | } | ||
4034 | if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP) | ||
4035 | printk(KERN_WARNING "BTRFS: unrecognized super flag: %llu\n", | ||
4036 | btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP); | ||
4023 | if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) { | 4037 | if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) { |
4024 | printk(KERN_ERR "BTRFS: tree_root level too big: %d >= %d\n", | 4038 | printk(KERN_ERR "BTRFS: tree_root level too big: %d >= %d\n", |
4025 | btrfs_super_root_level(sb), BTRFS_MAX_LEVEL); | 4039 | btrfs_super_root_level(sb), BTRFS_MAX_LEVEL); |
@@ -4037,31 +4051,46 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | |||
4037 | } | 4051 | } |
4038 | 4052 | ||
4039 | /* | 4053 | /* |
4040 | * The common minimum, we don't know if we can trust the nodesize/sectorsize | 4054 | * Check sectorsize and nodesize first, other check will need it. |
4041 | * items yet, they'll be verified later. Issue just a warning. | 4055 | * Check all possible sectorsize(4K, 8K, 16K, 32K, 64K) here. |
4042 | */ | 4056 | */ |
4043 | if (!IS_ALIGNED(btrfs_super_root(sb), 4096)) | 4057 | if (!is_power_of_2(sectorsize) || sectorsize < 4096 || |
4058 | sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE) { | ||
4059 | printk(KERN_ERR "BTRFS: invalid sectorsize %llu\n", sectorsize); | ||
4060 | ret = -EINVAL; | ||
4061 | } | ||
4062 | /* Only PAGE SIZE is supported yet */ | ||
4063 | if (sectorsize != PAGE_CACHE_SIZE) { | ||
4064 | printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n", | ||
4065 | sectorsize, PAGE_CACHE_SIZE); | ||
4066 | ret = -EINVAL; | ||
4067 | } | ||
4068 | if (!is_power_of_2(nodesize) || nodesize < sectorsize || | ||
4069 | nodesize > BTRFS_MAX_METADATA_BLOCKSIZE) { | ||
4070 | printk(KERN_ERR "BTRFS: invalid nodesize %llu\n", nodesize); | ||
4071 | ret = -EINVAL; | ||
4072 | } | ||
4073 | if (nodesize != le32_to_cpu(sb->__unused_leafsize)) { | ||
4074 | printk(KERN_ERR "BTRFS: invalid leafsize %u, should be %llu\n", | ||
4075 | le32_to_cpu(sb->__unused_leafsize), | ||
4076 | nodesize); | ||
4077 | ret = -EINVAL; | ||
4078 | } | ||
4079 | |||
4080 | /* Root alignment check */ | ||
4081 | if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) { | ||
4044 | printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n", | 4082 | printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n", |
4045 | btrfs_super_root(sb)); | 4083 | btrfs_super_root(sb)); |
4046 | if (!IS_ALIGNED(btrfs_super_chunk_root(sb), 4096)) | 4084 | ret = -EINVAL; |
4085 | } | ||
4086 | if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) { | ||
4047 | printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n", | 4087 | printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n", |
4048 | btrfs_super_chunk_root(sb)); | 4088 | btrfs_super_chunk_root(sb)); |
4049 | if (!IS_ALIGNED(btrfs_super_log_root(sb), 4096)) | ||
4050 | printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n", | ||
4051 | btrfs_super_log_root(sb)); | ||
4052 | |||
4053 | /* | ||
4054 | * Check the lower bound, the alignment and other constraints are | ||
4055 | * checked later. | ||
4056 | */ | ||
4057 | if (btrfs_super_nodesize(sb) < 4096) { | ||
4058 | printk(KERN_ERR "BTRFS: nodesize too small: %u < 4096\n", | ||
4059 | btrfs_super_nodesize(sb)); | ||
4060 | ret = -EINVAL; | 4089 | ret = -EINVAL; |
4061 | } | 4090 | } |
4062 | if (btrfs_super_sectorsize(sb) < 4096) { | 4091 | if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) { |
4063 | printk(KERN_ERR "BTRFS: sectorsize too small: %u < 4096\n", | 4092 | printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n", |
4064 | btrfs_super_sectorsize(sb)); | 4093 | btrfs_super_log_root(sb)); |
4065 | ret = -EINVAL; | 4094 | ret = -EINVAL; |
4066 | } | 4095 | } |
4067 | 4096 | ||