diff options
Diffstat (limited to 'fs/btrfs')
-rw-r--r-- | fs/btrfs/check-integrity.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 13 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 54 | ||||
-rw-r--r-- | fs/btrfs/disk-io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 12 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 25 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 4 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 18 | ||||
-rw-r--r-- | fs/btrfs/hash.c | 5 | ||||
-rw-r--r-- | fs/btrfs/hash.h | 1 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 11 | ||||
-rw-r--r-- | fs/btrfs/super.c | 61 | ||||
-rw-r--r-- | fs/btrfs/tests/btrfs-tests.c | 6 | ||||
-rw-r--r-- | fs/btrfs/tests/btrfs-tests.h | 27 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-buffer-tests.c | 13 | ||||
-rw-r--r-- | fs/btrfs/tests/extent-io-tests.c | 86 | ||||
-rw-r--r-- | fs/btrfs/tests/free-space-tests.c | 76 | ||||
-rw-r--r-- | fs/btrfs/tests/free-space-tree-tests.c | 30 | ||||
-rw-r--r-- | fs/btrfs/tests/inode-tests.c | 344 | ||||
-rw-r--r-- | fs/btrfs/tests/qgroup-tests.c | 111 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 7 | ||||
-rw-r--r-- | fs/btrfs/transaction.h | 2 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 4 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 113 |
24 files changed, 628 insertions, 399 deletions
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index b677a6ea6001..7706c8dc5fa6 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -2645,7 +2645,7 @@ static void btrfsic_dump_tree_sub(const struct btrfsic_state *state, | |||
2645 | * This algorithm is recursive because the amount of used stack space | 2645 | * This algorithm is recursive because the amount of used stack space |
2646 | * is very small and the max recursion depth is limited. | 2646 | * is very small and the max recursion depth is limited. |
2647 | */ | 2647 | */ |
2648 | indent_add = sprintf(buf, "%c-%llu(%s/%llu/%d)", | 2648 | indent_add = sprintf(buf, "%c-%llu(%s/%llu/%u)", |
2649 | btrfsic_get_block_type(state, block), | 2649 | btrfsic_get_block_type(state, block), |
2650 | block->logical_bytenr, block->dev_state->name, | 2650 | block->logical_bytenr, block->dev_state->name, |
2651 | block->dev_bytenr, block->mirror_num); | 2651 | block->dev_bytenr, block->mirror_num); |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index 427c36b430a6..6276add8538a 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -1373,7 +1373,8 @@ tree_mod_log_rewind(struct btrfs_fs_info *fs_info, struct btrfs_path *path, | |||
1373 | 1373 | ||
1374 | if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) { | 1374 | if (tm->op == MOD_LOG_KEY_REMOVE_WHILE_FREEING) { |
1375 | BUG_ON(tm->slot != 0); | 1375 | BUG_ON(tm->slot != 0); |
1376 | eb_rewin = alloc_dummy_extent_buffer(fs_info, eb->start); | 1376 | eb_rewin = alloc_dummy_extent_buffer(fs_info, eb->start, |
1377 | eb->len); | ||
1377 | if (!eb_rewin) { | 1378 | if (!eb_rewin) { |
1378 | btrfs_tree_read_unlock_blocking(eb); | 1379 | btrfs_tree_read_unlock_blocking(eb); |
1379 | free_extent_buffer(eb); | 1380 | free_extent_buffer(eb); |
@@ -1454,7 +1455,8 @@ get_old_root(struct btrfs_root *root, u64 time_seq) | |||
1454 | } else if (old_root) { | 1455 | } else if (old_root) { |
1455 | btrfs_tree_read_unlock(eb_root); | 1456 | btrfs_tree_read_unlock(eb_root); |
1456 | free_extent_buffer(eb_root); | 1457 | free_extent_buffer(eb_root); |
1457 | eb = alloc_dummy_extent_buffer(root->fs_info, logical); | 1458 | eb = alloc_dummy_extent_buffer(root->fs_info, logical, |
1459 | root->nodesize); | ||
1458 | } else { | 1460 | } else { |
1459 | btrfs_set_lock_blocking_rw(eb_root, BTRFS_READ_LOCK); | 1461 | btrfs_set_lock_blocking_rw(eb_root, BTRFS_READ_LOCK); |
1460 | eb = btrfs_clone_extent_buffer(eb_root); | 1462 | eb = btrfs_clone_extent_buffer(eb_root); |
@@ -1552,6 +1554,7 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
1552 | trans->transid, root->fs_info->generation); | 1554 | trans->transid, root->fs_info->generation); |
1553 | 1555 | ||
1554 | if (!should_cow_block(trans, root, buf)) { | 1556 | if (!should_cow_block(trans, root, buf)) { |
1557 | trans->dirty = true; | ||
1555 | *cow_ret = buf; | 1558 | *cow_ret = buf; |
1556 | return 0; | 1559 | return 0; |
1557 | } | 1560 | } |
@@ -2510,6 +2513,8 @@ read_block_for_search(struct btrfs_trans_handle *trans, | |||
2510 | if (!btrfs_buffer_uptodate(tmp, 0, 0)) | 2513 | if (!btrfs_buffer_uptodate(tmp, 0, 0)) |
2511 | ret = -EIO; | 2514 | ret = -EIO; |
2512 | free_extent_buffer(tmp); | 2515 | free_extent_buffer(tmp); |
2516 | } else { | ||
2517 | ret = PTR_ERR(tmp); | ||
2513 | } | 2518 | } |
2514 | return ret; | 2519 | return ret; |
2515 | } | 2520 | } |
@@ -2773,8 +2778,10 @@ again: | |||
2773 | * then we don't want to set the path blocking, | 2778 | * then we don't want to set the path blocking, |
2774 | * so we test it here | 2779 | * so we test it here |
2775 | */ | 2780 | */ |
2776 | if (!should_cow_block(trans, root, b)) | 2781 | if (!should_cow_block(trans, root, b)) { |
2782 | trans->dirty = true; | ||
2777 | goto cow_done; | 2783 | goto cow_done; |
2784 | } | ||
2778 | 2785 | ||
2779 | /* | 2786 | /* |
2780 | * must have write locks on this node and the | 2787 | * must have write locks on this node and the |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 6628fca9f4ed..54cca7a1572b 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); |
@@ -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,18 @@ 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_super_stripesize(sb) != sectorsize) && | ||
4138 | (btrfs_super_stripesize(sb) != 4096))) { | ||
4139 | btrfs_err(fs_info, "invalid stripesize %u", | ||
4140 | btrfs_super_stripesize(sb)); | ||
4141 | ret = -EINVAL; | ||
4142 | } | ||
4133 | if (btrfs_super_num_devices(sb) > (1UL << 31)) | 4143 | if (btrfs_super_num_devices(sb) > (1UL << 31)) |
4134 | printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n", | 4144 | printk(KERN_WARNING "BTRFS: suspicious number of devices: %llu\n", |
4135 | btrfs_super_num_devices(sb)); | 4145 | btrfs_super_num_devices(sb)); |
diff --git a/fs/btrfs/disk-io.h b/fs/btrfs/disk-io.h index 8e79d0070bcf..acba821499a9 100644 --- a/fs/btrfs/disk-io.h +++ b/fs/btrfs/disk-io.h | |||
@@ -90,7 +90,7 @@ void btrfs_drop_and_free_fs_root(struct btrfs_fs_info *fs_info, | |||
90 | void btrfs_free_fs_root(struct btrfs_root *root); | 90 | void btrfs_free_fs_root(struct btrfs_root *root); |
91 | 91 | ||
92 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | 92 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
93 | struct btrfs_root *btrfs_alloc_dummy_root(void); | 93 | struct btrfs_root *btrfs_alloc_dummy_root(u32 sectorsize, u32 nodesize); |
94 | #endif | 94 | #endif |
95 | 95 | ||
96 | /* | 96 | /* |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 689d25ac6a68..29e5d000bbee 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -8016,8 +8016,9 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
8016 | struct extent_buffer *buf; | 8016 | struct extent_buffer *buf; |
8017 | 8017 | ||
8018 | buf = btrfs_find_create_tree_block(root, bytenr); | 8018 | buf = btrfs_find_create_tree_block(root, bytenr); |
8019 | if (!buf) | 8019 | if (IS_ERR(buf)) |
8020 | return ERR_PTR(-ENOMEM); | 8020 | return buf; |
8021 | |||
8021 | btrfs_set_header_generation(buf, trans->transid); | 8022 | btrfs_set_header_generation(buf, trans->transid); |
8022 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level); | 8023 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, buf, level); |
8023 | btrfs_tree_lock(buf); | 8024 | btrfs_tree_lock(buf); |
@@ -8044,7 +8045,7 @@ btrfs_init_new_buffer(struct btrfs_trans_handle *trans, struct btrfs_root *root, | |||
8044 | set_extent_dirty(&trans->transaction->dirty_pages, buf->start, | 8045 | set_extent_dirty(&trans->transaction->dirty_pages, buf->start, |
8045 | buf->start + buf->len - 1, GFP_NOFS); | 8046 | buf->start + buf->len - 1, GFP_NOFS); |
8046 | } | 8047 | } |
8047 | trans->blocks_used++; | 8048 | trans->dirty = true; |
8048 | /* this returns a buffer locked for blocking */ | 8049 | /* this returns a buffer locked for blocking */ |
8049 | return buf; | 8050 | return buf; |
8050 | } | 8051 | } |
@@ -8659,8 +8660,9 @@ static noinline int do_walk_down(struct btrfs_trans_handle *trans, | |||
8659 | next = btrfs_find_tree_block(root->fs_info, bytenr); | 8660 | next = btrfs_find_tree_block(root->fs_info, bytenr); |
8660 | if (!next) { | 8661 | if (!next) { |
8661 | next = btrfs_find_create_tree_block(root, bytenr); | 8662 | next = btrfs_find_create_tree_block(root, bytenr); |
8662 | if (!next) | 8663 | if (IS_ERR(next)) |
8663 | return -ENOMEM; | 8664 | return PTR_ERR(next); |
8665 | |||
8664 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, next, | 8666 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, next, |
8665 | level - 1); | 8667 | level - 1); |
8666 | reada = 1; | 8668 | reada = 1; |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 6e953de83f08..aaee3ef55ed8 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -4728,16 +4728,16 @@ err: | |||
4728 | } | 4728 | } |
4729 | 4729 | ||
4730 | struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, | 4730 | struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, |
4731 | u64 start) | 4731 | u64 start, u32 nodesize) |
4732 | { | 4732 | { |
4733 | unsigned long len; | 4733 | unsigned long len; |
4734 | 4734 | ||
4735 | if (!fs_info) { | 4735 | if (!fs_info) { |
4736 | /* | 4736 | /* |
4737 | * Called only from tests that don't always have a fs_info | 4737 | * Called only from tests that don't always have a fs_info |
4738 | * available, but we know that nodesize is 4096 | 4738 | * available |
4739 | */ | 4739 | */ |
4740 | len = 4096; | 4740 | len = nodesize; |
4741 | } else { | 4741 | } else { |
4742 | len = fs_info->tree_root->nodesize; | 4742 | len = fs_info->tree_root->nodesize; |
4743 | } | 4743 | } |
@@ -4833,7 +4833,7 @@ struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4833 | 4833 | ||
4834 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS | 4834 | #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
4835 | struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, | 4835 | struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, |
4836 | u64 start) | 4836 | u64 start, u32 nodesize) |
4837 | { | 4837 | { |
4838 | struct extent_buffer *eb, *exists = NULL; | 4838 | struct extent_buffer *eb, *exists = NULL; |
4839 | int ret; | 4839 | int ret; |
@@ -4841,7 +4841,7 @@ struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4841 | eb = find_extent_buffer(fs_info, start); | 4841 | eb = find_extent_buffer(fs_info, start); |
4842 | if (eb) | 4842 | if (eb) |
4843 | return eb; | 4843 | return eb; |
4844 | eb = alloc_dummy_extent_buffer(fs_info, start); | 4844 | eb = alloc_dummy_extent_buffer(fs_info, start, nodesize); |
4845 | if (!eb) | 4845 | if (!eb) |
4846 | return NULL; | 4846 | return NULL; |
4847 | eb->fs_info = fs_info; | 4847 | eb->fs_info = fs_info; |
@@ -4892,18 +4892,25 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4892 | int uptodate = 1; | 4892 | int uptodate = 1; |
4893 | int ret; | 4893 | int ret; |
4894 | 4894 | ||
4895 | if (!IS_ALIGNED(start, fs_info->tree_root->sectorsize)) { | ||
4896 | btrfs_err(fs_info, "bad tree block start %llu", start); | ||
4897 | return ERR_PTR(-EINVAL); | ||
4898 | } | ||
4899 | |||
4895 | eb = find_extent_buffer(fs_info, start); | 4900 | eb = find_extent_buffer(fs_info, start); |
4896 | if (eb) | 4901 | if (eb) |
4897 | return eb; | 4902 | return eb; |
4898 | 4903 | ||
4899 | eb = __alloc_extent_buffer(fs_info, start, len); | 4904 | eb = __alloc_extent_buffer(fs_info, start, len); |
4900 | if (!eb) | 4905 | if (!eb) |
4901 | return NULL; | 4906 | return ERR_PTR(-ENOMEM); |
4902 | 4907 | ||
4903 | for (i = 0; i < num_pages; i++, index++) { | 4908 | for (i = 0; i < num_pages; i++, index++) { |
4904 | p = find_or_create_page(mapping, index, GFP_NOFS|__GFP_NOFAIL); | 4909 | p = find_or_create_page(mapping, index, GFP_NOFS|__GFP_NOFAIL); |
4905 | if (!p) | 4910 | if (!p) { |
4911 | exists = ERR_PTR(-ENOMEM); | ||
4906 | goto free_eb; | 4912 | goto free_eb; |
4913 | } | ||
4907 | 4914 | ||
4908 | spin_lock(&mapping->private_lock); | 4915 | spin_lock(&mapping->private_lock); |
4909 | if (PagePrivate(p)) { | 4916 | if (PagePrivate(p)) { |
@@ -4948,8 +4955,10 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, | |||
4948 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); | 4955 | set_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
4949 | again: | 4956 | again: |
4950 | ret = radix_tree_preload(GFP_NOFS); | 4957 | ret = radix_tree_preload(GFP_NOFS); |
4951 | if (ret) | 4958 | if (ret) { |
4959 | exists = ERR_PTR(ret); | ||
4952 | goto free_eb; | 4960 | goto free_eb; |
4961 | } | ||
4953 | 4962 | ||
4954 | spin_lock(&fs_info->buffer_lock); | 4963 | spin_lock(&fs_info->buffer_lock); |
4955 | ret = radix_tree_insert(&fs_info->buffer_radix, | 4964 | ret = radix_tree_insert(&fs_info->buffer_radix, |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 1baf19c9b79d..c0c1c4fef6ce 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -348,7 +348,7 @@ struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, | |||
348 | struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, | 348 | struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, |
349 | u64 start, unsigned long len); | 349 | u64 start, unsigned long len); |
350 | struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, | 350 | struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, |
351 | u64 start); | 351 | u64 start, u32 nodesize); |
352 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); | 352 | struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); |
353 | struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, | 353 | struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, |
354 | u64 start); | 354 | u64 start); |
@@ -468,5 +468,5 @@ noinline u64 find_lock_delalloc_range(struct inode *inode, | |||
468 | u64 *end, u64 max_bytes); | 468 | u64 *end, u64 max_bytes); |
469 | #endif | 469 | #endif |
470 | struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, | 470 | struct extent_buffer *alloc_test_extent_buffer(struct btrfs_fs_info *fs_info, |
471 | u64 start); | 471 | u64 start, u32 nodesize); |
472 | #endif | 472 | #endif |
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index c6dc1183f542..69d270f6602c 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -29,7 +29,7 @@ | |||
29 | #include "inode-map.h" | 29 | #include "inode-map.h" |
30 | #include "volumes.h" | 30 | #include "volumes.h" |
31 | 31 | ||
32 | #define BITS_PER_BITMAP (PAGE_SIZE * 8) | 32 | #define BITS_PER_BITMAP (PAGE_SIZE * 8UL) |
33 | #define MAX_CACHE_BYTES_PER_GIG SZ_32K | 33 | #define MAX_CACHE_BYTES_PER_GIG SZ_32K |
34 | 34 | ||
35 | struct btrfs_trim_range { | 35 | struct btrfs_trim_range { |
@@ -1415,11 +1415,11 @@ static inline u64 offset_to_bitmap(struct btrfs_free_space_ctl *ctl, | |||
1415 | u64 offset) | 1415 | u64 offset) |
1416 | { | 1416 | { |
1417 | u64 bitmap_start; | 1417 | u64 bitmap_start; |
1418 | u32 bytes_per_bitmap; | 1418 | u64 bytes_per_bitmap; |
1419 | 1419 | ||
1420 | bytes_per_bitmap = BITS_PER_BITMAP * ctl->unit; | 1420 | bytes_per_bitmap = BITS_PER_BITMAP * ctl->unit; |
1421 | bitmap_start = offset - ctl->start; | 1421 | bitmap_start = offset - ctl->start; |
1422 | bitmap_start = div_u64(bitmap_start, bytes_per_bitmap); | 1422 | bitmap_start = div64_u64(bitmap_start, bytes_per_bitmap); |
1423 | bitmap_start *= bytes_per_bitmap; | 1423 | bitmap_start *= bytes_per_bitmap; |
1424 | bitmap_start += ctl->start; | 1424 | bitmap_start += ctl->start; |
1425 | 1425 | ||
@@ -1638,10 +1638,10 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) | |||
1638 | u64 bitmap_bytes; | 1638 | u64 bitmap_bytes; |
1639 | u64 extent_bytes; | 1639 | u64 extent_bytes; |
1640 | u64 size = block_group->key.offset; | 1640 | u64 size = block_group->key.offset; |
1641 | u32 bytes_per_bg = BITS_PER_BITMAP * ctl->unit; | 1641 | u64 bytes_per_bg = BITS_PER_BITMAP * ctl->unit; |
1642 | u32 max_bitmaps = div_u64(size + bytes_per_bg - 1, bytes_per_bg); | 1642 | u64 max_bitmaps = div64_u64(size + bytes_per_bg - 1, bytes_per_bg); |
1643 | 1643 | ||
1644 | max_bitmaps = max_t(u32, max_bitmaps, 1); | 1644 | max_bitmaps = max_t(u64, max_bitmaps, 1); |
1645 | 1645 | ||
1646 | ASSERT(ctl->total_bitmaps <= max_bitmaps); | 1646 | ASSERT(ctl->total_bitmaps <= max_bitmaps); |
1647 | 1647 | ||
@@ -1660,7 +1660,7 @@ static void recalculate_thresholds(struct btrfs_free_space_ctl *ctl) | |||
1660 | * sure we don't go over our overall goal of MAX_CACHE_BYTES_PER_GIG as | 1660 | * sure we don't go over our overall goal of MAX_CACHE_BYTES_PER_GIG as |
1661 | * we add more bitmaps. | 1661 | * we add more bitmaps. |
1662 | */ | 1662 | */ |
1663 | bitmap_bytes = (ctl->total_bitmaps + 1) * PAGE_SIZE; | 1663 | bitmap_bytes = (ctl->total_bitmaps + 1) * ctl->unit; |
1664 | 1664 | ||
1665 | if (bitmap_bytes >= max_bytes) { | 1665 | if (bitmap_bytes >= max_bytes) { |
1666 | ctl->extents_thresh = 0; | 1666 | ctl->extents_thresh = 0; |
@@ -3662,7 +3662,7 @@ have_info: | |||
3662 | if (tmp->offset + tmp->bytes < offset) | 3662 | if (tmp->offset + tmp->bytes < offset) |
3663 | break; | 3663 | break; |
3664 | if (offset + bytes < tmp->offset) { | 3664 | if (offset + bytes < tmp->offset) { |
3665 | n = rb_prev(&info->offset_index); | 3665 | n = rb_prev(&tmp->offset_index); |
3666 | continue; | 3666 | continue; |
3667 | } | 3667 | } |
3668 | info = tmp; | 3668 | info = tmp; |
@@ -3676,7 +3676,7 @@ have_info: | |||
3676 | if (offset + bytes < tmp->offset) | 3676 | if (offset + bytes < tmp->offset) |
3677 | break; | 3677 | break; |
3678 | if (tmp->offset + tmp->bytes < offset) { | 3678 | if (tmp->offset + tmp->bytes < offset) { |
3679 | n = rb_next(&info->offset_index); | 3679 | n = rb_next(&tmp->offset_index); |
3680 | continue; | 3680 | continue; |
3681 | } | 3681 | } |
3682 | info = tmp; | 3682 | info = tmp; |
diff --git a/fs/btrfs/hash.c b/fs/btrfs/hash.c index aae520b2aee5..a97fdc156a03 100644 --- a/fs/btrfs/hash.c +++ b/fs/btrfs/hash.c | |||
@@ -24,6 +24,11 @@ int __init btrfs_hash_init(void) | |||
24 | return PTR_ERR_OR_ZERO(tfm); | 24 | return PTR_ERR_OR_ZERO(tfm); |
25 | } | 25 | } |
26 | 26 | ||
27 | const char* btrfs_crc32c_impl(void) | ||
28 | { | ||
29 | return crypto_tfm_alg_driver_name(crypto_shash_tfm(tfm)); | ||
30 | } | ||
31 | |||
27 | void btrfs_hash_exit(void) | 32 | void btrfs_hash_exit(void) |
28 | { | 33 | { |
29 | crypto_free_shash(tfm); | 34 | crypto_free_shash(tfm); |
diff --git a/fs/btrfs/hash.h b/fs/btrfs/hash.h index 118a2316e5d3..c3a2ec554361 100644 --- a/fs/btrfs/hash.h +++ b/fs/btrfs/hash.h | |||
@@ -22,6 +22,7 @@ | |||
22 | int __init btrfs_hash_init(void); | 22 | int __init btrfs_hash_init(void); |
23 | 23 | ||
24 | void btrfs_hash_exit(void); | 24 | void btrfs_hash_exit(void); |
25 | const char* btrfs_crc32c_impl(void); | ||
25 | 26 | ||
26 | u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length); | 27 | u32 btrfs_crc32c(u32 crc, const void *address, unsigned int length); |
27 | 28 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 8b1212e8f7a8..d2be95cfb6d1 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3271,7 +3271,16 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode) | |||
3271 | /* grab metadata reservation from transaction handle */ | 3271 | /* grab metadata reservation from transaction handle */ |
3272 | if (reserve) { | 3272 | if (reserve) { |
3273 | ret = btrfs_orphan_reserve_metadata(trans, inode); | 3273 | ret = btrfs_orphan_reserve_metadata(trans, inode); |
3274 | BUG_ON(ret); /* -ENOSPC in reservation; Logic error? JDM */ | 3274 | ASSERT(!ret); |
3275 | if (ret) { | ||
3276 | atomic_dec(&root->orphan_inodes); | ||
3277 | clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED, | ||
3278 | &BTRFS_I(inode)->runtime_flags); | ||
3279 | if (insert) | ||
3280 | clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM, | ||
3281 | &BTRFS_I(inode)->runtime_flags); | ||
3282 | return ret; | ||
3283 | } | ||
3275 | } | 3284 | } |
3276 | 3285 | ||
3277 | /* insert an orphan item to track this unlinked/truncated file */ | 3286 | /* insert an orphan item to track this unlinked/truncated file */ |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 4e59a91a11e0..60e7179ed4b7 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -235,7 +235,7 @@ void __btrfs_abort_transaction(struct btrfs_trans_handle *trans, | |||
235 | trans->aborted = errno; | 235 | trans->aborted = errno; |
236 | /* Nothing used. The other threads that have joined this | 236 | /* Nothing used. The other threads that have joined this |
237 | * transaction may be able to continue. */ | 237 | * transaction may be able to continue. */ |
238 | if (!trans->blocks_used && list_empty(&trans->new_bgs)) { | 238 | if (!trans->dirty && list_empty(&trans->new_bgs)) { |
239 | const char *errstr; | 239 | const char *errstr; |
240 | 240 | ||
241 | errstr = btrfs_decode_error(errno); | 241 | errstr = btrfs_decode_error(errno); |
@@ -1807,6 +1807,8 @@ static int btrfs_remount(struct super_block *sb, int *flags, char *data) | |||
1807 | } | 1807 | } |
1808 | } | 1808 | } |
1809 | sb->s_flags &= ~MS_RDONLY; | 1809 | sb->s_flags &= ~MS_RDONLY; |
1810 | |||
1811 | fs_info->open = 1; | ||
1810 | } | 1812 | } |
1811 | out: | 1813 | out: |
1812 | wake_up_process(fs_info->transaction_kthread); | 1814 | wake_up_process(fs_info->transaction_kthread); |
@@ -2303,7 +2305,7 @@ static void btrfs_interface_exit(void) | |||
2303 | 2305 | ||
2304 | static void btrfs_print_mod_info(void) | 2306 | static void btrfs_print_mod_info(void) |
2305 | { | 2307 | { |
2306 | printk(KERN_INFO "Btrfs loaded" | 2308 | printk(KERN_INFO "Btrfs loaded, crc32c=%s" |
2307 | #ifdef CONFIG_BTRFS_DEBUG | 2309 | #ifdef CONFIG_BTRFS_DEBUG |
2308 | ", debug=on" | 2310 | ", debug=on" |
2309 | #endif | 2311 | #endif |
@@ -2313,33 +2315,48 @@ static void btrfs_print_mod_info(void) | |||
2313 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY | 2315 | #ifdef CONFIG_BTRFS_FS_CHECK_INTEGRITY |
2314 | ", integrity-checker=on" | 2316 | ", integrity-checker=on" |
2315 | #endif | 2317 | #endif |
2316 | "\n"); | 2318 | "\n", |
2319 | btrfs_crc32c_impl()); | ||
2317 | } | 2320 | } |
2318 | 2321 | ||
2319 | static int btrfs_run_sanity_tests(void) | 2322 | static int btrfs_run_sanity_tests(void) |
2320 | { | 2323 | { |
2321 | int ret; | 2324 | int ret, i; |
2322 | 2325 | u32 sectorsize, nodesize; | |
2326 | u32 test_sectorsize[] = { | ||
2327 | PAGE_SIZE, | ||
2328 | }; | ||
2323 | ret = btrfs_init_test_fs(); | 2329 | ret = btrfs_init_test_fs(); |
2324 | if (ret) | 2330 | if (ret) |
2325 | return ret; | 2331 | return ret; |
2326 | 2332 | for (i = 0; i < ARRAY_SIZE(test_sectorsize); i++) { | |
2327 | ret = btrfs_test_free_space_cache(); | 2333 | sectorsize = test_sectorsize[i]; |
2328 | if (ret) | 2334 | for (nodesize = sectorsize; |
2329 | goto out; | 2335 | nodesize <= BTRFS_MAX_METADATA_BLOCKSIZE; |
2330 | ret = btrfs_test_extent_buffer_operations(); | 2336 | nodesize <<= 1) { |
2331 | if (ret) | 2337 | pr_info("BTRFS: selftest: sectorsize: %u nodesize: %u\n", |
2332 | goto out; | 2338 | sectorsize, nodesize); |
2333 | ret = btrfs_test_extent_io(); | 2339 | ret = btrfs_test_free_space_cache(sectorsize, nodesize); |
2334 | if (ret) | 2340 | if (ret) |
2335 | goto out; | 2341 | goto out; |
2336 | ret = btrfs_test_inodes(); | 2342 | ret = btrfs_test_extent_buffer_operations(sectorsize, |
2337 | if (ret) | 2343 | nodesize); |
2338 | goto out; | 2344 | if (ret) |
2339 | ret = btrfs_test_qgroups(); | 2345 | goto out; |
2340 | if (ret) | 2346 | ret = btrfs_test_extent_io(sectorsize, nodesize); |
2341 | goto out; | 2347 | if (ret) |
2342 | ret = btrfs_test_free_space_tree(); | 2348 | goto out; |
2349 | ret = btrfs_test_inodes(sectorsize, nodesize); | ||
2350 | if (ret) | ||
2351 | goto out; | ||
2352 | ret = btrfs_test_qgroups(sectorsize, nodesize); | ||
2353 | if (ret) | ||
2354 | goto out; | ||
2355 | ret = btrfs_test_free_space_tree(sectorsize, nodesize); | ||
2356 | if (ret) | ||
2357 | goto out; | ||
2358 | } | ||
2359 | } | ||
2343 | out: | 2360 | out: |
2344 | btrfs_destroy_test_fs(); | 2361 | btrfs_destroy_test_fs(); |
2345 | return ret; | 2362 | return ret; |
diff --git a/fs/btrfs/tests/btrfs-tests.c b/fs/btrfs/tests/btrfs-tests.c index f54bf450bad3..10eb249ef891 100644 --- a/fs/btrfs/tests/btrfs-tests.c +++ b/fs/btrfs/tests/btrfs-tests.c | |||
@@ -175,7 +175,7 @@ void btrfs_free_dummy_root(struct btrfs_root *root) | |||
175 | } | 175 | } |
176 | 176 | ||
177 | struct btrfs_block_group_cache * | 177 | struct btrfs_block_group_cache * |
178 | btrfs_alloc_dummy_block_group(unsigned long length) | 178 | btrfs_alloc_dummy_block_group(unsigned long length, u32 sectorsize) |
179 | { | 179 | { |
180 | struct btrfs_block_group_cache *cache; | 180 | struct btrfs_block_group_cache *cache; |
181 | 181 | ||
@@ -192,8 +192,8 @@ btrfs_alloc_dummy_block_group(unsigned long length) | |||
192 | cache->key.objectid = 0; | 192 | cache->key.objectid = 0; |
193 | cache->key.offset = length; | 193 | cache->key.offset = length; |
194 | cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; | 194 | cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; |
195 | cache->sectorsize = 4096; | 195 | cache->sectorsize = sectorsize; |
196 | cache->full_stripe_len = 4096; | 196 | cache->full_stripe_len = sectorsize; |
197 | 197 | ||
198 | INIT_LIST_HEAD(&cache->list); | 198 | INIT_LIST_HEAD(&cache->list); |
199 | INIT_LIST_HEAD(&cache->cluster_list); | 199 | INIT_LIST_HEAD(&cache->cluster_list); |
diff --git a/fs/btrfs/tests/btrfs-tests.h b/fs/btrfs/tests/btrfs-tests.h index 054b8c73c951..66fb6b701eb7 100644 --- a/fs/btrfs/tests/btrfs-tests.h +++ b/fs/btrfs/tests/btrfs-tests.h | |||
@@ -26,27 +26,28 @@ | |||
26 | struct btrfs_root; | 26 | struct btrfs_root; |
27 | struct btrfs_trans_handle; | 27 | struct btrfs_trans_handle; |
28 | 28 | ||
29 | int btrfs_test_free_space_cache(void); | 29 | int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize); |
30 | int btrfs_test_extent_buffer_operations(void); | 30 | int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize); |
31 | int btrfs_test_extent_io(void); | 31 | int btrfs_test_extent_io(u32 sectorsize, u32 nodesize); |
32 | int btrfs_test_inodes(void); | 32 | int btrfs_test_inodes(u32 sectorsize, u32 nodesize); |
33 | int btrfs_test_qgroups(void); | 33 | int btrfs_test_qgroups(u32 sectorsize, u32 nodesize); |
34 | int btrfs_test_free_space_tree(void); | 34 | int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize); |
35 | int btrfs_init_test_fs(void); | 35 | int btrfs_init_test_fs(void); |
36 | void btrfs_destroy_test_fs(void); | 36 | void btrfs_destroy_test_fs(void); |
37 | struct inode *btrfs_new_test_inode(void); | 37 | struct inode *btrfs_new_test_inode(void); |
38 | struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void); | 38 | struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void); |
39 | void btrfs_free_dummy_root(struct btrfs_root *root); | 39 | void btrfs_free_dummy_root(struct btrfs_root *root); |
40 | struct btrfs_block_group_cache * | 40 | struct btrfs_block_group_cache * |
41 | btrfs_alloc_dummy_block_group(unsigned long length); | 41 | btrfs_alloc_dummy_block_group(unsigned long length, u32 sectorsize); |
42 | void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache); | 42 | void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache); |
43 | void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans); | 43 | void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans); |
44 | #else | 44 | #else |
45 | static inline int btrfs_test_free_space_cache(void) | 45 | static inline int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize) |
46 | { | 46 | { |
47 | return 0; | 47 | return 0; |
48 | } | 48 | } |
49 | static inline int btrfs_test_extent_buffer_operations(void) | 49 | static inline int btrfs_test_extent_buffer_operations(u32 sectorsize, |
50 | u32 nodesize) | ||
50 | { | 51 | { |
51 | return 0; | 52 | return 0; |
52 | } | 53 | } |
@@ -57,19 +58,19 @@ static inline int btrfs_init_test_fs(void) | |||
57 | static inline void btrfs_destroy_test_fs(void) | 58 | static inline void btrfs_destroy_test_fs(void) |
58 | { | 59 | { |
59 | } | 60 | } |
60 | static inline int btrfs_test_extent_io(void) | 61 | static inline int btrfs_test_extent_io(u32 sectorsize, u32 nodesize) |
61 | { | 62 | { |
62 | return 0; | 63 | return 0; |
63 | } | 64 | } |
64 | static inline int btrfs_test_inodes(void) | 65 | static inline int btrfs_test_inodes(u32 sectorsize, u32 nodesize) |
65 | { | 66 | { |
66 | return 0; | 67 | return 0; |
67 | } | 68 | } |
68 | static inline int btrfs_test_qgroups(void) | 69 | static inline int btrfs_test_qgroups(u32 sectorsize, u32 nodesize) |
69 | { | 70 | { |
70 | return 0; | 71 | return 0; |
71 | } | 72 | } |
72 | static inline int btrfs_test_free_space_tree(void) | 73 | static inline int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize) |
73 | { | 74 | { |
74 | return 0; | 75 | return 0; |
75 | } | 76 | } |
diff --git a/fs/btrfs/tests/extent-buffer-tests.c b/fs/btrfs/tests/extent-buffer-tests.c index f51963a8f929..4f8cbd1ec5ee 100644 --- a/fs/btrfs/tests/extent-buffer-tests.c +++ b/fs/btrfs/tests/extent-buffer-tests.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "../extent_io.h" | 22 | #include "../extent_io.h" |
23 | #include "../disk-io.h" | 23 | #include "../disk-io.h" |
24 | 24 | ||
25 | static int test_btrfs_split_item(void) | 25 | static int test_btrfs_split_item(u32 sectorsize, u32 nodesize) |
26 | { | 26 | { |
27 | struct btrfs_path *path; | 27 | struct btrfs_path *path; |
28 | struct btrfs_root *root; | 28 | struct btrfs_root *root; |
@@ -40,7 +40,7 @@ static int test_btrfs_split_item(void) | |||
40 | 40 | ||
41 | test_msg("Running btrfs_split_item tests\n"); | 41 | test_msg("Running btrfs_split_item tests\n"); |
42 | 42 | ||
43 | root = btrfs_alloc_dummy_root(); | 43 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
44 | if (IS_ERR(root)) { | 44 | if (IS_ERR(root)) { |
45 | test_msg("Could not allocate root\n"); | 45 | test_msg("Could not allocate root\n"); |
46 | return PTR_ERR(root); | 46 | return PTR_ERR(root); |
@@ -53,7 +53,8 @@ static int test_btrfs_split_item(void) | |||
53 | return -ENOMEM; | 53 | return -ENOMEM; |
54 | } | 54 | } |
55 | 55 | ||
56 | path->nodes[0] = eb = alloc_dummy_extent_buffer(NULL, 4096); | 56 | path->nodes[0] = eb = alloc_dummy_extent_buffer(NULL, nodesize, |
57 | nodesize); | ||
57 | if (!eb) { | 58 | if (!eb) { |
58 | test_msg("Could not allocate dummy buffer\n"); | 59 | test_msg("Could not allocate dummy buffer\n"); |
59 | ret = -ENOMEM; | 60 | ret = -ENOMEM; |
@@ -222,8 +223,8 @@ out: | |||
222 | return ret; | 223 | return ret; |
223 | } | 224 | } |
224 | 225 | ||
225 | int btrfs_test_extent_buffer_operations(void) | 226 | int btrfs_test_extent_buffer_operations(u32 sectorsize, u32 nodesize) |
226 | { | 227 | { |
227 | test_msg("Running extent buffer operation tests"); | 228 | test_msg("Running extent buffer operation tests\n"); |
228 | return test_btrfs_split_item(); | 229 | return test_btrfs_split_item(sectorsize, nodesize); |
229 | } | 230 | } |
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c index 55724607f79b..d19ab0317283 100644 --- a/fs/btrfs/tests/extent-io-tests.c +++ b/fs/btrfs/tests/extent-io-tests.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/sizes.h> | 22 | #include <linux/sizes.h> |
23 | #include "btrfs-tests.h" | 23 | #include "btrfs-tests.h" |
24 | #include "../ctree.h" | ||
24 | #include "../extent_io.h" | 25 | #include "../extent_io.h" |
25 | 26 | ||
26 | #define PROCESS_UNLOCK (1 << 0) | 27 | #define PROCESS_UNLOCK (1 << 0) |
@@ -65,7 +66,7 @@ static noinline int process_page_range(struct inode *inode, u64 start, u64 end, | |||
65 | return count; | 66 | return count; |
66 | } | 67 | } |
67 | 68 | ||
68 | static int test_find_delalloc(void) | 69 | static int test_find_delalloc(u32 sectorsize) |
69 | { | 70 | { |
70 | struct inode *inode; | 71 | struct inode *inode; |
71 | struct extent_io_tree tmp; | 72 | struct extent_io_tree tmp; |
@@ -113,7 +114,7 @@ static int test_find_delalloc(void) | |||
113 | * |--- delalloc ---| | 114 | * |--- delalloc ---| |
114 | * |--- search ---| | 115 | * |--- search ---| |
115 | */ | 116 | */ |
116 | set_extent_delalloc(&tmp, 0, 4095, NULL); | 117 | set_extent_delalloc(&tmp, 0, sectorsize - 1, NULL); |
117 | start = 0; | 118 | start = 0; |
118 | end = 0; | 119 | end = 0; |
119 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | 120 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, |
@@ -122,9 +123,9 @@ static int test_find_delalloc(void) | |||
122 | test_msg("Should have found at least one delalloc\n"); | 123 | test_msg("Should have found at least one delalloc\n"); |
123 | goto out_bits; | 124 | goto out_bits; |
124 | } | 125 | } |
125 | if (start != 0 || end != 4095) { | 126 | if (start != 0 || end != (sectorsize - 1)) { |
126 | test_msg("Expected start 0 end 4095, got start %Lu end %Lu\n", | 127 | test_msg("Expected start 0 end %u, got start %llu end %llu\n", |
127 | start, end); | 128 | sectorsize - 1, start, end); |
128 | goto out_bits; | 129 | goto out_bits; |
129 | } | 130 | } |
130 | unlock_extent(&tmp, start, end); | 131 | unlock_extent(&tmp, start, end); |
@@ -144,7 +145,7 @@ static int test_find_delalloc(void) | |||
144 | test_msg("Couldn't find the locked page\n"); | 145 | test_msg("Couldn't find the locked page\n"); |
145 | goto out_bits; | 146 | goto out_bits; |
146 | } | 147 | } |
147 | set_extent_delalloc(&tmp, 4096, max_bytes - 1, NULL); | 148 | set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, NULL); |
148 | start = test_start; | 149 | start = test_start; |
149 | end = 0; | 150 | end = 0; |
150 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, | 151 | found = find_lock_delalloc_range(inode, &tmp, locked_page, &start, |
@@ -172,7 +173,7 @@ static int test_find_delalloc(void) | |||
172 | * |--- delalloc ---| | 173 | * |--- delalloc ---| |
173 | * |--- search ---| | 174 | * |--- search ---| |
174 | */ | 175 | */ |
175 | test_start = max_bytes + 4096; | 176 | test_start = max_bytes + sectorsize; |
176 | locked_page = find_lock_page(inode->i_mapping, test_start >> | 177 | locked_page = find_lock_page(inode->i_mapping, test_start >> |
177 | PAGE_SHIFT); | 178 | PAGE_SHIFT); |
178 | if (!locked_page) { | 179 | if (!locked_page) { |
@@ -272,6 +273,16 @@ out: | |||
272 | return ret; | 273 | return ret; |
273 | } | 274 | } |
274 | 275 | ||
276 | /** | ||
277 | * test_bit_in_byte - Determine whether a bit is set in a byte | ||
278 | * @nr: bit number to test | ||
279 | * @addr: Address to start counting from | ||
280 | */ | ||
281 | static inline int test_bit_in_byte(int nr, const u8 *addr) | ||
282 | { | ||
283 | return 1UL & (addr[nr / BITS_PER_BYTE] >> (nr & (BITS_PER_BYTE - 1))); | ||
284 | } | ||
285 | |||
275 | static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, | 286 | static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, |
276 | unsigned long len) | 287 | unsigned long len) |
277 | { | 288 | { |
@@ -298,25 +309,29 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, | |||
298 | return -EINVAL; | 309 | return -EINVAL; |
299 | } | 310 | } |
300 | 311 | ||
301 | bitmap_set(bitmap, (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, | 312 | /* Straddling pages test */ |
302 | sizeof(long) * BITS_PER_BYTE); | 313 | if (len > PAGE_SIZE) { |
303 | extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0, | 314 | bitmap_set(bitmap, |
304 | sizeof(long) * BITS_PER_BYTE); | 315 | (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, |
305 | if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { | 316 | sizeof(long) * BITS_PER_BYTE); |
306 | test_msg("Setting straddling pages failed\n"); | 317 | extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0, |
307 | return -EINVAL; | 318 | sizeof(long) * BITS_PER_BYTE); |
308 | } | 319 | if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { |
320 | test_msg("Setting straddling pages failed\n"); | ||
321 | return -EINVAL; | ||
322 | } | ||
309 | 323 | ||
310 | bitmap_set(bitmap, 0, len * BITS_PER_BYTE); | 324 | bitmap_set(bitmap, 0, len * BITS_PER_BYTE); |
311 | bitmap_clear(bitmap, | 325 | bitmap_clear(bitmap, |
312 | (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, | 326 | (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, |
313 | sizeof(long) * BITS_PER_BYTE); | 327 | sizeof(long) * BITS_PER_BYTE); |
314 | extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); | 328 | extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); |
315 | extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0, | 329 | extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0, |
316 | sizeof(long) * BITS_PER_BYTE); | 330 | sizeof(long) * BITS_PER_BYTE); |
317 | if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { | 331 | if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { |
318 | test_msg("Clearing straddling pages failed\n"); | 332 | test_msg("Clearing straddling pages failed\n"); |
319 | return -EINVAL; | 333 | return -EINVAL; |
334 | } | ||
320 | } | 335 | } |
321 | 336 | ||
322 | /* | 337 | /* |
@@ -333,7 +348,7 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, | |||
333 | for (i = 0; i < len * BITS_PER_BYTE; i++) { | 348 | for (i = 0; i < len * BITS_PER_BYTE; i++) { |
334 | int bit, bit1; | 349 | int bit, bit1; |
335 | 350 | ||
336 | bit = !!test_bit(i, bitmap); | 351 | bit = !!test_bit_in_byte(i, (u8 *)bitmap); |
337 | bit1 = !!extent_buffer_test_bit(eb, 0, i); | 352 | bit1 = !!extent_buffer_test_bit(eb, 0, i); |
338 | if (bit1 != bit) { | 353 | if (bit1 != bit) { |
339 | test_msg("Testing bit pattern failed\n"); | 354 | test_msg("Testing bit pattern failed\n"); |
@@ -351,15 +366,22 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, | |||
351 | return 0; | 366 | return 0; |
352 | } | 367 | } |
353 | 368 | ||
354 | static int test_eb_bitmaps(void) | 369 | static int test_eb_bitmaps(u32 sectorsize, u32 nodesize) |
355 | { | 370 | { |
356 | unsigned long len = PAGE_SIZE * 4; | 371 | unsigned long len; |
357 | unsigned long *bitmap; | 372 | unsigned long *bitmap; |
358 | struct extent_buffer *eb; | 373 | struct extent_buffer *eb; |
359 | int ret; | 374 | int ret; |
360 | 375 | ||
361 | test_msg("Running extent buffer bitmap tests\n"); | 376 | test_msg("Running extent buffer bitmap tests\n"); |
362 | 377 | ||
378 | /* | ||
379 | * In ppc64, sectorsize can be 64K, thus 4 * 64K will be larger than | ||
380 | * BTRFS_MAX_METADATA_BLOCKSIZE. | ||
381 | */ | ||
382 | len = (sectorsize < BTRFS_MAX_METADATA_BLOCKSIZE) | ||
383 | ? sectorsize * 4 : sectorsize; | ||
384 | |||
363 | bitmap = kmalloc(len, GFP_KERNEL); | 385 | bitmap = kmalloc(len, GFP_KERNEL); |
364 | if (!bitmap) { | 386 | if (!bitmap) { |
365 | test_msg("Couldn't allocate test bitmap\n"); | 387 | test_msg("Couldn't allocate test bitmap\n"); |
@@ -379,7 +401,7 @@ static int test_eb_bitmaps(void) | |||
379 | 401 | ||
380 | /* Do it over again with an extent buffer which isn't page-aligned. */ | 402 | /* Do it over again with an extent buffer which isn't page-aligned. */ |
381 | free_extent_buffer(eb); | 403 | free_extent_buffer(eb); |
382 | eb = __alloc_dummy_extent_buffer(NULL, PAGE_SIZE / 2, len); | 404 | eb = __alloc_dummy_extent_buffer(NULL, nodesize / 2, len); |
383 | if (!eb) { | 405 | if (!eb) { |
384 | test_msg("Couldn't allocate test extent buffer\n"); | 406 | test_msg("Couldn't allocate test extent buffer\n"); |
385 | kfree(bitmap); | 407 | kfree(bitmap); |
@@ -393,17 +415,17 @@ out: | |||
393 | return ret; | 415 | return ret; |
394 | } | 416 | } |
395 | 417 | ||
396 | int btrfs_test_extent_io(void) | 418 | int btrfs_test_extent_io(u32 sectorsize, u32 nodesize) |
397 | { | 419 | { |
398 | int ret; | 420 | int ret; |
399 | 421 | ||
400 | test_msg("Running extent I/O tests\n"); | 422 | test_msg("Running extent I/O tests\n"); |
401 | 423 | ||
402 | ret = test_find_delalloc(); | 424 | ret = test_find_delalloc(sectorsize); |
403 | if (ret) | 425 | if (ret) |
404 | goto out; | 426 | goto out; |
405 | 427 | ||
406 | ret = test_eb_bitmaps(); | 428 | ret = test_eb_bitmaps(sectorsize, nodesize); |
407 | out: | 429 | out: |
408 | test_msg("Extent I/O tests finished\n"); | 430 | test_msg("Extent I/O tests finished\n"); |
409 | return ret; | 431 | return ret; |
diff --git a/fs/btrfs/tests/free-space-tests.c b/fs/btrfs/tests/free-space-tests.c index 0eeb8f3d6b67..3956bb2ff84c 100644 --- a/fs/btrfs/tests/free-space-tests.c +++ b/fs/btrfs/tests/free-space-tests.c | |||
@@ -22,7 +22,7 @@ | |||
22 | #include "../disk-io.h" | 22 | #include "../disk-io.h" |
23 | #include "../free-space-cache.h" | 23 | #include "../free-space-cache.h" |
24 | 24 | ||
25 | #define BITS_PER_BITMAP (PAGE_SIZE * 8) | 25 | #define BITS_PER_BITMAP (PAGE_SIZE * 8UL) |
26 | 26 | ||
27 | /* | 27 | /* |
28 | * This test just does basic sanity checking, making sure we can add an extent | 28 | * This test just does basic sanity checking, making sure we can add an extent |
@@ -99,7 +99,8 @@ static int test_extents(struct btrfs_block_group_cache *cache) | |||
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | 101 | ||
102 | static int test_bitmaps(struct btrfs_block_group_cache *cache) | 102 | static int test_bitmaps(struct btrfs_block_group_cache *cache, |
103 | u32 sectorsize) | ||
103 | { | 104 | { |
104 | u64 next_bitmap_offset; | 105 | u64 next_bitmap_offset; |
105 | int ret; | 106 | int ret; |
@@ -139,7 +140,7 @@ static int test_bitmaps(struct btrfs_block_group_cache *cache) | |||
139 | * The first bitmap we have starts at offset 0 so the next one is just | 140 | * The first bitmap we have starts at offset 0 so the next one is just |
140 | * at the end of the first bitmap. | 141 | * at the end of the first bitmap. |
141 | */ | 142 | */ |
142 | next_bitmap_offset = (u64)(BITS_PER_BITMAP * 4096); | 143 | next_bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize); |
143 | 144 | ||
144 | /* Test a bit straddling two bitmaps */ | 145 | /* Test a bit straddling two bitmaps */ |
145 | ret = test_add_free_space_entry(cache, next_bitmap_offset - SZ_2M, | 146 | ret = test_add_free_space_entry(cache, next_bitmap_offset - SZ_2M, |
@@ -167,9 +168,10 @@ static int test_bitmaps(struct btrfs_block_group_cache *cache) | |||
167 | } | 168 | } |
168 | 169 | ||
169 | /* This is the high grade jackassery */ | 170 | /* This is the high grade jackassery */ |
170 | static int test_bitmaps_and_extents(struct btrfs_block_group_cache *cache) | 171 | static int test_bitmaps_and_extents(struct btrfs_block_group_cache *cache, |
172 | u32 sectorsize) | ||
171 | { | 173 | { |
172 | u64 bitmap_offset = (u64)(BITS_PER_BITMAP * 4096); | 174 | u64 bitmap_offset = (u64)(BITS_PER_BITMAP * sectorsize); |
173 | int ret; | 175 | int ret; |
174 | 176 | ||
175 | test_msg("Running bitmap and extent tests\n"); | 177 | test_msg("Running bitmap and extent tests\n"); |
@@ -401,7 +403,8 @@ static int check_cache_empty(struct btrfs_block_group_cache *cache) | |||
401 | * requests. | 403 | * requests. |
402 | */ | 404 | */ |
403 | static int | 405 | static int |
404 | test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | 406 | test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache, |
407 | u32 sectorsize) | ||
405 | { | 408 | { |
406 | int ret; | 409 | int ret; |
407 | u64 offset; | 410 | u64 offset; |
@@ -539,7 +542,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
539 | * The goal is to test that the bitmap entry space stealing doesn't | 542 | * The goal is to test that the bitmap entry space stealing doesn't |
540 | * steal this space region. | 543 | * steal this space region. |
541 | */ | 544 | */ |
542 | ret = btrfs_add_free_space(cache, SZ_128M + SZ_16M, 4096); | 545 | ret = btrfs_add_free_space(cache, SZ_128M + SZ_16M, sectorsize); |
543 | if (ret) { | 546 | if (ret) { |
544 | test_msg("Error adding free space: %d\n", ret); | 547 | test_msg("Error adding free space: %d\n", ret); |
545 | return ret; | 548 | return ret; |
@@ -597,8 +600,8 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
597 | return -ENOENT; | 600 | return -ENOENT; |
598 | } | 601 | } |
599 | 602 | ||
600 | if (cache->free_space_ctl->free_space != (SZ_1M + 4096)) { | 603 | if (cache->free_space_ctl->free_space != (SZ_1M + sectorsize)) { |
601 | test_msg("Cache free space is not 1Mb + 4Kb\n"); | 604 | test_msg("Cache free space is not 1Mb + %u\n", sectorsize); |
602 | return -EINVAL; | 605 | return -EINVAL; |
603 | } | 606 | } |
604 | 607 | ||
@@ -611,22 +614,25 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
611 | return -EINVAL; | 614 | return -EINVAL; |
612 | } | 615 | } |
613 | 616 | ||
614 | /* All that remains is a 4Kb free space region in a bitmap. Confirm. */ | 617 | /* |
618 | * All that remains is a sectorsize free space region in a bitmap. | ||
619 | * Confirm. | ||
620 | */ | ||
615 | ret = check_num_extents_and_bitmaps(cache, 1, 1); | 621 | ret = check_num_extents_and_bitmaps(cache, 1, 1); |
616 | if (ret) | 622 | if (ret) |
617 | return ret; | 623 | return ret; |
618 | 624 | ||
619 | if (cache->free_space_ctl->free_space != 4096) { | 625 | if (cache->free_space_ctl->free_space != sectorsize) { |
620 | test_msg("Cache free space is not 4Kb\n"); | 626 | test_msg("Cache free space is not %u\n", sectorsize); |
621 | return -EINVAL; | 627 | return -EINVAL; |
622 | } | 628 | } |
623 | 629 | ||
624 | offset = btrfs_find_space_for_alloc(cache, | 630 | offset = btrfs_find_space_for_alloc(cache, |
625 | 0, 4096, 0, | 631 | 0, sectorsize, 0, |
626 | &max_extent_size); | 632 | &max_extent_size); |
627 | if (offset != (SZ_128M + SZ_16M)) { | 633 | if (offset != (SZ_128M + SZ_16M)) { |
628 | test_msg("Failed to allocate 4Kb from space cache, returned offset is: %llu\n", | 634 | test_msg("Failed to allocate %u, returned offset : %llu\n", |
629 | offset); | 635 | sectorsize, offset); |
630 | return -EINVAL; | 636 | return -EINVAL; |
631 | } | 637 | } |
632 | 638 | ||
@@ -733,7 +739,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
733 | * The goal is to test that the bitmap entry space stealing doesn't | 739 | * The goal is to test that the bitmap entry space stealing doesn't |
734 | * steal this space region. | 740 | * steal this space region. |
735 | */ | 741 | */ |
736 | ret = btrfs_add_free_space(cache, SZ_32M, 8192); | 742 | ret = btrfs_add_free_space(cache, SZ_32M, 2 * sectorsize); |
737 | if (ret) { | 743 | if (ret) { |
738 | test_msg("Error adding free space: %d\n", ret); | 744 | test_msg("Error adding free space: %d\n", ret); |
739 | return ret; | 745 | return ret; |
@@ -757,7 +763,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
757 | 763 | ||
758 | /* | 764 | /* |
759 | * Confirm that our extent entry didn't stole all free space from the | 765 | * Confirm that our extent entry didn't stole all free space from the |
760 | * bitmap, because of the small 8Kb free space region. | 766 | * bitmap, because of the small 2 * sectorsize free space region. |
761 | */ | 767 | */ |
762 | ret = check_num_extents_and_bitmaps(cache, 2, 1); | 768 | ret = check_num_extents_and_bitmaps(cache, 2, 1); |
763 | if (ret) | 769 | if (ret) |
@@ -783,8 +789,8 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
783 | return -ENOENT; | 789 | return -ENOENT; |
784 | } | 790 | } |
785 | 791 | ||
786 | if (cache->free_space_ctl->free_space != (SZ_1M + 8192)) { | 792 | if (cache->free_space_ctl->free_space != (SZ_1M + 2 * sectorsize)) { |
787 | test_msg("Cache free space is not 1Mb + 8Kb\n"); | 793 | test_msg("Cache free space is not 1Mb + %u\n", 2 * sectorsize); |
788 | return -EINVAL; | 794 | return -EINVAL; |
789 | } | 795 | } |
790 | 796 | ||
@@ -796,21 +802,25 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
796 | return -EINVAL; | 802 | return -EINVAL; |
797 | } | 803 | } |
798 | 804 | ||
799 | /* All that remains is a 8Kb free space region in a bitmap. Confirm. */ | 805 | /* |
806 | * All that remains is 2 * sectorsize free space region | ||
807 | * in a bitmap. Confirm. | ||
808 | */ | ||
800 | ret = check_num_extents_and_bitmaps(cache, 1, 1); | 809 | ret = check_num_extents_and_bitmaps(cache, 1, 1); |
801 | if (ret) | 810 | if (ret) |
802 | return ret; | 811 | return ret; |
803 | 812 | ||
804 | if (cache->free_space_ctl->free_space != 8192) { | 813 | if (cache->free_space_ctl->free_space != 2 * sectorsize) { |
805 | test_msg("Cache free space is not 8Kb\n"); | 814 | test_msg("Cache free space is not %u\n", 2 * sectorsize); |
806 | return -EINVAL; | 815 | return -EINVAL; |
807 | } | 816 | } |
808 | 817 | ||
809 | offset = btrfs_find_space_for_alloc(cache, | 818 | offset = btrfs_find_space_for_alloc(cache, |
810 | 0, 8192, 0, | 819 | 0, 2 * sectorsize, 0, |
811 | &max_extent_size); | 820 | &max_extent_size); |
812 | if (offset != SZ_32M) { | 821 | if (offset != SZ_32M) { |
813 | test_msg("Failed to allocate 8Kb from space cache, returned offset is: %llu\n", | 822 | test_msg("Failed to allocate %u, offset: %llu\n", |
823 | 2 * sectorsize, | ||
814 | offset); | 824 | offset); |
815 | return -EINVAL; | 825 | return -EINVAL; |
816 | } | 826 | } |
@@ -825,7 +835,7 @@ test_steal_space_from_bitmap_to_extent(struct btrfs_block_group_cache *cache) | |||
825 | return 0; | 835 | return 0; |
826 | } | 836 | } |
827 | 837 | ||
828 | int btrfs_test_free_space_cache(void) | 838 | int btrfs_test_free_space_cache(u32 sectorsize, u32 nodesize) |
829 | { | 839 | { |
830 | struct btrfs_block_group_cache *cache; | 840 | struct btrfs_block_group_cache *cache; |
831 | struct btrfs_root *root = NULL; | 841 | struct btrfs_root *root = NULL; |
@@ -833,13 +843,19 @@ int btrfs_test_free_space_cache(void) | |||
833 | 843 | ||
834 | test_msg("Running btrfs free space cache tests\n"); | 844 | test_msg("Running btrfs free space cache tests\n"); |
835 | 845 | ||
836 | cache = btrfs_alloc_dummy_block_group(1024 * 1024 * 1024); | 846 | /* |
847 | * For ppc64 (with 64k page size), bytes per bitmap might be | ||
848 | * larger than 1G. To make bitmap test available in ppc64, | ||
849 | * alloc dummy block group whose size cross bitmaps. | ||
850 | */ | ||
851 | cache = btrfs_alloc_dummy_block_group(BITS_PER_BITMAP * sectorsize | ||
852 | + PAGE_SIZE, sectorsize); | ||
837 | if (!cache) { | 853 | if (!cache) { |
838 | test_msg("Couldn't run the tests\n"); | 854 | test_msg("Couldn't run the tests\n"); |
839 | return 0; | 855 | return 0; |
840 | } | 856 | } |
841 | 857 | ||
842 | root = btrfs_alloc_dummy_root(); | 858 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
843 | if (IS_ERR(root)) { | 859 | if (IS_ERR(root)) { |
844 | ret = PTR_ERR(root); | 860 | ret = PTR_ERR(root); |
845 | goto out; | 861 | goto out; |
@@ -855,14 +871,14 @@ int btrfs_test_free_space_cache(void) | |||
855 | ret = test_extents(cache); | 871 | ret = test_extents(cache); |
856 | if (ret) | 872 | if (ret) |
857 | goto out; | 873 | goto out; |
858 | ret = test_bitmaps(cache); | 874 | ret = test_bitmaps(cache, sectorsize); |
859 | if (ret) | 875 | if (ret) |
860 | goto out; | 876 | goto out; |
861 | ret = test_bitmaps_and_extents(cache); | 877 | ret = test_bitmaps_and_extents(cache, sectorsize); |
862 | if (ret) | 878 | if (ret) |
863 | goto out; | 879 | goto out; |
864 | 880 | ||
865 | ret = test_steal_space_from_bitmap_to_extent(cache); | 881 | ret = test_steal_space_from_bitmap_to_extent(cache, sectorsize); |
866 | out: | 882 | out: |
867 | btrfs_free_dummy_block_group(cache); | 883 | btrfs_free_dummy_block_group(cache); |
868 | btrfs_free_dummy_root(root); | 884 | btrfs_free_dummy_root(root); |
diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c index 7cea4462acd5..aac507085ab0 100644 --- a/fs/btrfs/tests/free-space-tree-tests.c +++ b/fs/btrfs/tests/free-space-tree-tests.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/types.h> | ||
19 | #include "btrfs-tests.h" | 20 | #include "btrfs-tests.h" |
20 | #include "../ctree.h" | 21 | #include "../ctree.h" |
21 | #include "../disk-io.h" | 22 | #include "../disk-io.h" |
@@ -30,7 +31,7 @@ struct free_space_extent { | |||
30 | * The test cases align their operations to this in order to hit some of the | 31 | * The test cases align their operations to this in order to hit some of the |
31 | * edge cases in the bitmap code. | 32 | * edge cases in the bitmap code. |
32 | */ | 33 | */ |
33 | #define BITMAP_RANGE (BTRFS_FREE_SPACE_BITMAP_BITS * 4096) | 34 | #define BITMAP_RANGE (BTRFS_FREE_SPACE_BITMAP_BITS * PAGE_SIZE) |
34 | 35 | ||
35 | static int __check_free_space_extents(struct btrfs_trans_handle *trans, | 36 | static int __check_free_space_extents(struct btrfs_trans_handle *trans, |
36 | struct btrfs_fs_info *fs_info, | 37 | struct btrfs_fs_info *fs_info, |
@@ -439,7 +440,8 @@ typedef int (*test_func_t)(struct btrfs_trans_handle *, | |||
439 | struct btrfs_block_group_cache *, | 440 | struct btrfs_block_group_cache *, |
440 | struct btrfs_path *); | 441 | struct btrfs_path *); |
441 | 442 | ||
442 | static int run_test(test_func_t test_func, int bitmaps) | 443 | static int run_test(test_func_t test_func, int bitmaps, |
444 | u32 sectorsize, u32 nodesize) | ||
443 | { | 445 | { |
444 | struct btrfs_root *root = NULL; | 446 | struct btrfs_root *root = NULL; |
445 | struct btrfs_block_group_cache *cache = NULL; | 447 | struct btrfs_block_group_cache *cache = NULL; |
@@ -447,7 +449,7 @@ static int run_test(test_func_t test_func, int bitmaps) | |||
447 | struct btrfs_path *path = NULL; | 449 | struct btrfs_path *path = NULL; |
448 | int ret; | 450 | int ret; |
449 | 451 | ||
450 | root = btrfs_alloc_dummy_root(); | 452 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
451 | if (IS_ERR(root)) { | 453 | if (IS_ERR(root)) { |
452 | test_msg("Couldn't allocate dummy root\n"); | 454 | test_msg("Couldn't allocate dummy root\n"); |
453 | ret = PTR_ERR(root); | 455 | ret = PTR_ERR(root); |
@@ -466,7 +468,8 @@ static int run_test(test_func_t test_func, int bitmaps) | |||
466 | root->fs_info->free_space_root = root; | 468 | root->fs_info->free_space_root = root; |
467 | root->fs_info->tree_root = root; | 469 | root->fs_info->tree_root = root; |
468 | 470 | ||
469 | root->node = alloc_test_extent_buffer(root->fs_info, 4096); | 471 | root->node = alloc_test_extent_buffer(root->fs_info, |
472 | nodesize, nodesize); | ||
470 | if (!root->node) { | 473 | if (!root->node) { |
471 | test_msg("Couldn't allocate dummy buffer\n"); | 474 | test_msg("Couldn't allocate dummy buffer\n"); |
472 | ret = -ENOMEM; | 475 | ret = -ENOMEM; |
@@ -474,9 +477,9 @@ static int run_test(test_func_t test_func, int bitmaps) | |||
474 | } | 477 | } |
475 | btrfs_set_header_level(root->node, 0); | 478 | btrfs_set_header_level(root->node, 0); |
476 | btrfs_set_header_nritems(root->node, 0); | 479 | btrfs_set_header_nritems(root->node, 0); |
477 | root->alloc_bytenr += 8192; | 480 | root->alloc_bytenr += 2 * nodesize; |
478 | 481 | ||
479 | cache = btrfs_alloc_dummy_block_group(8 * BITMAP_RANGE); | 482 | cache = btrfs_alloc_dummy_block_group(8 * BITMAP_RANGE, sectorsize); |
480 | if (!cache) { | 483 | if (!cache) { |
481 | test_msg("Couldn't allocate dummy block group cache\n"); | 484 | test_msg("Couldn't allocate dummy block group cache\n"); |
482 | ret = -ENOMEM; | 485 | ret = -ENOMEM; |
@@ -534,17 +537,18 @@ out: | |||
534 | return ret; | 537 | return ret; |
535 | } | 538 | } |
536 | 539 | ||
537 | static int run_test_both_formats(test_func_t test_func) | 540 | static int run_test_both_formats(test_func_t test_func, |
541 | u32 sectorsize, u32 nodesize) | ||
538 | { | 542 | { |
539 | int ret; | 543 | int ret; |
540 | 544 | ||
541 | ret = run_test(test_func, 0); | 545 | ret = run_test(test_func, 0, sectorsize, nodesize); |
542 | if (ret) | 546 | if (ret) |
543 | return ret; | 547 | return ret; |
544 | return run_test(test_func, 1); | 548 | return run_test(test_func, 1, sectorsize, nodesize); |
545 | } | 549 | } |
546 | 550 | ||
547 | int btrfs_test_free_space_tree(void) | 551 | int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize) |
548 | { | 552 | { |
549 | test_func_t tests[] = { | 553 | test_func_t tests[] = { |
550 | test_empty_block_group, | 554 | test_empty_block_group, |
@@ -561,9 +565,11 @@ int btrfs_test_free_space_tree(void) | |||
561 | 565 | ||
562 | test_msg("Running free space tree tests\n"); | 566 | test_msg("Running free space tree tests\n"); |
563 | for (i = 0; i < ARRAY_SIZE(tests); i++) { | 567 | for (i = 0; i < ARRAY_SIZE(tests); i++) { |
564 | int ret = run_test_both_formats(tests[i]); | 568 | int ret = run_test_both_formats(tests[i], sectorsize, |
569 | nodesize); | ||
565 | if (ret) { | 570 | if (ret) { |
566 | test_msg("%pf failed\n", tests[i]); | 571 | test_msg("%pf : sectorsize %u failed\n", |
572 | tests[i], sectorsize); | ||
567 | return ret; | 573 | return ret; |
568 | } | 574 | } |
569 | } | 575 | } |
diff --git a/fs/btrfs/tests/inode-tests.c b/fs/btrfs/tests/inode-tests.c index 8a25fe8b7c45..29648c0a39f1 100644 --- a/fs/btrfs/tests/inode-tests.c +++ b/fs/btrfs/tests/inode-tests.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/types.h> | ||
19 | #include "btrfs-tests.h" | 20 | #include "btrfs-tests.h" |
20 | #include "../ctree.h" | 21 | #include "../ctree.h" |
21 | #include "../btrfs_inode.h" | 22 | #include "../btrfs_inode.h" |
@@ -86,19 +87,19 @@ static void insert_inode_item_key(struct btrfs_root *root) | |||
86 | * diagram of how the extents will look though this may not be possible we still | 87 | * diagram of how the extents will look though this may not be possible we still |
87 | * want to make sure everything acts normally (the last number is not inclusive) | 88 | * want to make sure everything acts normally (the last number is not inclusive) |
88 | * | 89 | * |
89 | * [0 - 5][5 - 6][6 - 10][10 - 4096][ 4096 - 8192 ][8192 - 12288] | 90 | * [0 - 5][5 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291] |
90 | * [hole ][inline][ hole ][ regular ][regular1 split][ hole ] | 91 | * [hole ][inline][hole but no extent][ hole ][ regular ][regular1 split] |
91 | * | 92 | * |
92 | * [ 12288 - 20480][20480 - 24576][ 24576 - 28672 ][28672 - 36864][36864 - 45056] | 93 | * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ] |
93 | * [regular1 split][ prealloc1 ][prealloc1 written][ prealloc1 ][ compressed ] | 94 | * [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written] |
94 | * | 95 | * |
95 | * [45056 - 49152][49152-53248][53248-61440][61440-65536][ 65536+81920 ] | 96 | * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635] |
96 | * [ compressed1 ][ regular ][compressed1][ regular ][ hole but no extent] | 97 | * [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1] |
97 | * | 98 | * |
98 | * [81920-86016] | 99 | * [69635-73731][ 73731 - 86019 ][86019-90115] |
99 | * [ regular ] | 100 | * [ regular ][ hole but no extent][ regular ] |
100 | */ | 101 | */ |
101 | static void setup_file_extents(struct btrfs_root *root) | 102 | static void setup_file_extents(struct btrfs_root *root, u32 sectorsize) |
102 | { | 103 | { |
103 | int slot = 0; | 104 | int slot = 0; |
104 | u64 disk_bytenr = SZ_1M; | 105 | u64 disk_bytenr = SZ_1M; |
@@ -119,7 +120,7 @@ static void setup_file_extents(struct btrfs_root *root) | |||
119 | insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0, | 120 | insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0, |
120 | slot); | 121 | slot); |
121 | slot++; | 122 | slot++; |
122 | offset = 4096; | 123 | offset = sectorsize; |
123 | 124 | ||
124 | /* Now another hole */ | 125 | /* Now another hole */ |
125 | insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, | 126 | insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, |
@@ -128,99 +129,106 @@ static void setup_file_extents(struct btrfs_root *root) | |||
128 | offset += 4; | 129 | offset += 4; |
129 | 130 | ||
130 | /* Now for a regular extent */ | 131 | /* Now for a regular extent */ |
131 | insert_extent(root, offset, 4095, 4095, 0, disk_bytenr, 4096, | 132 | insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0, |
132 | BTRFS_FILE_EXTENT_REG, 0, slot); | 133 | disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); |
133 | slot++; | 134 | slot++; |
134 | disk_bytenr += 4096; | 135 | disk_bytenr += sectorsize; |
135 | offset += 4095; | 136 | offset += sectorsize - 1; |
136 | 137 | ||
137 | /* | 138 | /* |
138 | * Now for 3 extents that were split from a hole punch so we test | 139 | * Now for 3 extents that were split from a hole punch so we test |
139 | * offsets properly. | 140 | * offsets properly. |
140 | */ | 141 | */ |
141 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384, | 142 | insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, |
142 | BTRFS_FILE_EXTENT_REG, 0, slot); | 143 | 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); |
143 | slot++; | 144 | slot++; |
144 | offset += 4096; | 145 | offset += sectorsize; |
145 | insert_extent(root, offset, 4096, 4096, 0, 0, 0, BTRFS_FILE_EXTENT_REG, | 146 | insert_extent(root, offset, sectorsize, sectorsize, 0, 0, 0, |
146 | 0, slot); | 147 | BTRFS_FILE_EXTENT_REG, 0, slot); |
147 | slot++; | 148 | slot++; |
148 | offset += 4096; | 149 | offset += sectorsize; |
149 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384, | 150 | insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, |
151 | 2 * sectorsize, disk_bytenr, 4 * sectorsize, | ||
150 | BTRFS_FILE_EXTENT_REG, 0, slot); | 152 | BTRFS_FILE_EXTENT_REG, 0, slot); |
151 | slot++; | 153 | slot++; |
152 | offset += 8192; | 154 | offset += 2 * sectorsize; |
153 | disk_bytenr += 16384; | 155 | disk_bytenr += 4 * sectorsize; |
154 | 156 | ||
155 | /* Now for a unwritten prealloc extent */ | 157 | /* Now for a unwritten prealloc extent */ |
156 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | 158 | insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, |
157 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | 159 | sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot); |
158 | slot++; | 160 | slot++; |
159 | offset += 4096; | 161 | offset += sectorsize; |
160 | 162 | ||
161 | /* | 163 | /* |
162 | * We want to jack up disk_bytenr a little more so the em stuff doesn't | 164 | * We want to jack up disk_bytenr a little more so the em stuff doesn't |
163 | * merge our records. | 165 | * merge our records. |
164 | */ | 166 | */ |
165 | disk_bytenr += 8192; | 167 | disk_bytenr += 2 * sectorsize; |
166 | 168 | ||
167 | /* | 169 | /* |
168 | * Now for a partially written prealloc extent, basically the same as | 170 | * Now for a partially written prealloc extent, basically the same as |
169 | * the hole punch example above. Ram_bytes never changes when you mark | 171 | * the hole punch example above. Ram_bytes never changes when you mark |
170 | * extents written btw. | 172 | * extents written btw. |
171 | */ | 173 | */ |
172 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 16384, | 174 | insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, |
173 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | 175 | 4 * sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot); |
174 | slot++; | 176 | slot++; |
175 | offset += 4096; | 177 | offset += sectorsize; |
176 | insert_extent(root, offset, 4096, 16384, 4096, disk_bytenr, 16384, | 178 | insert_extent(root, offset, sectorsize, 4 * sectorsize, sectorsize, |
177 | BTRFS_FILE_EXTENT_REG, 0, slot); | 179 | disk_bytenr, 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, |
180 | slot); | ||
178 | slot++; | 181 | slot++; |
179 | offset += 4096; | 182 | offset += sectorsize; |
180 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 16384, | 183 | insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, |
184 | 2 * sectorsize, disk_bytenr, 4 * sectorsize, | ||
181 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); | 185 | BTRFS_FILE_EXTENT_PREALLOC, 0, slot); |
182 | slot++; | 186 | slot++; |
183 | offset += 8192; | 187 | offset += 2 * sectorsize; |
184 | disk_bytenr += 16384; | 188 | disk_bytenr += 4 * sectorsize; |
185 | 189 | ||
186 | /* Now a normal compressed extent */ | 190 | /* Now a normal compressed extent */ |
187 | insert_extent(root, offset, 8192, 8192, 0, disk_bytenr, 4096, | 191 | insert_extent(root, offset, 2 * sectorsize, 2 * sectorsize, 0, |
188 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | 192 | disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, |
193 | BTRFS_COMPRESS_ZLIB, slot); | ||
189 | slot++; | 194 | slot++; |
190 | offset += 8192; | 195 | offset += 2 * sectorsize; |
191 | /* No merges */ | 196 | /* No merges */ |
192 | disk_bytenr += 8192; | 197 | disk_bytenr += 2 * sectorsize; |
193 | 198 | ||
194 | /* Now a split compressed extent */ | 199 | /* Now a split compressed extent */ |
195 | insert_extent(root, offset, 4096, 16384, 0, disk_bytenr, 4096, | 200 | insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, |
196 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | 201 | sectorsize, BTRFS_FILE_EXTENT_REG, |
202 | BTRFS_COMPRESS_ZLIB, slot); | ||
197 | slot++; | 203 | slot++; |
198 | offset += 4096; | 204 | offset += sectorsize; |
199 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr + 4096, 4096, | 205 | insert_extent(root, offset, sectorsize, sectorsize, 0, |
206 | disk_bytenr + sectorsize, sectorsize, | ||
200 | BTRFS_FILE_EXTENT_REG, 0, slot); | 207 | BTRFS_FILE_EXTENT_REG, 0, slot); |
201 | slot++; | 208 | slot++; |
202 | offset += 4096; | 209 | offset += sectorsize; |
203 | insert_extent(root, offset, 8192, 16384, 8192, disk_bytenr, 4096, | 210 | insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, |
211 | 2 * sectorsize, disk_bytenr, sectorsize, | ||
204 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); | 212 | BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); |
205 | slot++; | 213 | slot++; |
206 | offset += 8192; | 214 | offset += 2 * sectorsize; |
207 | disk_bytenr += 8192; | 215 | disk_bytenr += 2 * sectorsize; |
208 | 216 | ||
209 | /* Now extents that have a hole but no hole extent */ | 217 | /* Now extents that have a hole but no hole extent */ |
210 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | 218 | insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, |
211 | BTRFS_FILE_EXTENT_REG, 0, slot); | 219 | sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); |
212 | slot++; | 220 | slot++; |
213 | offset += 16384; | 221 | offset += 4 * sectorsize; |
214 | disk_bytenr += 4096; | 222 | disk_bytenr += sectorsize; |
215 | insert_extent(root, offset, 4096, 4096, 0, disk_bytenr, 4096, | 223 | insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, |
216 | BTRFS_FILE_EXTENT_REG, 0, slot); | 224 | sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); |
217 | } | 225 | } |
218 | 226 | ||
219 | static unsigned long prealloc_only = 0; | 227 | static unsigned long prealloc_only = 0; |
220 | static unsigned long compressed_only = 0; | 228 | static unsigned long compressed_only = 0; |
221 | static unsigned long vacancy_only = 0; | 229 | static unsigned long vacancy_only = 0; |
222 | 230 | ||
223 | static noinline int test_btrfs_get_extent(void) | 231 | static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize) |
224 | { | 232 | { |
225 | struct inode *inode = NULL; | 233 | struct inode *inode = NULL; |
226 | struct btrfs_root *root = NULL; | 234 | struct btrfs_root *root = NULL; |
@@ -240,7 +248,7 @@ static noinline int test_btrfs_get_extent(void) | |||
240 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; | 248 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; |
241 | BTRFS_I(inode)->location.offset = 0; | 249 | BTRFS_I(inode)->location.offset = 0; |
242 | 250 | ||
243 | root = btrfs_alloc_dummy_root(); | 251 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
244 | if (IS_ERR(root)) { | 252 | if (IS_ERR(root)) { |
245 | test_msg("Couldn't allocate root\n"); | 253 | test_msg("Couldn't allocate root\n"); |
246 | goto out; | 254 | goto out; |
@@ -256,7 +264,7 @@ static noinline int test_btrfs_get_extent(void) | |||
256 | goto out; | 264 | goto out; |
257 | } | 265 | } |
258 | 266 | ||
259 | root->node = alloc_dummy_extent_buffer(NULL, 4096); | 267 | root->node = alloc_dummy_extent_buffer(NULL, nodesize, nodesize); |
260 | if (!root->node) { | 268 | if (!root->node) { |
261 | test_msg("Couldn't allocate dummy buffer\n"); | 269 | test_msg("Couldn't allocate dummy buffer\n"); |
262 | goto out; | 270 | goto out; |
@@ -273,7 +281,7 @@ static noinline int test_btrfs_get_extent(void) | |||
273 | 281 | ||
274 | /* First with no extents */ | 282 | /* First with no extents */ |
275 | BTRFS_I(inode)->root = root; | 283 | BTRFS_I(inode)->root = root; |
276 | em = btrfs_get_extent(inode, NULL, 0, 0, 4096, 0); | 284 | em = btrfs_get_extent(inode, NULL, 0, 0, sectorsize, 0); |
277 | if (IS_ERR(em)) { | 285 | if (IS_ERR(em)) { |
278 | em = NULL; | 286 | em = NULL; |
279 | test_msg("Got an error when we shouldn't have\n"); | 287 | test_msg("Got an error when we shouldn't have\n"); |
@@ -295,7 +303,7 @@ static noinline int test_btrfs_get_extent(void) | |||
295 | * setup_file_extents, so if you change anything there you need to | 303 | * setup_file_extents, so if you change anything there you need to |
296 | * update the comment and update the expected values below. | 304 | * update the comment and update the expected values below. |
297 | */ | 305 | */ |
298 | setup_file_extents(root); | 306 | setup_file_extents(root, sectorsize); |
299 | 307 | ||
300 | em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0); | 308 | em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0); |
301 | if (IS_ERR(em)) { | 309 | if (IS_ERR(em)) { |
@@ -318,7 +326,7 @@ static noinline int test_btrfs_get_extent(void) | |||
318 | offset = em->start + em->len; | 326 | offset = em->start + em->len; |
319 | free_extent_map(em); | 327 | free_extent_map(em); |
320 | 328 | ||
321 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 329 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
322 | if (IS_ERR(em)) { | 330 | if (IS_ERR(em)) { |
323 | test_msg("Got an error when we shouldn't have\n"); | 331 | test_msg("Got an error when we shouldn't have\n"); |
324 | goto out; | 332 | goto out; |
@@ -327,7 +335,8 @@ static noinline int test_btrfs_get_extent(void) | |||
327 | test_msg("Expected an inline, got %llu\n", em->block_start); | 335 | test_msg("Expected an inline, got %llu\n", em->block_start); |
328 | goto out; | 336 | goto out; |
329 | } | 337 | } |
330 | if (em->start != offset || em->len != 4091) { | 338 | |
339 | if (em->start != offset || em->len != (sectorsize - 5)) { | ||
331 | test_msg("Unexpected extent wanted start %llu len 1, got start " | 340 | test_msg("Unexpected extent wanted start %llu len 1, got start " |
332 | "%llu len %llu\n", offset, em->start, em->len); | 341 | "%llu len %llu\n", offset, em->start, em->len); |
333 | goto out; | 342 | goto out; |
@@ -344,7 +353,7 @@ static noinline int test_btrfs_get_extent(void) | |||
344 | offset = em->start + em->len; | 353 | offset = em->start + em->len; |
345 | free_extent_map(em); | 354 | free_extent_map(em); |
346 | 355 | ||
347 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 356 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
348 | if (IS_ERR(em)) { | 357 | if (IS_ERR(em)) { |
349 | test_msg("Got an error when we shouldn't have\n"); | 358 | test_msg("Got an error when we shouldn't have\n"); |
350 | goto out; | 359 | goto out; |
@@ -366,7 +375,7 @@ static noinline int test_btrfs_get_extent(void) | |||
366 | free_extent_map(em); | 375 | free_extent_map(em); |
367 | 376 | ||
368 | /* Regular extent */ | 377 | /* Regular extent */ |
369 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 378 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
370 | if (IS_ERR(em)) { | 379 | if (IS_ERR(em)) { |
371 | test_msg("Got an error when we shouldn't have\n"); | 380 | test_msg("Got an error when we shouldn't have\n"); |
372 | goto out; | 381 | goto out; |
@@ -375,7 +384,7 @@ static noinline int test_btrfs_get_extent(void) | |||
375 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 384 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
376 | goto out; | 385 | goto out; |
377 | } | 386 | } |
378 | if (em->start != offset || em->len != 4095) { | 387 | if (em->start != offset || em->len != sectorsize - 1) { |
379 | test_msg("Unexpected extent wanted start %llu len 4095, got " | 388 | test_msg("Unexpected extent wanted start %llu len 4095, got " |
380 | "start %llu len %llu\n", offset, em->start, em->len); | 389 | "start %llu len %llu\n", offset, em->start, em->len); |
381 | goto out; | 390 | goto out; |
@@ -393,7 +402,7 @@ static noinline int test_btrfs_get_extent(void) | |||
393 | free_extent_map(em); | 402 | free_extent_map(em); |
394 | 403 | ||
395 | /* The next 3 are split extents */ | 404 | /* The next 3 are split extents */ |
396 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 405 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
397 | if (IS_ERR(em)) { | 406 | if (IS_ERR(em)) { |
398 | test_msg("Got an error when we shouldn't have\n"); | 407 | test_msg("Got an error when we shouldn't have\n"); |
399 | goto out; | 408 | goto out; |
@@ -402,9 +411,10 @@ static noinline int test_btrfs_get_extent(void) | |||
402 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 411 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
403 | goto out; | 412 | goto out; |
404 | } | 413 | } |
405 | if (em->start != offset || em->len != 4096) { | 414 | if (em->start != offset || em->len != sectorsize) { |
406 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 415 | test_msg("Unexpected extent start %llu len %u, " |
407 | "start %llu len %llu\n", offset, em->start, em->len); | 416 | "got start %llu len %llu\n", |
417 | offset, sectorsize, em->start, em->len); | ||
408 | goto out; | 418 | goto out; |
409 | } | 419 | } |
410 | if (em->flags != 0) { | 420 | if (em->flags != 0) { |
@@ -421,7 +431,7 @@ static noinline int test_btrfs_get_extent(void) | |||
421 | offset = em->start + em->len; | 431 | offset = em->start + em->len; |
422 | free_extent_map(em); | 432 | free_extent_map(em); |
423 | 433 | ||
424 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 434 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
425 | if (IS_ERR(em)) { | 435 | if (IS_ERR(em)) { |
426 | test_msg("Got an error when we shouldn't have\n"); | 436 | test_msg("Got an error when we shouldn't have\n"); |
427 | goto out; | 437 | goto out; |
@@ -430,9 +440,10 @@ static noinline int test_btrfs_get_extent(void) | |||
430 | test_msg("Expected a hole, got %llu\n", em->block_start); | 440 | test_msg("Expected a hole, got %llu\n", em->block_start); |
431 | goto out; | 441 | goto out; |
432 | } | 442 | } |
433 | if (em->start != offset || em->len != 4096) { | 443 | if (em->start != offset || em->len != sectorsize) { |
434 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 444 | test_msg("Unexpected extent wanted start %llu len %u, " |
435 | "start %llu len %llu\n", offset, em->start, em->len); | 445 | "got start %llu len %llu\n", |
446 | offset, sectorsize, em->start, em->len); | ||
436 | goto out; | 447 | goto out; |
437 | } | 448 | } |
438 | if (em->flags != 0) { | 449 | if (em->flags != 0) { |
@@ -442,7 +453,7 @@ static noinline int test_btrfs_get_extent(void) | |||
442 | offset = em->start + em->len; | 453 | offset = em->start + em->len; |
443 | free_extent_map(em); | 454 | free_extent_map(em); |
444 | 455 | ||
445 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 456 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
446 | if (IS_ERR(em)) { | 457 | if (IS_ERR(em)) { |
447 | test_msg("Got an error when we shouldn't have\n"); | 458 | test_msg("Got an error when we shouldn't have\n"); |
448 | goto out; | 459 | goto out; |
@@ -451,9 +462,10 @@ static noinline int test_btrfs_get_extent(void) | |||
451 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 462 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
452 | goto out; | 463 | goto out; |
453 | } | 464 | } |
454 | if (em->start != offset || em->len != 8192) { | 465 | if (em->start != offset || em->len != 2 * sectorsize) { |
455 | test_msg("Unexpected extent wanted start %llu len 8192, got " | 466 | test_msg("Unexpected extent wanted start %llu len %u, " |
456 | "start %llu len %llu\n", offset, em->start, em->len); | 467 | "got start %llu len %llu\n", |
468 | offset, 2 * sectorsize, em->start, em->len); | ||
457 | goto out; | 469 | goto out; |
458 | } | 470 | } |
459 | if (em->flags != 0) { | 471 | if (em->flags != 0) { |
@@ -475,7 +487,7 @@ static noinline int test_btrfs_get_extent(void) | |||
475 | free_extent_map(em); | 487 | free_extent_map(em); |
476 | 488 | ||
477 | /* Prealloc extent */ | 489 | /* Prealloc extent */ |
478 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 490 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
479 | if (IS_ERR(em)) { | 491 | if (IS_ERR(em)) { |
480 | test_msg("Got an error when we shouldn't have\n"); | 492 | test_msg("Got an error when we shouldn't have\n"); |
481 | goto out; | 493 | goto out; |
@@ -484,9 +496,10 @@ static noinline int test_btrfs_get_extent(void) | |||
484 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 496 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
485 | goto out; | 497 | goto out; |
486 | } | 498 | } |
487 | if (em->start != offset || em->len != 4096) { | 499 | if (em->start != offset || em->len != sectorsize) { |
488 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 500 | test_msg("Unexpected extent wanted start %llu len %u, " |
489 | "start %llu len %llu\n", offset, em->start, em->len); | 501 | "got start %llu len %llu\n", |
502 | offset, sectorsize, em->start, em->len); | ||
490 | goto out; | 503 | goto out; |
491 | } | 504 | } |
492 | if (em->flags != prealloc_only) { | 505 | if (em->flags != prealloc_only) { |
@@ -503,7 +516,7 @@ static noinline int test_btrfs_get_extent(void) | |||
503 | free_extent_map(em); | 516 | free_extent_map(em); |
504 | 517 | ||
505 | /* The next 3 are a half written prealloc extent */ | 518 | /* The next 3 are a half written prealloc extent */ |
506 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 519 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
507 | if (IS_ERR(em)) { | 520 | if (IS_ERR(em)) { |
508 | test_msg("Got an error when we shouldn't have\n"); | 521 | test_msg("Got an error when we shouldn't have\n"); |
509 | goto out; | 522 | goto out; |
@@ -512,9 +525,10 @@ static noinline int test_btrfs_get_extent(void) | |||
512 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 525 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
513 | goto out; | 526 | goto out; |
514 | } | 527 | } |
515 | if (em->start != offset || em->len != 4096) { | 528 | if (em->start != offset || em->len != sectorsize) { |
516 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 529 | test_msg("Unexpected extent wanted start %llu len %u, " |
517 | "start %llu len %llu\n", offset, em->start, em->len); | 530 | "got start %llu len %llu\n", |
531 | offset, sectorsize, em->start, em->len); | ||
518 | goto out; | 532 | goto out; |
519 | } | 533 | } |
520 | if (em->flags != prealloc_only) { | 534 | if (em->flags != prealloc_only) { |
@@ -532,7 +546,7 @@ static noinline int test_btrfs_get_extent(void) | |||
532 | offset = em->start + em->len; | 546 | offset = em->start + em->len; |
533 | free_extent_map(em); | 547 | free_extent_map(em); |
534 | 548 | ||
535 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 549 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
536 | if (IS_ERR(em)) { | 550 | if (IS_ERR(em)) { |
537 | test_msg("Got an error when we shouldn't have\n"); | 551 | test_msg("Got an error when we shouldn't have\n"); |
538 | goto out; | 552 | goto out; |
@@ -541,9 +555,10 @@ static noinline int test_btrfs_get_extent(void) | |||
541 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 555 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
542 | goto out; | 556 | goto out; |
543 | } | 557 | } |
544 | if (em->start != offset || em->len != 4096) { | 558 | if (em->start != offset || em->len != sectorsize) { |
545 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 559 | test_msg("Unexpected extent wanted start %llu len %u, " |
546 | "start %llu len %llu\n", offset, em->start, em->len); | 560 | "got start %llu len %llu\n", |
561 | offset, sectorsize, em->start, em->len); | ||
547 | goto out; | 562 | goto out; |
548 | } | 563 | } |
549 | if (em->flags != 0) { | 564 | if (em->flags != 0) { |
@@ -564,7 +579,7 @@ static noinline int test_btrfs_get_extent(void) | |||
564 | offset = em->start + em->len; | 579 | offset = em->start + em->len; |
565 | free_extent_map(em); | 580 | free_extent_map(em); |
566 | 581 | ||
567 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 582 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
568 | if (IS_ERR(em)) { | 583 | if (IS_ERR(em)) { |
569 | test_msg("Got an error when we shouldn't have\n"); | 584 | test_msg("Got an error when we shouldn't have\n"); |
570 | goto out; | 585 | goto out; |
@@ -573,9 +588,10 @@ static noinline int test_btrfs_get_extent(void) | |||
573 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 588 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
574 | goto out; | 589 | goto out; |
575 | } | 590 | } |
576 | if (em->start != offset || em->len != 8192) { | 591 | if (em->start != offset || em->len != 2 * sectorsize) { |
577 | test_msg("Unexpected extent wanted start %llu len 8192, got " | 592 | test_msg("Unexpected extent wanted start %llu len %u, " |
578 | "start %llu len %llu\n", offset, em->start, em->len); | 593 | "got start %llu len %llu\n", |
594 | offset, 2 * sectorsize, em->start, em->len); | ||
579 | goto out; | 595 | goto out; |
580 | } | 596 | } |
581 | if (em->flags != prealloc_only) { | 597 | if (em->flags != prealloc_only) { |
@@ -598,7 +614,7 @@ static noinline int test_btrfs_get_extent(void) | |||
598 | free_extent_map(em); | 614 | free_extent_map(em); |
599 | 615 | ||
600 | /* Now for the compressed extent */ | 616 | /* Now for the compressed extent */ |
601 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 617 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
602 | if (IS_ERR(em)) { | 618 | if (IS_ERR(em)) { |
603 | test_msg("Got an error when we shouldn't have\n"); | 619 | test_msg("Got an error when we shouldn't have\n"); |
604 | goto out; | 620 | goto out; |
@@ -607,9 +623,10 @@ static noinline int test_btrfs_get_extent(void) | |||
607 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 623 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
608 | goto out; | 624 | goto out; |
609 | } | 625 | } |
610 | if (em->start != offset || em->len != 8192) { | 626 | if (em->start != offset || em->len != 2 * sectorsize) { |
611 | test_msg("Unexpected extent wanted start %llu len 8192, got " | 627 | test_msg("Unexpected extent wanted start %llu len %u," |
612 | "start %llu len %llu\n", offset, em->start, em->len); | 628 | "got start %llu len %llu\n", |
629 | offset, 2 * sectorsize, em->start, em->len); | ||
613 | goto out; | 630 | goto out; |
614 | } | 631 | } |
615 | if (em->flags != compressed_only) { | 632 | if (em->flags != compressed_only) { |
@@ -631,7 +648,7 @@ static noinline int test_btrfs_get_extent(void) | |||
631 | free_extent_map(em); | 648 | free_extent_map(em); |
632 | 649 | ||
633 | /* Split compressed extent */ | 650 | /* Split compressed extent */ |
634 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 651 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
635 | if (IS_ERR(em)) { | 652 | if (IS_ERR(em)) { |
636 | test_msg("Got an error when we shouldn't have\n"); | 653 | test_msg("Got an error when we shouldn't have\n"); |
637 | goto out; | 654 | goto out; |
@@ -640,9 +657,10 @@ static noinline int test_btrfs_get_extent(void) | |||
640 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 657 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
641 | goto out; | 658 | goto out; |
642 | } | 659 | } |
643 | if (em->start != offset || em->len != 4096) { | 660 | if (em->start != offset || em->len != sectorsize) { |
644 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 661 | test_msg("Unexpected extent wanted start %llu len %u," |
645 | "start %llu len %llu\n", offset, em->start, em->len); | 662 | "got start %llu len %llu\n", |
663 | offset, sectorsize, em->start, em->len); | ||
646 | goto out; | 664 | goto out; |
647 | } | 665 | } |
648 | if (em->flags != compressed_only) { | 666 | if (em->flags != compressed_only) { |
@@ -665,7 +683,7 @@ static noinline int test_btrfs_get_extent(void) | |||
665 | offset = em->start + em->len; | 683 | offset = em->start + em->len; |
666 | free_extent_map(em); | 684 | free_extent_map(em); |
667 | 685 | ||
668 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 686 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
669 | if (IS_ERR(em)) { | 687 | if (IS_ERR(em)) { |
670 | test_msg("Got an error when we shouldn't have\n"); | 688 | test_msg("Got an error when we shouldn't have\n"); |
671 | goto out; | 689 | goto out; |
@@ -674,9 +692,10 @@ static noinline int test_btrfs_get_extent(void) | |||
674 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 692 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
675 | goto out; | 693 | goto out; |
676 | } | 694 | } |
677 | if (em->start != offset || em->len != 4096) { | 695 | if (em->start != offset || em->len != sectorsize) { |
678 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 696 | test_msg("Unexpected extent wanted start %llu len %u, " |
679 | "start %llu len %llu\n", offset, em->start, em->len); | 697 | "got start %llu len %llu\n", |
698 | offset, sectorsize, em->start, em->len); | ||
680 | goto out; | 699 | goto out; |
681 | } | 700 | } |
682 | if (em->flags != 0) { | 701 | if (em->flags != 0) { |
@@ -691,7 +710,7 @@ static noinline int test_btrfs_get_extent(void) | |||
691 | offset = em->start + em->len; | 710 | offset = em->start + em->len; |
692 | free_extent_map(em); | 711 | free_extent_map(em); |
693 | 712 | ||
694 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 713 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
695 | if (IS_ERR(em)) { | 714 | if (IS_ERR(em)) { |
696 | test_msg("Got an error when we shouldn't have\n"); | 715 | test_msg("Got an error when we shouldn't have\n"); |
697 | goto out; | 716 | goto out; |
@@ -701,9 +720,10 @@ static noinline int test_btrfs_get_extent(void) | |||
701 | disk_bytenr, em->block_start); | 720 | disk_bytenr, em->block_start); |
702 | goto out; | 721 | goto out; |
703 | } | 722 | } |
704 | if (em->start != offset || em->len != 8192) { | 723 | if (em->start != offset || em->len != 2 * sectorsize) { |
705 | test_msg("Unexpected extent wanted start %llu len 8192, got " | 724 | test_msg("Unexpected extent wanted start %llu len %u, " |
706 | "start %llu len %llu\n", offset, em->start, em->len); | 725 | "got start %llu len %llu\n", |
726 | offset, 2 * sectorsize, em->start, em->len); | ||
707 | goto out; | 727 | goto out; |
708 | } | 728 | } |
709 | if (em->flags != compressed_only) { | 729 | if (em->flags != compressed_only) { |
@@ -725,7 +745,7 @@ static noinline int test_btrfs_get_extent(void) | |||
725 | free_extent_map(em); | 745 | free_extent_map(em); |
726 | 746 | ||
727 | /* A hole between regular extents but no hole extent */ | 747 | /* A hole between regular extents but no hole extent */ |
728 | em = btrfs_get_extent(inode, NULL, 0, offset + 6, 4096, 0); | 748 | em = btrfs_get_extent(inode, NULL, 0, offset + 6, sectorsize, 0); |
729 | if (IS_ERR(em)) { | 749 | if (IS_ERR(em)) { |
730 | test_msg("Got an error when we shouldn't have\n"); | 750 | test_msg("Got an error when we shouldn't have\n"); |
731 | goto out; | 751 | goto out; |
@@ -734,9 +754,10 @@ static noinline int test_btrfs_get_extent(void) | |||
734 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 754 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
735 | goto out; | 755 | goto out; |
736 | } | 756 | } |
737 | if (em->start != offset || em->len != 4096) { | 757 | if (em->start != offset || em->len != sectorsize) { |
738 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 758 | test_msg("Unexpected extent wanted start %llu len %u, " |
739 | "start %llu len %llu\n", offset, em->start, em->len); | 759 | "got start %llu len %llu\n", |
760 | offset, sectorsize, em->start, em->len); | ||
740 | goto out; | 761 | goto out; |
741 | } | 762 | } |
742 | if (em->flags != 0) { | 763 | if (em->flags != 0) { |
@@ -765,9 +786,10 @@ static noinline int test_btrfs_get_extent(void) | |||
765 | * length of the actual hole, if this changes we'll have to change this | 786 | * length of the actual hole, if this changes we'll have to change this |
766 | * test. | 787 | * test. |
767 | */ | 788 | */ |
768 | if (em->start != offset || em->len != 12288) { | 789 | if (em->start != offset || em->len != 3 * sectorsize) { |
769 | test_msg("Unexpected extent wanted start %llu len 12288, got " | 790 | test_msg("Unexpected extent wanted start %llu len %u, " |
770 | "start %llu len %llu\n", offset, em->start, em->len); | 791 | "got start %llu len %llu\n", |
792 | offset, 3 * sectorsize, em->start, em->len); | ||
771 | goto out; | 793 | goto out; |
772 | } | 794 | } |
773 | if (em->flags != vacancy_only) { | 795 | if (em->flags != vacancy_only) { |
@@ -783,7 +805,7 @@ static noinline int test_btrfs_get_extent(void) | |||
783 | offset = em->start + em->len; | 805 | offset = em->start + em->len; |
784 | free_extent_map(em); | 806 | free_extent_map(em); |
785 | 807 | ||
786 | em = btrfs_get_extent(inode, NULL, 0, offset, 4096, 0); | 808 | em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); |
787 | if (IS_ERR(em)) { | 809 | if (IS_ERR(em)) { |
788 | test_msg("Got an error when we shouldn't have\n"); | 810 | test_msg("Got an error when we shouldn't have\n"); |
789 | goto out; | 811 | goto out; |
@@ -792,9 +814,10 @@ static noinline int test_btrfs_get_extent(void) | |||
792 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 814 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
793 | goto out; | 815 | goto out; |
794 | } | 816 | } |
795 | if (em->start != offset || em->len != 4096) { | 817 | if (em->start != offset || em->len != sectorsize) { |
796 | test_msg("Unexpected extent wanted start %llu len 4096, got " | 818 | test_msg("Unexpected extent wanted start %llu len %u," |
797 | "start %llu len %llu\n", offset, em->start, em->len); | 819 | "got start %llu len %llu\n", |
820 | offset, sectorsize, em->start, em->len); | ||
798 | goto out; | 821 | goto out; |
799 | } | 822 | } |
800 | if (em->flags != 0) { | 823 | if (em->flags != 0) { |
@@ -815,7 +838,7 @@ out: | |||
815 | return ret; | 838 | return ret; |
816 | } | 839 | } |
817 | 840 | ||
818 | static int test_hole_first(void) | 841 | static int test_hole_first(u32 sectorsize, u32 nodesize) |
819 | { | 842 | { |
820 | struct inode *inode = NULL; | 843 | struct inode *inode = NULL; |
821 | struct btrfs_root *root = NULL; | 844 | struct btrfs_root *root = NULL; |
@@ -832,7 +855,7 @@ static int test_hole_first(void) | |||
832 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; | 855 | BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; |
833 | BTRFS_I(inode)->location.offset = 0; | 856 | BTRFS_I(inode)->location.offset = 0; |
834 | 857 | ||
835 | root = btrfs_alloc_dummy_root(); | 858 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
836 | if (IS_ERR(root)) { | 859 | if (IS_ERR(root)) { |
837 | test_msg("Couldn't allocate root\n"); | 860 | test_msg("Couldn't allocate root\n"); |
838 | goto out; | 861 | goto out; |
@@ -844,7 +867,7 @@ static int test_hole_first(void) | |||
844 | goto out; | 867 | goto out; |
845 | } | 868 | } |
846 | 869 | ||
847 | root->node = alloc_dummy_extent_buffer(NULL, 4096); | 870 | root->node = alloc_dummy_extent_buffer(NULL, nodesize, nodesize); |
848 | if (!root->node) { | 871 | if (!root->node) { |
849 | test_msg("Couldn't allocate dummy buffer\n"); | 872 | test_msg("Couldn't allocate dummy buffer\n"); |
850 | goto out; | 873 | goto out; |
@@ -861,9 +884,9 @@ static int test_hole_first(void) | |||
861 | * btrfs_get_extent. | 884 | * btrfs_get_extent. |
862 | */ | 885 | */ |
863 | insert_inode_item_key(root); | 886 | insert_inode_item_key(root); |
864 | insert_extent(root, 4096, 4096, 4096, 0, 4096, 4096, | 887 | insert_extent(root, sectorsize, sectorsize, sectorsize, 0, sectorsize, |
865 | BTRFS_FILE_EXTENT_REG, 0, 1); | 888 | sectorsize, BTRFS_FILE_EXTENT_REG, 0, 1); |
866 | em = btrfs_get_extent(inode, NULL, 0, 0, 8192, 0); | 889 | em = btrfs_get_extent(inode, NULL, 0, 0, 2 * sectorsize, 0); |
867 | if (IS_ERR(em)) { | 890 | if (IS_ERR(em)) { |
868 | test_msg("Got an error when we shouldn't have\n"); | 891 | test_msg("Got an error when we shouldn't have\n"); |
869 | goto out; | 892 | goto out; |
@@ -872,9 +895,10 @@ static int test_hole_first(void) | |||
872 | test_msg("Expected a hole, got %llu\n", em->block_start); | 895 | test_msg("Expected a hole, got %llu\n", em->block_start); |
873 | goto out; | 896 | goto out; |
874 | } | 897 | } |
875 | if (em->start != 0 || em->len != 4096) { | 898 | if (em->start != 0 || em->len != sectorsize) { |
876 | test_msg("Unexpected extent wanted start 0 len 4096, got start " | 899 | test_msg("Unexpected extent wanted start 0 len %u, " |
877 | "%llu len %llu\n", em->start, em->len); | 900 | "got start %llu len %llu\n", |
901 | sectorsize, em->start, em->len); | ||
878 | goto out; | 902 | goto out; |
879 | } | 903 | } |
880 | if (em->flags != vacancy_only) { | 904 | if (em->flags != vacancy_only) { |
@@ -884,18 +908,19 @@ static int test_hole_first(void) | |||
884 | } | 908 | } |
885 | free_extent_map(em); | 909 | free_extent_map(em); |
886 | 910 | ||
887 | em = btrfs_get_extent(inode, NULL, 0, 4096, 8192, 0); | 911 | em = btrfs_get_extent(inode, NULL, 0, sectorsize, 2 * sectorsize, 0); |
888 | if (IS_ERR(em)) { | 912 | if (IS_ERR(em)) { |
889 | test_msg("Got an error when we shouldn't have\n"); | 913 | test_msg("Got an error when we shouldn't have\n"); |
890 | goto out; | 914 | goto out; |
891 | } | 915 | } |
892 | if (em->block_start != 4096) { | 916 | if (em->block_start != sectorsize) { |
893 | test_msg("Expected a real extent, got %llu\n", em->block_start); | 917 | test_msg("Expected a real extent, got %llu\n", em->block_start); |
894 | goto out; | 918 | goto out; |
895 | } | 919 | } |
896 | if (em->start != 4096 || em->len != 4096) { | 920 | if (em->start != sectorsize || em->len != sectorsize) { |
897 | test_msg("Unexpected extent wanted start 4096 len 4096, got " | 921 | test_msg("Unexpected extent wanted start %u len %u, " |
898 | "start %llu len %llu\n", em->start, em->len); | 922 | "got start %llu len %llu\n", |
923 | sectorsize, sectorsize, em->start, em->len); | ||
899 | goto out; | 924 | goto out; |
900 | } | 925 | } |
901 | if (em->flags != 0) { | 926 | if (em->flags != 0) { |
@@ -912,7 +937,7 @@ out: | |||
912 | return ret; | 937 | return ret; |
913 | } | 938 | } |
914 | 939 | ||
915 | static int test_extent_accounting(void) | 940 | static int test_extent_accounting(u32 sectorsize, u32 nodesize) |
916 | { | 941 | { |
917 | struct inode *inode = NULL; | 942 | struct inode *inode = NULL; |
918 | struct btrfs_root *root = NULL; | 943 | struct btrfs_root *root = NULL; |
@@ -924,7 +949,7 @@ static int test_extent_accounting(void) | |||
924 | return ret; | 949 | return ret; |
925 | } | 950 | } |
926 | 951 | ||
927 | root = btrfs_alloc_dummy_root(); | 952 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
928 | if (IS_ERR(root)) { | 953 | if (IS_ERR(root)) { |
929 | test_msg("Couldn't allocate root\n"); | 954 | test_msg("Couldn't allocate root\n"); |
930 | goto out; | 955 | goto out; |
@@ -954,10 +979,11 @@ static int test_extent_accounting(void) | |||
954 | goto out; | 979 | goto out; |
955 | } | 980 | } |
956 | 981 | ||
957 | /* [BTRFS_MAX_EXTENT_SIZE][4k] */ | 982 | /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ |
958 | BTRFS_I(inode)->outstanding_extents++; | 983 | BTRFS_I(inode)->outstanding_extents++; |
959 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, | 984 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, |
960 | BTRFS_MAX_EXTENT_SIZE + 4095, NULL); | 985 | BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, |
986 | NULL); | ||
961 | if (ret) { | 987 | if (ret) { |
962 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 988 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
963 | goto out; | 989 | goto out; |
@@ -969,10 +995,10 @@ static int test_extent_accounting(void) | |||
969 | goto out; | 995 | goto out; |
970 | } | 996 | } |
971 | 997 | ||
972 | /* [BTRFS_MAX_EXTENT_SIZE/2][4K HOLE][the rest] */ | 998 | /* [BTRFS_MAX_EXTENT_SIZE/2][sectorsize HOLE][the rest] */ |
973 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | 999 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, |
974 | BTRFS_MAX_EXTENT_SIZE >> 1, | 1000 | BTRFS_MAX_EXTENT_SIZE >> 1, |
975 | (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095, | 1001 | (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1, |
976 | EXTENT_DELALLOC | EXTENT_DIRTY | | 1002 | EXTENT_DELALLOC | EXTENT_DIRTY | |
977 | EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING, 0, 0, | 1003 | EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING, 0, 0, |
978 | NULL, GFP_KERNEL); | 1004 | NULL, GFP_KERNEL); |
@@ -987,10 +1013,11 @@ static int test_extent_accounting(void) | |||
987 | goto out; | 1013 | goto out; |
988 | } | 1014 | } |
989 | 1015 | ||
990 | /* [BTRFS_MAX_EXTENT_SIZE][4K] */ | 1016 | /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ |
991 | BTRFS_I(inode)->outstanding_extents++; | 1017 | BTRFS_I(inode)->outstanding_extents++; |
992 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, | 1018 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, |
993 | (BTRFS_MAX_EXTENT_SIZE >> 1) + 4095, | 1019 | (BTRFS_MAX_EXTENT_SIZE >> 1) |
1020 | + sectorsize - 1, | ||
994 | NULL); | 1021 | NULL); |
995 | if (ret) { | 1022 | if (ret) { |
996 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1023 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
@@ -1004,16 +1031,17 @@ static int test_extent_accounting(void) | |||
1004 | } | 1031 | } |
1005 | 1032 | ||
1006 | /* | 1033 | /* |
1007 | * [BTRFS_MAX_EXTENT_SIZE+4K][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4K] | 1034 | * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize HOLE][BTRFS_MAX_EXTENT_SIZE+sectorsize] |
1008 | * | 1035 | * |
1009 | * I'm artificially adding 2 to outstanding_extents because in the | 1036 | * I'm artificially adding 2 to outstanding_extents because in the |
1010 | * buffered IO case we'd add things up as we go, but I don't feel like | 1037 | * buffered IO case we'd add things up as we go, but I don't feel like |
1011 | * doing that here, this isn't the interesting case we want to test. | 1038 | * doing that here, this isn't the interesting case we want to test. |
1012 | */ | 1039 | */ |
1013 | BTRFS_I(inode)->outstanding_extents += 2; | 1040 | BTRFS_I(inode)->outstanding_extents += 2; |
1014 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE + 8192, | 1041 | ret = btrfs_set_extent_delalloc(inode, |
1015 | (BTRFS_MAX_EXTENT_SIZE << 1) + 12287, | 1042 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, |
1016 | NULL); | 1043 | (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, |
1044 | NULL); | ||
1017 | if (ret) { | 1045 | if (ret) { |
1018 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1046 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1019 | goto out; | 1047 | goto out; |
@@ -1025,10 +1053,13 @@ static int test_extent_accounting(void) | |||
1025 | goto out; | 1053 | goto out; |
1026 | } | 1054 | } |
1027 | 1055 | ||
1028 | /* [BTRFS_MAX_EXTENT_SIZE+4k][4k][BTRFS_MAX_EXTENT_SIZE+4k] */ | 1056 | /* |
1057 | * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize] | ||
1058 | */ | ||
1029 | BTRFS_I(inode)->outstanding_extents++; | 1059 | BTRFS_I(inode)->outstanding_extents++; |
1030 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096, | 1060 | ret = btrfs_set_extent_delalloc(inode, |
1031 | BTRFS_MAX_EXTENT_SIZE+8191, NULL); | 1061 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
1062 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); | ||
1032 | if (ret) { | 1063 | if (ret) { |
1033 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1064 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1034 | goto out; | 1065 | goto out; |
@@ -1042,8 +1073,8 @@ static int test_extent_accounting(void) | |||
1042 | 1073 | ||
1043 | /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */ | 1074 | /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */ |
1044 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, | 1075 | ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, |
1045 | BTRFS_MAX_EXTENT_SIZE+4096, | 1076 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
1046 | BTRFS_MAX_EXTENT_SIZE+8191, | 1077 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, |
1047 | EXTENT_DIRTY | EXTENT_DELALLOC | | 1078 | EXTENT_DIRTY | EXTENT_DELALLOC | |
1048 | EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, | 1079 | EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, |
1049 | NULL, GFP_KERNEL); | 1080 | NULL, GFP_KERNEL); |
@@ -1063,8 +1094,9 @@ static int test_extent_accounting(void) | |||
1063 | * might fail and I'd rather satisfy my paranoia at this point. | 1094 | * might fail and I'd rather satisfy my paranoia at this point. |
1064 | */ | 1095 | */ |
1065 | BTRFS_I(inode)->outstanding_extents++; | 1096 | BTRFS_I(inode)->outstanding_extents++; |
1066 | ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE+4096, | 1097 | ret = btrfs_set_extent_delalloc(inode, |
1067 | BTRFS_MAX_EXTENT_SIZE+8191, NULL); | 1098 | BTRFS_MAX_EXTENT_SIZE + sectorsize, |
1099 | BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); | ||
1068 | if (ret) { | 1100 | if (ret) { |
1069 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); | 1101 | test_msg("btrfs_set_extent_delalloc returned %d\n", ret); |
1070 | goto out; | 1102 | goto out; |
@@ -1103,7 +1135,7 @@ out: | |||
1103 | return ret; | 1135 | return ret; |
1104 | } | 1136 | } |
1105 | 1137 | ||
1106 | int btrfs_test_inodes(void) | 1138 | int btrfs_test_inodes(u32 sectorsize, u32 nodesize) |
1107 | { | 1139 | { |
1108 | int ret; | 1140 | int ret; |
1109 | 1141 | ||
@@ -1112,13 +1144,13 @@ int btrfs_test_inodes(void) | |||
1112 | set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only); | 1144 | set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only); |
1113 | 1145 | ||
1114 | test_msg("Running btrfs_get_extent tests\n"); | 1146 | test_msg("Running btrfs_get_extent tests\n"); |
1115 | ret = test_btrfs_get_extent(); | 1147 | ret = test_btrfs_get_extent(sectorsize, nodesize); |
1116 | if (ret) | 1148 | if (ret) |
1117 | return ret; | 1149 | return ret; |
1118 | test_msg("Running hole first btrfs_get_extent test\n"); | 1150 | test_msg("Running hole first btrfs_get_extent test\n"); |
1119 | ret = test_hole_first(); | 1151 | ret = test_hole_first(sectorsize, nodesize); |
1120 | if (ret) | 1152 | if (ret) |
1121 | return ret; | 1153 | return ret; |
1122 | test_msg("Running outstanding_extents tests\n"); | 1154 | test_msg("Running outstanding_extents tests\n"); |
1123 | return test_extent_accounting(); | 1155 | return test_extent_accounting(sectorsize, nodesize); |
1124 | } | 1156 | } |
diff --git a/fs/btrfs/tests/qgroup-tests.c b/fs/btrfs/tests/qgroup-tests.c index 8aa4ded31326..57a12c0d680b 100644 --- a/fs/btrfs/tests/qgroup-tests.c +++ b/fs/btrfs/tests/qgroup-tests.c | |||
@@ -16,6 +16,7 @@ | |||
16 | * Boston, MA 021110-1307, USA. | 16 | * Boston, MA 021110-1307, USA. |
17 | */ | 17 | */ |
18 | 18 | ||
19 | #include <linux/types.h> | ||
19 | #include "btrfs-tests.h" | 20 | #include "btrfs-tests.h" |
20 | #include "../ctree.h" | 21 | #include "../ctree.h" |
21 | #include "../transaction.h" | 22 | #include "../transaction.h" |
@@ -216,7 +217,8 @@ static int remove_extent_ref(struct btrfs_root *root, u64 bytenr, | |||
216 | return ret; | 217 | return ret; |
217 | } | 218 | } |
218 | 219 | ||
219 | static int test_no_shared_qgroup(struct btrfs_root *root) | 220 | static int test_no_shared_qgroup(struct btrfs_root *root, |
221 | u32 sectorsize, u32 nodesize) | ||
220 | { | 222 | { |
221 | struct btrfs_trans_handle trans; | 223 | struct btrfs_trans_handle trans; |
222 | struct btrfs_fs_info *fs_info = root->fs_info; | 224 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -227,7 +229,7 @@ static int test_no_shared_qgroup(struct btrfs_root *root) | |||
227 | btrfs_init_dummy_trans(&trans); | 229 | btrfs_init_dummy_trans(&trans); |
228 | 230 | ||
229 | test_msg("Qgroup basic add\n"); | 231 | test_msg("Qgroup basic add\n"); |
230 | ret = btrfs_create_qgroup(NULL, fs_info, 5); | 232 | ret = btrfs_create_qgroup(NULL, fs_info, BTRFS_FS_TREE_OBJECTID); |
231 | if (ret) { | 233 | if (ret) { |
232 | test_msg("Couldn't create a qgroup %d\n", ret); | 234 | test_msg("Couldn't create a qgroup %d\n", ret); |
233 | return ret; | 235 | return ret; |
@@ -238,18 +240,19 @@ static int test_no_shared_qgroup(struct btrfs_root *root) | |||
238 | * we can only call btrfs_qgroup_account_extent() directly to test | 240 | * we can only call btrfs_qgroup_account_extent() directly to test |
239 | * quota. | 241 | * quota. |
240 | */ | 242 | */ |
241 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &old_roots); | 243 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
242 | if (ret) { | 244 | if (ret) { |
243 | ulist_free(old_roots); | 245 | ulist_free(old_roots); |
244 | test_msg("Couldn't find old roots: %d\n", ret); | 246 | test_msg("Couldn't find old roots: %d\n", ret); |
245 | return ret; | 247 | return ret; |
246 | } | 248 | } |
247 | 249 | ||
248 | ret = insert_normal_tree_ref(root, 4096, 4096, 0, 5); | 250 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, |
251 | BTRFS_FS_TREE_OBJECTID); | ||
249 | if (ret) | 252 | if (ret) |
250 | return ret; | 253 | return ret; |
251 | 254 | ||
252 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &new_roots); | 255 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
253 | if (ret) { | 256 | if (ret) { |
254 | ulist_free(old_roots); | 257 | ulist_free(old_roots); |
255 | ulist_free(new_roots); | 258 | ulist_free(new_roots); |
@@ -257,32 +260,33 @@ static int test_no_shared_qgroup(struct btrfs_root *root) | |||
257 | return ret; | 260 | return ret; |
258 | } | 261 | } |
259 | 262 | ||
260 | ret = btrfs_qgroup_account_extent(&trans, fs_info, 4096, 4096, | 263 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
261 | old_roots, new_roots); | 264 | nodesize, old_roots, new_roots); |
262 | if (ret) { | 265 | if (ret) { |
263 | test_msg("Couldn't account space for a qgroup %d\n", ret); | 266 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
264 | return ret; | 267 | return ret; |
265 | } | 268 | } |
266 | 269 | ||
267 | if (btrfs_verify_qgroup_counts(fs_info, 5, 4096, 4096)) { | 270 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
271 | nodesize, nodesize)) { | ||
268 | test_msg("Qgroup counts didn't match expected values\n"); | 272 | test_msg("Qgroup counts didn't match expected values\n"); |
269 | return -EINVAL; | 273 | return -EINVAL; |
270 | } | 274 | } |
271 | old_roots = NULL; | 275 | old_roots = NULL; |
272 | new_roots = NULL; | 276 | new_roots = NULL; |
273 | 277 | ||
274 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &old_roots); | 278 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
275 | if (ret) { | 279 | if (ret) { |
276 | ulist_free(old_roots); | 280 | ulist_free(old_roots); |
277 | test_msg("Couldn't find old roots: %d\n", ret); | 281 | test_msg("Couldn't find old roots: %d\n", ret); |
278 | return ret; | 282 | return ret; |
279 | } | 283 | } |
280 | 284 | ||
281 | ret = remove_extent_item(root, 4096, 4096); | 285 | ret = remove_extent_item(root, nodesize, nodesize); |
282 | if (ret) | 286 | if (ret) |
283 | return -EINVAL; | 287 | return -EINVAL; |
284 | 288 | ||
285 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &new_roots); | 289 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
286 | if (ret) { | 290 | if (ret) { |
287 | ulist_free(old_roots); | 291 | ulist_free(old_roots); |
288 | ulist_free(new_roots); | 292 | ulist_free(new_roots); |
@@ -290,14 +294,14 @@ static int test_no_shared_qgroup(struct btrfs_root *root) | |||
290 | return ret; | 294 | return ret; |
291 | } | 295 | } |
292 | 296 | ||
293 | ret = btrfs_qgroup_account_extent(&trans, fs_info, 4096, 4096, | 297 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
294 | old_roots, new_roots); | 298 | nodesize, old_roots, new_roots); |
295 | if (ret) { | 299 | if (ret) { |
296 | test_msg("Couldn't account space for a qgroup %d\n", ret); | 300 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
297 | return -EINVAL; | 301 | return -EINVAL; |
298 | } | 302 | } |
299 | 303 | ||
300 | if (btrfs_verify_qgroup_counts(fs_info, 5, 0, 0)) { | 304 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, 0, 0)) { |
301 | test_msg("Qgroup counts didn't match expected values\n"); | 305 | test_msg("Qgroup counts didn't match expected values\n"); |
302 | return -EINVAL; | 306 | return -EINVAL; |
303 | } | 307 | } |
@@ -310,7 +314,8 @@ static int test_no_shared_qgroup(struct btrfs_root *root) | |||
310 | * right, also remove one of the roots and make sure the exclusive count is | 314 | * right, also remove one of the roots and make sure the exclusive count is |
311 | * adjusted properly. | 315 | * adjusted properly. |
312 | */ | 316 | */ |
313 | static int test_multiple_refs(struct btrfs_root *root) | 317 | static int test_multiple_refs(struct btrfs_root *root, |
318 | u32 sectorsize, u32 nodesize) | ||
314 | { | 319 | { |
315 | struct btrfs_trans_handle trans; | 320 | struct btrfs_trans_handle trans; |
316 | struct btrfs_fs_info *fs_info = root->fs_info; | 321 | struct btrfs_fs_info *fs_info = root->fs_info; |
@@ -322,25 +327,29 @@ static int test_multiple_refs(struct btrfs_root *root) | |||
322 | 327 | ||
323 | test_msg("Qgroup multiple refs test\n"); | 328 | test_msg("Qgroup multiple refs test\n"); |
324 | 329 | ||
325 | /* We have 5 created already from the previous test */ | 330 | /* |
326 | ret = btrfs_create_qgroup(NULL, fs_info, 256); | 331 | * We have BTRFS_FS_TREE_OBJECTID created already from the |
332 | * previous test. | ||
333 | */ | ||
334 | ret = btrfs_create_qgroup(NULL, fs_info, BTRFS_FIRST_FREE_OBJECTID); | ||
327 | if (ret) { | 335 | if (ret) { |
328 | test_msg("Couldn't create a qgroup %d\n", ret); | 336 | test_msg("Couldn't create a qgroup %d\n", ret); |
329 | return ret; | 337 | return ret; |
330 | } | 338 | } |
331 | 339 | ||
332 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &old_roots); | 340 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
333 | if (ret) { | 341 | if (ret) { |
334 | ulist_free(old_roots); | 342 | ulist_free(old_roots); |
335 | test_msg("Couldn't find old roots: %d\n", ret); | 343 | test_msg("Couldn't find old roots: %d\n", ret); |
336 | return ret; | 344 | return ret; |
337 | } | 345 | } |
338 | 346 | ||
339 | ret = insert_normal_tree_ref(root, 4096, 4096, 0, 5); | 347 | ret = insert_normal_tree_ref(root, nodesize, nodesize, 0, |
348 | BTRFS_FS_TREE_OBJECTID); | ||
340 | if (ret) | 349 | if (ret) |
341 | return ret; | 350 | return ret; |
342 | 351 | ||
343 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &new_roots); | 352 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
344 | if (ret) { | 353 | if (ret) { |
345 | ulist_free(old_roots); | 354 | ulist_free(old_roots); |
346 | ulist_free(new_roots); | 355 | ulist_free(new_roots); |
@@ -348,30 +357,32 @@ static int test_multiple_refs(struct btrfs_root *root) | |||
348 | return ret; | 357 | return ret; |
349 | } | 358 | } |
350 | 359 | ||
351 | ret = btrfs_qgroup_account_extent(&trans, fs_info, 4096, 4096, | 360 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
352 | old_roots, new_roots); | 361 | nodesize, old_roots, new_roots); |
353 | if (ret) { | 362 | if (ret) { |
354 | test_msg("Couldn't account space for a qgroup %d\n", ret); | 363 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
355 | return ret; | 364 | return ret; |
356 | } | 365 | } |
357 | 366 | ||
358 | if (btrfs_verify_qgroup_counts(fs_info, 5, 4096, 4096)) { | 367 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
368 | nodesize, nodesize)) { | ||
359 | test_msg("Qgroup counts didn't match expected values\n"); | 369 | test_msg("Qgroup counts didn't match expected values\n"); |
360 | return -EINVAL; | 370 | return -EINVAL; |
361 | } | 371 | } |
362 | 372 | ||
363 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &old_roots); | 373 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
364 | if (ret) { | 374 | if (ret) { |
365 | ulist_free(old_roots); | 375 | ulist_free(old_roots); |
366 | test_msg("Couldn't find old roots: %d\n", ret); | 376 | test_msg("Couldn't find old roots: %d\n", ret); |
367 | return ret; | 377 | return ret; |
368 | } | 378 | } |
369 | 379 | ||
370 | ret = add_tree_ref(root, 4096, 4096, 0, 256); | 380 | ret = add_tree_ref(root, nodesize, nodesize, 0, |
381 | BTRFS_FIRST_FREE_OBJECTID); | ||
371 | if (ret) | 382 | if (ret) |
372 | return ret; | 383 | return ret; |
373 | 384 | ||
374 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &new_roots); | 385 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
375 | if (ret) { | 386 | if (ret) { |
376 | ulist_free(old_roots); | 387 | ulist_free(old_roots); |
377 | ulist_free(new_roots); | 388 | ulist_free(new_roots); |
@@ -379,35 +390,38 @@ static int test_multiple_refs(struct btrfs_root *root) | |||
379 | return ret; | 390 | return ret; |
380 | } | 391 | } |
381 | 392 | ||
382 | ret = btrfs_qgroup_account_extent(&trans, fs_info, 4096, 4096, | 393 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
383 | old_roots, new_roots); | 394 | nodesize, old_roots, new_roots); |
384 | if (ret) { | 395 | if (ret) { |
385 | test_msg("Couldn't account space for a qgroup %d\n", ret); | 396 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
386 | return ret; | 397 | return ret; |
387 | } | 398 | } |
388 | 399 | ||
389 | if (btrfs_verify_qgroup_counts(fs_info, 5, 4096, 0)) { | 400 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
401 | nodesize, 0)) { | ||
390 | test_msg("Qgroup counts didn't match expected values\n"); | 402 | test_msg("Qgroup counts didn't match expected values\n"); |
391 | return -EINVAL; | 403 | return -EINVAL; |
392 | } | 404 | } |
393 | 405 | ||
394 | if (btrfs_verify_qgroup_counts(fs_info, 256, 4096, 0)) { | 406 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID, |
407 | nodesize, 0)) { | ||
395 | test_msg("Qgroup counts didn't match expected values\n"); | 408 | test_msg("Qgroup counts didn't match expected values\n"); |
396 | return -EINVAL; | 409 | return -EINVAL; |
397 | } | 410 | } |
398 | 411 | ||
399 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &old_roots); | 412 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &old_roots); |
400 | if (ret) { | 413 | if (ret) { |
401 | ulist_free(old_roots); | 414 | ulist_free(old_roots); |
402 | test_msg("Couldn't find old roots: %d\n", ret); | 415 | test_msg("Couldn't find old roots: %d\n", ret); |
403 | return ret; | 416 | return ret; |
404 | } | 417 | } |
405 | 418 | ||
406 | ret = remove_extent_ref(root, 4096, 4096, 0, 256); | 419 | ret = remove_extent_ref(root, nodesize, nodesize, 0, |
420 | BTRFS_FIRST_FREE_OBJECTID); | ||
407 | if (ret) | 421 | if (ret) |
408 | return ret; | 422 | return ret; |
409 | 423 | ||
410 | ret = btrfs_find_all_roots(&trans, fs_info, 4096, 0, &new_roots); | 424 | ret = btrfs_find_all_roots(&trans, fs_info, nodesize, 0, &new_roots); |
411 | if (ret) { | 425 | if (ret) { |
412 | ulist_free(old_roots); | 426 | ulist_free(old_roots); |
413 | ulist_free(new_roots); | 427 | ulist_free(new_roots); |
@@ -415,19 +429,21 @@ static int test_multiple_refs(struct btrfs_root *root) | |||
415 | return ret; | 429 | return ret; |
416 | } | 430 | } |
417 | 431 | ||
418 | ret = btrfs_qgroup_account_extent(&trans, fs_info, 4096, 4096, | 432 | ret = btrfs_qgroup_account_extent(&trans, fs_info, nodesize, |
419 | old_roots, new_roots); | 433 | nodesize, old_roots, new_roots); |
420 | if (ret) { | 434 | if (ret) { |
421 | test_msg("Couldn't account space for a qgroup %d\n", ret); | 435 | test_msg("Couldn't account space for a qgroup %d\n", ret); |
422 | return ret; | 436 | return ret; |
423 | } | 437 | } |
424 | 438 | ||
425 | if (btrfs_verify_qgroup_counts(fs_info, 256, 0, 0)) { | 439 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FIRST_FREE_OBJECTID, |
440 | 0, 0)) { | ||
426 | test_msg("Qgroup counts didn't match expected values\n"); | 441 | test_msg("Qgroup counts didn't match expected values\n"); |
427 | return -EINVAL; | 442 | return -EINVAL; |
428 | } | 443 | } |
429 | 444 | ||
430 | if (btrfs_verify_qgroup_counts(fs_info, 5, 4096, 4096)) { | 445 | if (btrfs_verify_qgroup_counts(fs_info, BTRFS_FS_TREE_OBJECTID, |
446 | nodesize, nodesize)) { | ||
431 | test_msg("Qgroup counts didn't match expected values\n"); | 447 | test_msg("Qgroup counts didn't match expected values\n"); |
432 | return -EINVAL; | 448 | return -EINVAL; |
433 | } | 449 | } |
@@ -435,13 +451,13 @@ static int test_multiple_refs(struct btrfs_root *root) | |||
435 | return 0; | 451 | return 0; |
436 | } | 452 | } |
437 | 453 | ||
438 | int btrfs_test_qgroups(void) | 454 | int btrfs_test_qgroups(u32 sectorsize, u32 nodesize) |
439 | { | 455 | { |
440 | struct btrfs_root *root; | 456 | struct btrfs_root *root; |
441 | struct btrfs_root *tmp_root; | 457 | struct btrfs_root *tmp_root; |
442 | int ret = 0; | 458 | int ret = 0; |
443 | 459 | ||
444 | root = btrfs_alloc_dummy_root(); | 460 | root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
445 | if (IS_ERR(root)) { | 461 | if (IS_ERR(root)) { |
446 | test_msg("Couldn't allocate root\n"); | 462 | test_msg("Couldn't allocate root\n"); |
447 | return PTR_ERR(root); | 463 | return PTR_ERR(root); |
@@ -468,7 +484,8 @@ int btrfs_test_qgroups(void) | |||
468 | * Can't use bytenr 0, some things freak out | 484 | * Can't use bytenr 0, some things freak out |
469 | * *cough*backref walking code*cough* | 485 | * *cough*backref walking code*cough* |
470 | */ | 486 | */ |
471 | root->node = alloc_test_extent_buffer(root->fs_info, 4096); | 487 | root->node = alloc_test_extent_buffer(root->fs_info, nodesize, |
488 | nodesize); | ||
472 | if (!root->node) { | 489 | if (!root->node) { |
473 | test_msg("Couldn't allocate dummy buffer\n"); | 490 | test_msg("Couldn't allocate dummy buffer\n"); |
474 | ret = -ENOMEM; | 491 | ret = -ENOMEM; |
@@ -476,16 +493,16 @@ int btrfs_test_qgroups(void) | |||
476 | } | 493 | } |
477 | btrfs_set_header_level(root->node, 0); | 494 | btrfs_set_header_level(root->node, 0); |
478 | btrfs_set_header_nritems(root->node, 0); | 495 | btrfs_set_header_nritems(root->node, 0); |
479 | root->alloc_bytenr += 8192; | 496 | root->alloc_bytenr += 2 * nodesize; |
480 | 497 | ||
481 | tmp_root = btrfs_alloc_dummy_root(); | 498 | tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
482 | if (IS_ERR(tmp_root)) { | 499 | if (IS_ERR(tmp_root)) { |
483 | test_msg("Couldn't allocate a fs root\n"); | 500 | test_msg("Couldn't allocate a fs root\n"); |
484 | ret = PTR_ERR(tmp_root); | 501 | ret = PTR_ERR(tmp_root); |
485 | goto out; | 502 | goto out; |
486 | } | 503 | } |
487 | 504 | ||
488 | tmp_root->root_key.objectid = 5; | 505 | tmp_root->root_key.objectid = BTRFS_FS_TREE_OBJECTID; |
489 | root->fs_info->fs_root = tmp_root; | 506 | root->fs_info->fs_root = tmp_root; |
490 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); | 507 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); |
491 | if (ret) { | 508 | if (ret) { |
@@ -493,14 +510,14 @@ int btrfs_test_qgroups(void) | |||
493 | goto out; | 510 | goto out; |
494 | } | 511 | } |
495 | 512 | ||
496 | tmp_root = btrfs_alloc_dummy_root(); | 513 | tmp_root = btrfs_alloc_dummy_root(sectorsize, nodesize); |
497 | if (IS_ERR(tmp_root)) { | 514 | if (IS_ERR(tmp_root)) { |
498 | test_msg("Couldn't allocate a fs root\n"); | 515 | test_msg("Couldn't allocate a fs root\n"); |
499 | ret = PTR_ERR(tmp_root); | 516 | ret = PTR_ERR(tmp_root); |
500 | goto out; | 517 | goto out; |
501 | } | 518 | } |
502 | 519 | ||
503 | tmp_root->root_key.objectid = 256; | 520 | tmp_root->root_key.objectid = BTRFS_FIRST_FREE_OBJECTID; |
504 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); | 521 | ret = btrfs_insert_fs_root(root->fs_info, tmp_root); |
505 | if (ret) { | 522 | if (ret) { |
506 | test_msg("Couldn't insert fs root %d\n", ret); | 523 | test_msg("Couldn't insert fs root %d\n", ret); |
@@ -508,10 +525,10 @@ int btrfs_test_qgroups(void) | |||
508 | } | 525 | } |
509 | 526 | ||
510 | test_msg("Running qgroup tests\n"); | 527 | test_msg("Running qgroup tests\n"); |
511 | ret = test_no_shared_qgroup(root); | 528 | ret = test_no_shared_qgroup(root, sectorsize, nodesize); |
512 | if (ret) | 529 | if (ret) |
513 | goto out; | 530 | goto out; |
514 | ret = test_multiple_refs(root); | 531 | ret = test_multiple_refs(root, sectorsize, nodesize); |
515 | out: | 532 | out: |
516 | btrfs_free_dummy_root(root); | 533 | btrfs_free_dummy_root(root); |
517 | return ret; | 534 | return ret; |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index f6e24cb423ae..765845742fde 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -1311,11 +1311,6 @@ int btrfs_defrag_root(struct btrfs_root *root) | |||
1311 | return ret; | 1311 | return ret; |
1312 | } | 1312 | } |
1313 | 1313 | ||
1314 | /* Bisesctability fixup, remove in 4.8 */ | ||
1315 | #ifndef btrfs_std_error | ||
1316 | #define btrfs_std_error btrfs_handle_fs_error | ||
1317 | #endif | ||
1318 | |||
1319 | /* | 1314 | /* |
1320 | * Do all special snapshot related qgroup dirty hack. | 1315 | * Do all special snapshot related qgroup dirty hack. |
1321 | * | 1316 | * |
@@ -1385,7 +1380,7 @@ static int qgroup_account_snapshot(struct btrfs_trans_handle *trans, | |||
1385 | switch_commit_roots(trans->transaction, fs_info); | 1380 | switch_commit_roots(trans->transaction, fs_info); |
1386 | ret = btrfs_write_and_wait_transaction(trans, src); | 1381 | ret = btrfs_write_and_wait_transaction(trans, src); |
1387 | if (ret) | 1382 | if (ret) |
1388 | btrfs_std_error(fs_info, ret, | 1383 | btrfs_handle_fs_error(fs_info, ret, |
1389 | "Error while writing out transaction for qgroup"); | 1384 | "Error while writing out transaction for qgroup"); |
1390 | 1385 | ||
1391 | out: | 1386 | out: |
diff --git a/fs/btrfs/transaction.h b/fs/btrfs/transaction.h index 9fe0ec2bf0fe..c5abee4f01ad 100644 --- a/fs/btrfs/transaction.h +++ b/fs/btrfs/transaction.h | |||
@@ -110,7 +110,6 @@ struct btrfs_trans_handle { | |||
110 | u64 chunk_bytes_reserved; | 110 | u64 chunk_bytes_reserved; |
111 | unsigned long use_count; | 111 | unsigned long use_count; |
112 | unsigned long blocks_reserved; | 112 | unsigned long blocks_reserved; |
113 | unsigned long blocks_used; | ||
114 | unsigned long delayed_ref_updates; | 113 | unsigned long delayed_ref_updates; |
115 | struct btrfs_transaction *transaction; | 114 | struct btrfs_transaction *transaction; |
116 | struct btrfs_block_rsv *block_rsv; | 115 | struct btrfs_block_rsv *block_rsv; |
@@ -121,6 +120,7 @@ struct btrfs_trans_handle { | |||
121 | bool can_flush_pending_bgs; | 120 | bool can_flush_pending_bgs; |
122 | bool reloc_reserved; | 121 | bool reloc_reserved; |
123 | bool sync; | 122 | bool sync; |
123 | bool dirty; | ||
124 | unsigned int type; | 124 | unsigned int type; |
125 | /* | 125 | /* |
126 | * this root is only needed to validate that the root passed to | 126 | * this root is only needed to validate that the root passed to |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index b7665af471d8..c05f69a8ec42 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -2422,8 +2422,8 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, | |||
2422 | root_owner = btrfs_header_owner(parent); | 2422 | root_owner = btrfs_header_owner(parent); |
2423 | 2423 | ||
2424 | next = btrfs_find_create_tree_block(root, bytenr); | 2424 | next = btrfs_find_create_tree_block(root, bytenr); |
2425 | if (!next) | 2425 | if (IS_ERR(next)) |
2426 | return -ENOMEM; | 2426 | return PTR_ERR(next); |
2427 | 2427 | ||
2428 | if (*level == 1) { | 2428 | if (*level == 1) { |
2429 | ret = wc->process_func(root, next, wc, ptr_gen); | 2429 | ret = wc->process_func(root, next, wc, ptr_gen); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index da9e0036a864..2f631b58ae00 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -4241,6 +4241,7 @@ int btrfs_create_uuid_tree(struct btrfs_fs_info *fs_info) | |||
4241 | if (IS_ERR(uuid_root)) { | 4241 | if (IS_ERR(uuid_root)) { |
4242 | ret = PTR_ERR(uuid_root); | 4242 | ret = PTR_ERR(uuid_root); |
4243 | btrfs_abort_transaction(trans, tree_root, ret); | 4243 | btrfs_abort_transaction(trans, tree_root, ret); |
4244 | btrfs_end_transaction(trans, tree_root); | ||
4244 | return ret; | 4245 | return ret; |
4245 | } | 4246 | } |
4246 | 4247 | ||
@@ -6258,27 +6259,23 @@ struct btrfs_device *btrfs_alloc_device(struct btrfs_fs_info *fs_info, | |||
6258 | return dev; | 6259 | return dev; |
6259 | } | 6260 | } |
6260 | 6261 | ||
6261 | static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | 6262 | /* Return -EIO if any error, otherwise return 0. */ |
6262 | struct extent_buffer *leaf, | 6263 | static int btrfs_check_chunk_valid(struct btrfs_root *root, |
6263 | struct btrfs_chunk *chunk) | 6264 | struct extent_buffer *leaf, |
6265 | struct btrfs_chunk *chunk, u64 logical) | ||
6264 | { | 6266 | { |
6265 | struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; | ||
6266 | struct map_lookup *map; | ||
6267 | struct extent_map *em; | ||
6268 | u64 logical; | ||
6269 | u64 length; | 6267 | u64 length; |
6270 | u64 stripe_len; | 6268 | u64 stripe_len; |
6271 | u64 devid; | 6269 | u16 num_stripes; |
6272 | u8 uuid[BTRFS_UUID_SIZE]; | 6270 | u16 sub_stripes; |
6273 | int num_stripes; | 6271 | u64 type; |
6274 | int ret; | ||
6275 | int i; | ||
6276 | 6272 | ||
6277 | logical = key->offset; | ||
6278 | length = btrfs_chunk_length(leaf, chunk); | 6273 | length = btrfs_chunk_length(leaf, chunk); |
6279 | stripe_len = btrfs_chunk_stripe_len(leaf, chunk); | 6274 | stripe_len = btrfs_chunk_stripe_len(leaf, chunk); |
6280 | num_stripes = btrfs_chunk_num_stripes(leaf, chunk); | 6275 | num_stripes = btrfs_chunk_num_stripes(leaf, chunk); |
6281 | /* Validation check */ | 6276 | sub_stripes = btrfs_chunk_sub_stripes(leaf, chunk); |
6277 | type = btrfs_chunk_type(leaf, chunk); | ||
6278 | |||
6282 | if (!num_stripes) { | 6279 | if (!num_stripes) { |
6283 | btrfs_err(root->fs_info, "invalid chunk num_stripes: %u", | 6280 | btrfs_err(root->fs_info, "invalid chunk num_stripes: %u", |
6284 | num_stripes); | 6281 | num_stripes); |
@@ -6289,6 +6286,11 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
6289 | "invalid chunk logical %llu", logical); | 6286 | "invalid chunk logical %llu", logical); |
6290 | return -EIO; | 6287 | return -EIO; |
6291 | } | 6288 | } |
6289 | if (btrfs_chunk_sector_size(leaf, chunk) != root->sectorsize) { | ||
6290 | btrfs_err(root->fs_info, "invalid chunk sectorsize %u", | ||
6291 | btrfs_chunk_sector_size(leaf, chunk)); | ||
6292 | return -EIO; | ||
6293 | } | ||
6292 | if (!length || !IS_ALIGNED(length, root->sectorsize)) { | 6294 | if (!length || !IS_ALIGNED(length, root->sectorsize)) { |
6293 | btrfs_err(root->fs_info, | 6295 | btrfs_err(root->fs_info, |
6294 | "invalid chunk length %llu", length); | 6296 | "invalid chunk length %llu", length); |
@@ -6300,13 +6302,54 @@ static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | |||
6300 | return -EIO; | 6302 | return -EIO; |
6301 | } | 6303 | } |
6302 | if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) & | 6304 | if (~(BTRFS_BLOCK_GROUP_TYPE_MASK | BTRFS_BLOCK_GROUP_PROFILE_MASK) & |
6303 | btrfs_chunk_type(leaf, chunk)) { | 6305 | type) { |
6304 | btrfs_err(root->fs_info, "unrecognized chunk type: %llu", | 6306 | btrfs_err(root->fs_info, "unrecognized chunk type: %llu", |
6305 | ~(BTRFS_BLOCK_GROUP_TYPE_MASK | | 6307 | ~(BTRFS_BLOCK_GROUP_TYPE_MASK | |
6306 | BTRFS_BLOCK_GROUP_PROFILE_MASK) & | 6308 | BTRFS_BLOCK_GROUP_PROFILE_MASK) & |
6307 | btrfs_chunk_type(leaf, chunk)); | 6309 | btrfs_chunk_type(leaf, chunk)); |
6308 | return -EIO; | 6310 | return -EIO; |
6309 | } | 6311 | } |
6312 | if ((type & BTRFS_BLOCK_GROUP_RAID10 && sub_stripes != 2) || | ||
6313 | (type & BTRFS_BLOCK_GROUP_RAID1 && num_stripes < 1) || | ||
6314 | (type & BTRFS_BLOCK_GROUP_RAID5 && num_stripes < 2) || | ||
6315 | (type & BTRFS_BLOCK_GROUP_RAID6 && num_stripes < 3) || | ||
6316 | (type & BTRFS_BLOCK_GROUP_DUP && num_stripes > 2) || | ||
6317 | ((type & BTRFS_BLOCK_GROUP_PROFILE_MASK) == 0 && | ||
6318 | num_stripes != 1)) { | ||
6319 | btrfs_err(root->fs_info, | ||
6320 | "invalid num_stripes:sub_stripes %u:%u for profile %llu", | ||
6321 | num_stripes, sub_stripes, | ||
6322 | type & BTRFS_BLOCK_GROUP_PROFILE_MASK); | ||
6323 | return -EIO; | ||
6324 | } | ||
6325 | |||
6326 | return 0; | ||
6327 | } | ||
6328 | |||
6329 | static int read_one_chunk(struct btrfs_root *root, struct btrfs_key *key, | ||
6330 | struct extent_buffer *leaf, | ||
6331 | struct btrfs_chunk *chunk) | ||
6332 | { | ||
6333 | struct btrfs_mapping_tree *map_tree = &root->fs_info->mapping_tree; | ||
6334 | struct map_lookup *map; | ||
6335 | struct extent_map *em; | ||
6336 | u64 logical; | ||
6337 | u64 length; | ||
6338 | u64 stripe_len; | ||
6339 | u64 devid; | ||
6340 | u8 uuid[BTRFS_UUID_SIZE]; | ||
6341 | int num_stripes; | ||
6342 | int ret; | ||
6343 | int i; | ||
6344 | |||
6345 | logical = key->offset; | ||
6346 | length = btrfs_chunk_length(leaf, chunk); | ||
6347 | stripe_len = btrfs_chunk_stripe_len(leaf, chunk); | ||
6348 | num_stripes = btrfs_chunk_num_stripes(leaf, chunk); | ||
6349 | |||
6350 | ret = btrfs_check_chunk_valid(root, leaf, chunk, logical); | ||
6351 | if (ret) | ||
6352 | return ret; | ||
6310 | 6353 | ||
6311 | read_lock(&map_tree->map_tree.lock); | 6354 | read_lock(&map_tree->map_tree.lock); |
6312 | em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); | 6355 | em = lookup_extent_mapping(&map_tree->map_tree, logical, 1); |
@@ -6554,6 +6597,7 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6554 | u32 array_size; | 6597 | u32 array_size; |
6555 | u32 len = 0; | 6598 | u32 len = 0; |
6556 | u32 cur_offset; | 6599 | u32 cur_offset; |
6600 | u64 type; | ||
6557 | struct btrfs_key key; | 6601 | struct btrfs_key key; |
6558 | 6602 | ||
6559 | ASSERT(BTRFS_SUPER_INFO_SIZE <= root->nodesize); | 6603 | ASSERT(BTRFS_SUPER_INFO_SIZE <= root->nodesize); |
@@ -6563,8 +6607,8 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6563 | * overallocate but we can keep it as-is, only the first page is used. | 6607 | * overallocate but we can keep it as-is, only the first page is used. |
6564 | */ | 6608 | */ |
6565 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET); | 6609 | sb = btrfs_find_create_tree_block(root, BTRFS_SUPER_INFO_OFFSET); |
6566 | if (!sb) | 6610 | if (IS_ERR(sb)) |
6567 | return -ENOMEM; | 6611 | return PTR_ERR(sb); |
6568 | set_extent_buffer_uptodate(sb); | 6612 | set_extent_buffer_uptodate(sb); |
6569 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0); | 6613 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0); |
6570 | /* | 6614 | /* |
@@ -6620,6 +6664,15 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6620 | break; | 6664 | break; |
6621 | } | 6665 | } |
6622 | 6666 | ||
6667 | type = btrfs_chunk_type(sb, chunk); | ||
6668 | if ((type & BTRFS_BLOCK_GROUP_SYSTEM) == 0) { | ||
6669 | btrfs_err(root->fs_info, | ||
6670 | "invalid chunk type %llu in sys_array at offset %u", | ||
6671 | type, cur_offset); | ||
6672 | ret = -EIO; | ||
6673 | break; | ||
6674 | } | ||
6675 | |||
6623 | len = btrfs_chunk_item_size(num_stripes); | 6676 | len = btrfs_chunk_item_size(num_stripes); |
6624 | if (cur_offset + len > array_size) | 6677 | if (cur_offset + len > array_size) |
6625 | goto out_short_read; | 6678 | goto out_short_read; |
@@ -6638,12 +6691,14 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
6638 | sb_array_offset += len; | 6691 | sb_array_offset += len; |
6639 | cur_offset += len; | 6692 | cur_offset += len; |
6640 | } | 6693 | } |
6694 | clear_extent_buffer_uptodate(sb); | ||
6641 | free_extent_buffer_stale(sb); | 6695 | free_extent_buffer_stale(sb); |
6642 | return ret; | 6696 | return ret; |
6643 | 6697 | ||
6644 | out_short_read: | 6698 | out_short_read: |
6645 | printk(KERN_ERR "BTRFS: sys_array too short to read %u bytes at offset %u\n", | 6699 | printk(KERN_ERR "BTRFS: sys_array too short to read %u bytes at offset %u\n", |
6646 | len, cur_offset); | 6700 | len, cur_offset); |
6701 | clear_extent_buffer_uptodate(sb); | ||
6647 | free_extent_buffer_stale(sb); | 6702 | free_extent_buffer_stale(sb); |
6648 | return -EIO; | 6703 | return -EIO; |
6649 | } | 6704 | } |
@@ -6656,6 +6711,7 @@ int btrfs_read_chunk_tree(struct btrfs_root *root) | |||
6656 | struct btrfs_key found_key; | 6711 | struct btrfs_key found_key; |
6657 | int ret; | 6712 | int ret; |
6658 | int slot; | 6713 | int slot; |
6714 | u64 total_dev = 0; | ||
6659 | 6715 | ||
6660 | root = root->fs_info->chunk_root; | 6716 | root = root->fs_info->chunk_root; |
6661 | 6717 | ||
@@ -6697,6 +6753,7 @@ int btrfs_read_chunk_tree(struct btrfs_root *root) | |||
6697 | ret = read_one_dev(root, leaf, dev_item); | 6753 | ret = read_one_dev(root, leaf, dev_item); |
6698 | if (ret) | 6754 | if (ret) |
6699 | goto error; | 6755 | goto error; |
6756 | total_dev++; | ||
6700 | } else if (found_key.type == BTRFS_CHUNK_ITEM_KEY) { | 6757 | } else if (found_key.type == BTRFS_CHUNK_ITEM_KEY) { |
6701 | struct btrfs_chunk *chunk; | 6758 | struct btrfs_chunk *chunk; |
6702 | chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk); | 6759 | chunk = btrfs_item_ptr(leaf, slot, struct btrfs_chunk); |
@@ -6706,6 +6763,28 @@ int btrfs_read_chunk_tree(struct btrfs_root *root) | |||
6706 | } | 6763 | } |
6707 | path->slots[0]++; | 6764 | path->slots[0]++; |
6708 | } | 6765 | } |
6766 | |||
6767 | /* | ||
6768 | * After loading chunk tree, we've got all device information, | ||
6769 | * do another round of validation checks. | ||
6770 | */ | ||
6771 | if (total_dev != root->fs_info->fs_devices->total_devices) { | ||
6772 | btrfs_err(root->fs_info, | ||
6773 | "super_num_devices %llu mismatch with num_devices %llu found here", | ||
6774 | btrfs_super_num_devices(root->fs_info->super_copy), | ||
6775 | total_dev); | ||
6776 | ret = -EINVAL; | ||
6777 | goto error; | ||
6778 | } | ||
6779 | if (btrfs_super_total_bytes(root->fs_info->super_copy) < | ||
6780 | root->fs_info->fs_devices->total_rw_bytes) { | ||
6781 | btrfs_err(root->fs_info, | ||
6782 | "super_total_bytes %llu mismatch with fs_devices total_rw_bytes %llu", | ||
6783 | btrfs_super_total_bytes(root->fs_info->super_copy), | ||
6784 | root->fs_info->fs_devices->total_rw_bytes); | ||
6785 | ret = -EINVAL; | ||
6786 | goto error; | ||
6787 | } | ||
6709 | ret = 0; | 6788 | ret = 0; |
6710 | error: | 6789 | error: |
6711 | unlock_chunks(root); | 6790 | unlock_chunks(root); |