diff options
Diffstat (limited to 'fs/btrfs/disk-io.c')
| -rw-r--r-- | fs/btrfs/disk-io.c | 54 |
1 files changed, 31 insertions, 23 deletions
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6628fca9f4ed..60ce1190307b 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1098,7 +1098,7 @@ void readahead_tree_block(struct btrfs_root *root, u64 bytenr) | |||
| 1098 | struct inode *btree_inode = root->fs_info->btree_inode; | 1098 | struct inode *btree_inode = root->fs_info->btree_inode; |
| 1099 | 1099 | ||
| 1100 | buf = btrfs_find_create_tree_block(root, bytenr); | 1100 | buf = btrfs_find_create_tree_block(root, bytenr); |
| 1101 | if (!buf) | 1101 | if (IS_ERR(buf)) |
| 1102 | return; | 1102 | return; |
| 1103 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, | 1103 | read_extent_buffer_pages(&BTRFS_I(btree_inode)->io_tree, |
| 1104 | buf, 0, WAIT_NONE, btree_get_extent, 0); | 1104 | buf, 0, WAIT_NONE, btree_get_extent, 0); |
| @@ -1114,7 +1114,7 @@ int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, | |||
| 1114 | int ret; | 1114 | int ret; |
| 1115 | 1115 | ||
| 1116 | buf = btrfs_find_create_tree_block(root, bytenr); | 1116 | buf = btrfs_find_create_tree_block(root, bytenr); |
| 1117 | if (!buf) | 1117 | if (IS_ERR(buf)) |
| 1118 | return 0; | 1118 | return 0; |
| 1119 | 1119 | ||
| 1120 | set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags); | 1120 | set_bit(EXTENT_BUFFER_READAHEAD, &buf->bflags); |
| @@ -1147,7 +1147,8 @@ struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, | |||
| 1147 | u64 bytenr) | 1147 | u64 bytenr) |
| 1148 | { | 1148 | { |
| 1149 | if (btrfs_test_is_dummy_root(root)) | 1149 | if (btrfs_test_is_dummy_root(root)) |
| 1150 | return alloc_test_extent_buffer(root->fs_info, bytenr); | 1150 | return alloc_test_extent_buffer(root->fs_info, bytenr, |
| 1151 | root->nodesize); | ||
| 1151 | return alloc_extent_buffer(root->fs_info, bytenr); | 1152 | return alloc_extent_buffer(root->fs_info, bytenr); |
| 1152 | } | 1153 | } |
| 1153 | 1154 | ||
| @@ -1171,8 +1172,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, | |||
| 1171 | int ret; | 1172 | int ret; |
| 1172 | 1173 | ||
| 1173 | buf = btrfs_find_create_tree_block(root, bytenr); | 1174 | buf = btrfs_find_create_tree_block(root, bytenr); |
| 1174 | if (!buf) | 1175 | if (IS_ERR(buf)) |
| 1175 | return ERR_PTR(-ENOMEM); | 1176 | return buf; |
| 1176 | 1177 | ||
| 1177 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); | 1178 | ret = btree_read_extent_buffer_pages(root, buf, 0, parent_transid); |
| 1178 | if (ret) { | 1179 | if (ret) { |
| @@ -1314,14 +1315,16 @@ static struct btrfs_root *btrfs_alloc_root(struct btrfs_fs_info *fs_info, | |||
| 1314 | 1315 | ||
| 1315 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | 1316 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
| 1316 | /* Should only be used by the testing infrastructure */ | 1317 | /* Should only be used by the testing infrastructure */ |
| 1317 | struct btrfs_root *btrfs_alloc_dummy_root(void) | 1318 | struct btrfs_root *btrfs_alloc_dummy_root(u32 sectorsize, u32 nodesize) |
| 1318 | { | 1319 | { |
| 1319 | struct btrfs_root *root; | 1320 | struct btrfs_root *root; |
| 1320 | 1321 | ||
| 1321 | root = btrfs_alloc_root(NULL, GFP_KERNEL); | 1322 | root = btrfs_alloc_root(NULL, GFP_KERNEL); |
| 1322 | if (!root) | 1323 | if (!root) |
| 1323 | return ERR_PTR(-ENOMEM); | 1324 | return ERR_PTR(-ENOMEM); |
| 1324 | __setup_root(4096, 4096, 4096, root, NULL, 1); | 1325 | /* We don't use the stripesize in selftest, set it as sectorsize */ |
| 1326 | __setup_root(nodesize, sectorsize, sectorsize, root, NULL, | ||
| 1327 | BTRFS_ROOT_TREE_OBJECTID); | ||
| 1325 | set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state); | 1328 | set_bit(BTRFS_ROOT_DUMMY_ROOT, &root->state); |
| 1326 | root->alloc_bytenr = 0; | 1329 | root->alloc_bytenr = 0; |
| 1327 | 1330 | ||
| @@ -1803,6 +1806,13 @@ static int cleaner_kthread(void *arg) | |||
| 1803 | if (btrfs_need_cleaner_sleep(root)) | 1806 | if (btrfs_need_cleaner_sleep(root)) |
| 1804 | goto sleep; | 1807 | goto sleep; |
| 1805 | 1808 | ||
| 1809 | /* | ||
| 1810 | * Do not do anything if we might cause open_ctree() to block | ||
| 1811 | * before we have finished mounting the filesystem. | ||
| 1812 | */ | ||
| 1813 | if (!root->fs_info->open) | ||
| 1814 | goto sleep; | ||
| 1815 | |||
| 1806 | if (!mutex_trylock(&root->fs_info->cleaner_mutex)) | 1816 | if (!mutex_trylock(&root->fs_info->cleaner_mutex)) |
| 1807 | goto sleep; | 1817 | goto sleep; |
| 1808 | 1818 | ||
| @@ -2517,7 +2527,6 @@ int open_ctree(struct super_block *sb, | |||
| 2517 | int num_backups_tried = 0; | 2527 | int num_backups_tried = 0; |
| 2518 | int backup_index = 0; | 2528 | int backup_index = 0; |
| 2519 | int max_active; | 2529 | int max_active; |
| 2520 | bool cleaner_mutex_locked = false; | ||
| 2521 | 2530 | ||
| 2522 | tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); | 2531 | tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); |
| 2523 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); | 2532 | chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); |
| @@ -2797,7 +2806,7 @@ int open_ctree(struct super_block *sb, | |||
| 2797 | 2806 | ||
| 2798 | nodesize = btrfs_super_nodesize(disk_super); | 2807 | nodesize = btrfs_super_nodesize(disk_super); |
| 2799 | sectorsize = btrfs_super_sectorsize(disk_super); | 2808 | sectorsize = btrfs_super_sectorsize(disk_super); |
| 2800 | stripesize = btrfs_super_stripesize(disk_super); | 2809 | stripesize = sectorsize; |
| 2801 | fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids)); | 2810 | fs_info->dirty_metadata_batch = nodesize * (1 + ilog2(nr_cpu_ids)); |
| 2802 | fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); | 2811 | fs_info->delalloc_batch = sectorsize * 512 * (1 + ilog2(nr_cpu_ids)); |
| 2803 | 2812 | ||
| @@ -2996,13 +3005,6 @@ retry_root_backup: | |||
| 2996 | goto fail_sysfs; | 3005 | goto fail_sysfs; |
| 2997 | } | 3006 | } |
| 2998 | 3007 | ||
| 2999 | /* | ||
| 3000 | * Hold the cleaner_mutex thread here so that we don't block | ||
| 3001 | * for a long time on btrfs_recover_relocation. cleaner_kthread | ||
| 3002 | * will wait for us to finish mounting the filesystem. | ||
| 3003 | */ | ||
| 3004 | mutex_lock(&fs_info->cleaner_mutex); | ||
| 3005 | cleaner_mutex_locked = true; | ||
| 3006 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, | 3008 | fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, |
| 3007 | "btrfs-cleaner"); | 3009 | "btrfs-cleaner"); |
| 3008 | if (IS_ERR(fs_info->cleaner_kthread)) | 3010 | if (IS_ERR(fs_info->cleaner_kthread)) |
| @@ -3062,8 +3064,10 @@ retry_root_backup: | |||
| 3062 | ret = btrfs_cleanup_fs_roots(fs_info); | 3064 | ret = btrfs_cleanup_fs_roots(fs_info); |
| 3063 | if (ret) | 3065 | if (ret) |
| 3064 | goto fail_qgroup; | 3066 | goto fail_qgroup; |
| 3065 | /* We locked cleaner_mutex before creating cleaner_kthread. */ | 3067 | |
| 3068 | mutex_lock(&fs_info->cleaner_mutex); | ||
| 3066 | ret = btrfs_recover_relocation(tree_root); | 3069 | ret = btrfs_recover_relocation(tree_root); |
| 3070 | mutex_unlock(&fs_info->cleaner_mutex); | ||
| 3067 | if (ret < 0) { | 3071 | if (ret < 0) { |
| 3068 | btrfs_warn(fs_info, "failed to recover relocation: %d", | 3072 | btrfs_warn(fs_info, "failed to recover relocation: %d", |
| 3069 | ret); | 3073 | ret); |
| @@ -3071,8 +3075,6 @@ retry_root_backup: | |||
| 3071 | goto fail_qgroup; | 3075 | goto fail_qgroup; |
| 3072 | } | 3076 | } |
| 3073 | } | 3077 | } |
| 3074 | mutex_unlock(&fs_info->cleaner_mutex); | ||
| 3075 | cleaner_mutex_locked = false; | ||
| 3076 | 3078 | ||
| 3077 | location.objectid = BTRFS_FS_TREE_OBJECTID; | 3079 | location.objectid = BTRFS_FS_TREE_OBJECTID; |
| 3078 | location.type = BTRFS_ROOT_ITEM_KEY; | 3080 | location.type = BTRFS_ROOT_ITEM_KEY; |
| @@ -3186,10 +3188,6 @@ fail_cleaner: | |||
| 3186 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); | 3188 | filemap_write_and_wait(fs_info->btree_inode->i_mapping); |
| 3187 | 3189 | ||
| 3188 | fail_sysfs: | 3190 | fail_sysfs: |
| 3189 | if (cleaner_mutex_locked) { | ||
| 3190 | mutex_unlock(&fs_info->cleaner_mutex); | ||
| 3191 | cleaner_mutex_locked = false; | ||
| 3192 | } | ||
| 3193 | btrfs_sysfs_remove_mounted(fs_info); | 3191 | btrfs_sysfs_remove_mounted(fs_info); |
| 3194 | 3192 | ||
| 3195 | fail_fsdev_sysfs: | 3193 | fail_fsdev_sysfs: |
| @@ -4130,6 +4128,16 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info, | |||
| 4130 | * Hint to catch really bogus numbers, bitflips or so, more exact checks are | 4128 | * Hint to catch really bogus numbers, bitflips or so, more exact checks are |
| 4131 | * done later | 4129 | * done later |
| 4132 | */ | 4130 | */ |
| 4131 | if (btrfs_super_bytes_used(sb) < 6 * btrfs_super_nodesize(sb)) { | ||
| 4132 | btrfs_err(fs_info, "bytes_used is too small %llu", | ||
| 4133 | btrfs_super_bytes_used(sb)); | ||
| 4134 | ret = -EINVAL; | ||
| 4135 | } | ||
| 4136 | if (!is_power_of_2(btrfs_super_stripesize(sb))) { | ||
| 4137 | btrfs_err(fs_info, "invalid stripesize %u", | ||
| 4138 | btrfs_super_stripesize(sb)); | ||
| 4139 | ret = -EINVAL; | ||
| 4140 | } | ||
| 4133 | if (btrfs_super_num_devices(sb) > (1UL << 31)) | 4141 | if (btrfs_super_num_devices(sb) > (1UL << 31)) |
| 4134 | printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n", | 4142 | printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n", |
| 4135 | btrfs_super_num_devices(sb)); | 4143 | btrfs_super_num_devices(sb)); |
