aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <clm@fb.com>2016-10-12 16:16:00 -0400
committerChris Mason <clm@fb.com>2016-10-12 16:16:00 -0400
commitd9ed71e5457c8c5bf1dc706e06468eab9e2aa87e (patch)
treeddc02c4207fc2c828ea4612d45f4af32d5dc292f
parent19c4d2f994788a954af1aa7e53b0fdb46fd7925a (diff)
parent0e6757859efea6ed919fc37e4ee468634220b2d2 (diff)
Merge branch 'fst-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux into for-linus-4.9
Signed-off-by: Chris Mason <clm@fb.com>
-rw-r--r--fs/btrfs/ctree.h3
-rw-r--r--fs/btrfs/disk-io.c33
-rw-r--r--fs/btrfs/extent_io.c64
-rw-r--r--fs/btrfs/extent_io.h22
-rw-r--r--fs/btrfs/free-space-tree.c19
-rw-r--r--fs/btrfs/tests/extent-io-tests.c87
-rw-r--r--fs/btrfs/tests/free-space-tree-tests.c189
-rw-r--r--include/uapi/linux/btrfs.h12
8 files changed, 272 insertions, 157 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index bf7cb6da78e6..9d8edcb0813c 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -252,7 +252,8 @@ struct btrfs_super_block {
252#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL 252#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL
253 253
254#define BTRFS_FEATURE_COMPAT_RO_SUPP \ 254#define BTRFS_FEATURE_COMPAT_RO_SUPP \
255 (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) 255 (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \
256 BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID)
256 257
257#define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL 258#define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL
258#define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL 259#define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index e720d3e6ec20..3a57f99d96aa 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -2586,6 +2586,7 @@ int open_ctree(struct super_block *sb,
2586 int num_backups_tried = 0; 2586 int num_backups_tried = 0;
2587 int backup_index = 0; 2587 int backup_index = 0;
2588 int max_active; 2588 int max_active;
2589 int clear_free_space_tree = 0;
2589 2590
2590 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL); 2591 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
2591 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL); 2592 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
@@ -3148,6 +3149,26 @@ retry_root_backup:
3148 if (sb->s_flags & MS_RDONLY) 3149 if (sb->s_flags & MS_RDONLY)
3149 return 0; 3150 return 0;
3150 3151
3152 if (btrfs_test_opt(fs_info, CLEAR_CACHE) &&
3153 btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3154 clear_free_space_tree = 1;
3155 } else if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE) &&
3156 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID)) {
3157 btrfs_warn(fs_info, "free space tree is invalid");
3158 clear_free_space_tree = 1;
3159 }
3160
3161 if (clear_free_space_tree) {
3162 btrfs_info(fs_info, "clearing free space tree");
3163 ret = btrfs_clear_free_space_tree(fs_info);
3164 if (ret) {
3165 btrfs_warn(fs_info,
3166 "failed to clear free space tree: %d", ret);
3167 close_ctree(tree_root);
3168 return ret;
3169 }
3170 }
3171
3151 if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) && 3172 if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) &&
3152 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 3173 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3153 btrfs_info(fs_info, "creating free space tree"); 3174 btrfs_info(fs_info, "creating free space tree");
@@ -3185,18 +3206,6 @@ retry_root_backup:
3185 3206
3186 btrfs_qgroup_rescan_resume(fs_info); 3207 btrfs_qgroup_rescan_resume(fs_info);
3187 3208
3188 if (btrfs_test_opt(tree_root->fs_info, CLEAR_CACHE) &&
3189 btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
3190 btrfs_info(fs_info, "clearing free space tree");
3191 ret = btrfs_clear_free_space_tree(fs_info);
3192 if (ret) {
3193 btrfs_warn(fs_info,
3194 "failed to clear free space tree: %d", ret);
3195 close_ctree(tree_root);
3196 return ret;
3197 }
3198 }
3199
3200 if (!fs_info->uuid_root) { 3209 if (!fs_info->uuid_root) {
3201 btrfs_info(fs_info, "creating UUID tree"); 3210 btrfs_info(fs_info, "creating UUID tree");
3202 ret = btrfs_create_uuid_tree(fs_info); 3211 ret = btrfs_create_uuid_tree(fs_info);
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c
index ee40384c394d..66a755150056 100644
--- a/fs/btrfs/extent_io.c
+++ b/fs/btrfs/extent_io.c
@@ -5558,17 +5558,45 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src,
5558 } 5558 }
5559} 5559}
5560 5560
5561/* 5561void le_bitmap_set(u8 *map, unsigned int start, int len)
5562 * The extent buffer bitmap operations are done with byte granularity because 5562{
5563 * bitmap items are not guaranteed to be aligned to a word and therefore a 5563 u8 *p = map + BIT_BYTE(start);
5564 * single word in a bitmap may straddle two pages in the extent buffer. 5564 const unsigned int size = start + len;
5565 */ 5565 int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
5566#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) 5566 u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
5567#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) 5567
5568#define BITMAP_FIRST_BYTE_MASK(start) \ 5568 while (len - bits_to_set >= 0) {
5569 ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) 5569 *p |= mask_to_set;
5570#define BITMAP_LAST_BYTE_MASK(nbits) \ 5570 len -= bits_to_set;
5571 (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) 5571 bits_to_set = BITS_PER_BYTE;
5572 mask_to_set = ~(u8)0;
5573 p++;
5574 }
5575 if (len) {
5576 mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
5577 *p |= mask_to_set;
5578 }
5579}
5580
5581void le_bitmap_clear(u8 *map, unsigned int start, int len)
5582{
5583 u8 *p = map + BIT_BYTE(start);
5584 const unsigned int size = start + len;
5585 int bits_to_clear = BITS_PER_BYTE - (start % BITS_PER_BYTE);
5586 u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(start);
5587
5588 while (len - bits_to_clear >= 0) {
5589 *p &= ~mask_to_clear;
5590 len -= bits_to_clear;
5591 bits_to_clear = BITS_PER_BYTE;
5592 mask_to_clear = ~(u8)0;
5593 p++;
5594 }
5595 if (len) {
5596 mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);
5597 *p &= ~mask_to_clear;
5598 }
5599}
5572 5600
5573/* 5601/*
5574 * eb_bitmap_offset() - calculate the page and offset of the byte containing the 5602 * eb_bitmap_offset() - calculate the page and offset of the byte containing the
@@ -5612,7 +5640,7 @@ static inline void eb_bitmap_offset(struct extent_buffer *eb,
5612int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, 5640int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
5613 unsigned long nr) 5641 unsigned long nr)
5614{ 5642{
5615 char *kaddr; 5643 u8 *kaddr;
5616 struct page *page; 5644 struct page *page;
5617 unsigned long i; 5645 unsigned long i;
5618 size_t offset; 5646 size_t offset;
@@ -5634,13 +5662,13 @@ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
5634void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, 5662void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5635 unsigned long pos, unsigned long len) 5663 unsigned long pos, unsigned long len)
5636{ 5664{
5637 char *kaddr; 5665 u8 *kaddr;
5638 struct page *page; 5666 struct page *page;
5639 unsigned long i; 5667 unsigned long i;
5640 size_t offset; 5668 size_t offset;
5641 const unsigned int size = pos + len; 5669 const unsigned int size = pos + len;
5642 int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5670 int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
5643 unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos); 5671 u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);
5644 5672
5645 eb_bitmap_offset(eb, start, pos, &i, &offset); 5673 eb_bitmap_offset(eb, start, pos, &i, &offset);
5646 page = eb->pages[i]; 5674 page = eb->pages[i];
@@ -5651,7 +5679,7 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5651 kaddr[offset] |= mask_to_set; 5679 kaddr[offset] |= mask_to_set;
5652 len -= bits_to_set; 5680 len -= bits_to_set;
5653 bits_to_set = BITS_PER_BYTE; 5681 bits_to_set = BITS_PER_BYTE;
5654 mask_to_set = ~0U; 5682 mask_to_set = ~(u8)0;
5655 if (++offset >= PAGE_SIZE && len > 0) { 5683 if (++offset >= PAGE_SIZE && len > 0) {
5656 offset = 0; 5684 offset = 0;
5657 page = eb->pages[++i]; 5685 page = eb->pages[++i];
@@ -5676,13 +5704,13 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
5676void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, 5704void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
5677 unsigned long pos, unsigned long len) 5705 unsigned long pos, unsigned long len)
5678{ 5706{
5679 char *kaddr; 5707 u8 *kaddr;
5680 struct page *page; 5708 struct page *page;
5681 unsigned long i; 5709 unsigned long i;
5682 size_t offset; 5710 size_t offset;
5683 const unsigned int size = pos + len; 5711 const unsigned int size = pos + len;
5684 int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5712 int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);
5685 unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos); 5713 u8 mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);
5686 5714
5687 eb_bitmap_offset(eb, start, pos, &i, &offset); 5715 eb_bitmap_offset(eb, start, pos, &i, &offset);
5688 page = eb->pages[i]; 5716 page = eb->pages[i];
@@ -5693,7 +5721,7 @@ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
5693 kaddr[offset] &= ~mask_to_clear; 5721 kaddr[offset] &= ~mask_to_clear;
5694 len -= bits_to_clear; 5722 len -= bits_to_clear;
5695 bits_to_clear = BITS_PER_BYTE; 5723 bits_to_clear = BITS_PER_BYTE;
5696 mask_to_clear = ~0U; 5724 mask_to_clear = ~(u8)0;
5697 if (++offset >= PAGE_SIZE && len > 0) { 5725 if (++offset >= PAGE_SIZE && len > 0) {
5698 offset = 0; 5726 offset = 0;
5699 page = eb->pages[++i]; 5727 page = eb->pages[++i];
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h
index 4a094f1dc7ef..ab31d145227e 100644
--- a/fs/btrfs/extent_io.h
+++ b/fs/btrfs/extent_io.h
@@ -59,6 +59,28 @@
59 */ 59 */
60#define EXTENT_PAGE_PRIVATE 1 60#define EXTENT_PAGE_PRIVATE 1
61 61
62/*
63 * The extent buffer bitmap operations are done with byte granularity instead of
64 * word granularity for two reasons:
65 * 1. The bitmaps must be little-endian on disk.
66 * 2. Bitmap items are not guaranteed to be aligned to a word and therefore a
67 * single word in a bitmap may straddle two pages in the extent buffer.
68 */
69#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
70#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)
71#define BITMAP_FIRST_BYTE_MASK(start) \
72 ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)
73#define BITMAP_LAST_BYTE_MASK(nbits) \
74 (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))
75
76static inline int le_test_bit(int nr, const u8 *addr)
77{
78 return 1U & (addr[BIT_BYTE(nr)] >> (nr & (BITS_PER_BYTE-1)));
79}
80
81extern void le_bitmap_set(u8 *map, unsigned int start, int len);
82extern void le_bitmap_clear(u8 *map, unsigned int start, int len);
83
62struct extent_state; 84struct extent_state;
63struct btrfs_root; 85struct btrfs_root;
64struct btrfs_io_bio; 86struct btrfs_io_bio;
diff --git a/fs/btrfs/free-space-tree.c b/fs/btrfs/free-space-tree.c
index e4a42a8e4f84..57401b474ec6 100644
--- a/fs/btrfs/free-space-tree.c
+++ b/fs/btrfs/free-space-tree.c
@@ -151,7 +151,7 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize)
151 return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE); 151 return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE);
152} 152}
153 153
154static unsigned long *alloc_bitmap(u32 bitmap_size) 154static u8 *alloc_bitmap(u32 bitmap_size)
155{ 155{
156 void *mem; 156 void *mem;
157 157
@@ -180,8 +180,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
180 struct btrfs_free_space_info *info; 180 struct btrfs_free_space_info *info;
181 struct btrfs_key key, found_key; 181 struct btrfs_key key, found_key;
182 struct extent_buffer *leaf; 182 struct extent_buffer *leaf;
183 unsigned long *bitmap; 183 u8 *bitmap, *bitmap_cursor;
184 char *bitmap_cursor;
185 u64 start, end; 184 u64 start, end;
186 u64 bitmap_range, i; 185 u64 bitmap_range, i;
187 u32 bitmap_size, flags, expected_extent_count; 186 u32 bitmap_size, flags, expected_extent_count;
@@ -231,7 +230,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
231 block_group->sectorsize); 230 block_group->sectorsize);
232 last = div_u64(found_key.objectid + found_key.offset - start, 231 last = div_u64(found_key.objectid + found_key.offset - start,
233 block_group->sectorsize); 232 block_group->sectorsize);
234 bitmap_set(bitmap, first, last - first); 233 le_bitmap_set(bitmap, first, last - first);
235 234
236 extent_count++; 235 extent_count++;
237 nr++; 236 nr++;
@@ -270,7 +269,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
270 goto out; 269 goto out;
271 } 270 }
272 271
273 bitmap_cursor = (char *)bitmap; 272 bitmap_cursor = bitmap;
274 bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS; 273 bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
275 i = start; 274 i = start;
276 while (i < end) { 275 while (i < end) {
@@ -319,7 +318,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
319 struct btrfs_free_space_info *info; 318 struct btrfs_free_space_info *info;
320 struct btrfs_key key, found_key; 319 struct btrfs_key key, found_key;
321 struct extent_buffer *leaf; 320 struct extent_buffer *leaf;
322 unsigned long *bitmap; 321 u8 *bitmap;
323 u64 start, end; 322 u64 start, end;
324 /* Initialize to silence GCC. */ 323 /* Initialize to silence GCC. */
325 u64 extent_start = 0; 324 u64 extent_start = 0;
@@ -363,7 +362,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
363 break; 362 break;
364 } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { 363 } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
365 unsigned long ptr; 364 unsigned long ptr;
366 char *bitmap_cursor; 365 u8 *bitmap_cursor;
367 u32 bitmap_pos, data_size; 366 u32 bitmap_pos, data_size;
368 367
369 ASSERT(found_key.objectid >= start); 368 ASSERT(found_key.objectid >= start);
@@ -373,7 +372,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
373 bitmap_pos = div_u64(found_key.objectid - start, 372 bitmap_pos = div_u64(found_key.objectid - start,
374 block_group->sectorsize * 373 block_group->sectorsize *
375 BITS_PER_BYTE); 374 BITS_PER_BYTE);
376 bitmap_cursor = ((char *)bitmap) + bitmap_pos; 375 bitmap_cursor = bitmap + bitmap_pos;
377 data_size = free_space_bitmap_size(found_key.offset, 376 data_size = free_space_bitmap_size(found_key.offset,
378 block_group->sectorsize); 377 block_group->sectorsize);
379 378
@@ -410,7 +409,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans,
410 offset = start; 409 offset = start;
411 bitnr = 0; 410 bitnr = 0;
412 while (offset < end) { 411 while (offset < end) {
413 bit = !!test_bit(bitnr, bitmap); 412 bit = !!le_test_bit(bitnr, bitmap);
414 if (prev_bit == 0 && bit == 1) { 413 if (prev_bit == 0 && bit == 1) {
415 extent_start = offset; 414 extent_start = offset;
416 } else if (prev_bit == 1 && bit == 0) { 415 } else if (prev_bit == 1 && bit == 0) {
@@ -1185,6 +1184,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
1185 } 1184 }
1186 1185
1187 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); 1186 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
1187 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
1188 clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags); 1188 clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
1189 1189
1190 ret = btrfs_commit_transaction(trans, tree_root); 1190 ret = btrfs_commit_transaction(trans, tree_root);
@@ -1253,6 +1253,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)
1253 return PTR_ERR(trans); 1253 return PTR_ERR(trans);
1254 1254
1255 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE); 1255 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);
1256 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
1256 fs_info->free_space_root = NULL; 1257 fs_info->free_space_root = NULL;
1257 1258
1258 ret = clear_free_space_tree(trans, free_space_root); 1259 ret = clear_free_space_tree(trans, free_space_root);
diff --git a/fs/btrfs/tests/extent-io-tests.c b/fs/btrfs/tests/extent-io-tests.c
index d19ab0317283..caad80bb9bd0 100644
--- a/fs/btrfs/tests/extent-io-tests.c
+++ b/fs/btrfs/tests/extent-io-tests.c
@@ -273,20 +273,37 @@ out:
273 return ret; 273 return ret;
274} 274}
275 275
276/** 276static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb,
277 * test_bit_in_byte - Determine whether a bit is set in a byte 277 unsigned long len)
278 * @nr: bit number to test
279 * @addr: Address to start counting from
280 */
281static inline int test_bit_in_byte(int nr, const u8 *addr)
282{ 278{
283 return 1UL & (addr[nr / BITS_PER_BYTE] >> (nr & (BITS_PER_BYTE - 1))); 279 unsigned long i;
280
281 for (i = 0; i < len * BITS_PER_BYTE; i++) {
282 int bit, bit1;
283
284 bit = !!test_bit(i, bitmap);
285 bit1 = !!extent_buffer_test_bit(eb, 0, i);
286 if (bit1 != bit) {
287 test_msg("Bits do not match\n");
288 return -EINVAL;
289 }
290
291 bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
292 i % BITS_PER_BYTE);
293 if (bit1 != bit) {
294 test_msg("Offset bits do not match\n");
295 return -EINVAL;
296 }
297 }
298 return 0;
284} 299}
285 300
286static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, 301static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
287 unsigned long len) 302 unsigned long len)
288{ 303{
289 unsigned long i, x; 304 unsigned long i, j;
305 u32 x;
306 int ret;
290 307
291 memset(bitmap, 0, len); 308 memset(bitmap, 0, len);
292 memset_extent_buffer(eb, 0, 0, len); 309 memset_extent_buffer(eb, 0, 0, len);
@@ -297,16 +314,18 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
297 314
298 bitmap_set(bitmap, 0, len * BITS_PER_BYTE); 315 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
299 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); 316 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
300 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 317 ret = check_eb_bitmap(bitmap, eb, len);
318 if (ret) {
301 test_msg("Setting all bits failed\n"); 319 test_msg("Setting all bits failed\n");
302 return -EINVAL; 320 return ret;
303 } 321 }
304 322
305 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE); 323 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
306 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE); 324 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
307 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 325 ret = check_eb_bitmap(bitmap, eb, len);
326 if (ret) {
308 test_msg("Clearing all bits failed\n"); 327 test_msg("Clearing all bits failed\n");
309 return -EINVAL; 328 return ret;
310 } 329 }
311 330
312 /* Straddling pages test */ 331 /* Straddling pages test */
@@ -316,9 +335,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
316 sizeof(long) * BITS_PER_BYTE); 335 sizeof(long) * BITS_PER_BYTE);
317 extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0, 336 extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0,
318 sizeof(long) * BITS_PER_BYTE); 337 sizeof(long) * BITS_PER_BYTE);
319 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 338 ret = check_eb_bitmap(bitmap, eb, len);
339 if (ret) {
320 test_msg("Setting straddling pages failed\n"); 340 test_msg("Setting straddling pages failed\n");
321 return -EINVAL; 341 return ret;
322 } 342 }
323 343
324 bitmap_set(bitmap, 0, len * BITS_PER_BYTE); 344 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
@@ -328,9 +348,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
328 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); 348 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
329 extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0, 349 extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0,
330 sizeof(long) * BITS_PER_BYTE); 350 sizeof(long) * BITS_PER_BYTE);
331 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 351 ret = check_eb_bitmap(bitmap, eb, len);
352 if (ret) {
332 test_msg("Clearing straddling pages failed\n"); 353 test_msg("Clearing straddling pages failed\n");
333 return -EINVAL; 354 return ret;
334 } 355 }
335 } 356 }
336 357
@@ -339,28 +360,22 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
339 * something repetitive that could miss some hypothetical off-by-n bug. 360 * something repetitive that could miss some hypothetical off-by-n bug.
340 */ 361 */
341 x = 0; 362 x = 0;
342 for (i = 0; i < len / sizeof(long); i++) { 363 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
343 x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffUL; 364 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
344 bitmap[i] = x; 365 for (i = 0; i < len * BITS_PER_BYTE / 32; i++) {
345 } 366 x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffU;
346 write_extent_buffer(eb, bitmap, 0, len); 367 for (j = 0; j < 32; j++) {
347 368 if (x & (1U << j)) {
348 for (i = 0; i < len * BITS_PER_BYTE; i++) { 369 bitmap_set(bitmap, i * 32 + j, 1);
349 int bit, bit1; 370 extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
350 371 }
351 bit = !!test_bit_in_byte(i, (u8 *)bitmap);
352 bit1 = !!extent_buffer_test_bit(eb, 0, i);
353 if (bit1 != bit) {
354 test_msg("Testing bit pattern failed\n");
355 return -EINVAL;
356 } 372 }
373 }
357 374
358 bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE, 375 ret = check_eb_bitmap(bitmap, eb, len);
359 i % BITS_PER_BYTE); 376 if (ret) {
360 if (bit1 != bit) { 377 test_msg("Random bit pattern failed\n");
361 test_msg("Testing bit pattern with offset failed\n"); 378 return ret;
362 return -EINVAL;
363 }
364 } 379 }
365 380
366 return 0; 381 return 0;
diff --git a/fs/btrfs/tests/free-space-tree-tests.c b/fs/btrfs/tests/free-space-tree-tests.c
index 7508d3b42780..6e144048a72e 100644
--- a/fs/btrfs/tests/free-space-tree-tests.c
+++ b/fs/btrfs/tests/free-space-tree-tests.c
@@ -24,20 +24,15 @@
24#include "../transaction.h" 24#include "../transaction.h"
25 25
26struct free_space_extent { 26struct free_space_extent {
27 u64 start, length; 27 u64 start;
28 u64 length;
28}; 29};
29 30
30/*
31 * The test cases align their operations to this in order to hit some of the
32 * edge cases in the bitmap code.
33 */
34#define BITMAP_RANGE (BTRFS_FREE_SPACE_BITMAP_BITS * PAGE_SIZE)
35
36static int __check_free_space_extents(struct btrfs_trans_handle *trans, 31static int __check_free_space_extents(struct btrfs_trans_handle *trans,
37 struct btrfs_fs_info *fs_info, 32 struct btrfs_fs_info *fs_info,
38 struct btrfs_block_group_cache *cache, 33 struct btrfs_block_group_cache *cache,
39 struct btrfs_path *path, 34 struct btrfs_path *path,
40 struct free_space_extent *extents, 35 const struct free_space_extent * const extents,
41 unsigned int num_extents) 36 unsigned int num_extents)
42{ 37{
43 struct btrfs_free_space_info *info; 38 struct btrfs_free_space_info *info;
@@ -126,7 +121,7 @@ static int check_free_space_extents(struct btrfs_trans_handle *trans,
126 struct btrfs_fs_info *fs_info, 121 struct btrfs_fs_info *fs_info,
127 struct btrfs_block_group_cache *cache, 122 struct btrfs_block_group_cache *cache,
128 struct btrfs_path *path, 123 struct btrfs_path *path,
129 struct free_space_extent *extents, 124 const struct free_space_extent * const extents,
130 unsigned int num_extents) 125 unsigned int num_extents)
131{ 126{
132 struct btrfs_free_space_info *info; 127 struct btrfs_free_space_info *info;
@@ -168,9 +163,10 @@ static int check_free_space_extents(struct btrfs_trans_handle *trans,
168static int test_empty_block_group(struct btrfs_trans_handle *trans, 163static int test_empty_block_group(struct btrfs_trans_handle *trans,
169 struct btrfs_fs_info *fs_info, 164 struct btrfs_fs_info *fs_info,
170 struct btrfs_block_group_cache *cache, 165 struct btrfs_block_group_cache *cache,
171 struct btrfs_path *path) 166 struct btrfs_path *path,
167 u32 alignment)
172{ 168{
173 struct free_space_extent extents[] = { 169 const struct free_space_extent extents[] = {
174 {cache->key.objectid, cache->key.offset}, 170 {cache->key.objectid, cache->key.offset},
175 }; 171 };
176 172
@@ -181,9 +177,10 @@ static int test_empty_block_group(struct btrfs_trans_handle *trans,
181static int test_remove_all(struct btrfs_trans_handle *trans, 177static int test_remove_all(struct btrfs_trans_handle *trans,
182 struct btrfs_fs_info *fs_info, 178 struct btrfs_fs_info *fs_info,
183 struct btrfs_block_group_cache *cache, 179 struct btrfs_block_group_cache *cache,
184 struct btrfs_path *path) 180 struct btrfs_path *path,
181 u32 alignment)
185{ 182{
186 struct free_space_extent extents[] = {}; 183 const struct free_space_extent extents[] = {};
187 int ret; 184 int ret;
188 185
189 ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 186 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
@@ -201,16 +198,17 @@ static int test_remove_all(struct btrfs_trans_handle *trans,
201static int test_remove_beginning(struct btrfs_trans_handle *trans, 198static int test_remove_beginning(struct btrfs_trans_handle *trans,
202 struct btrfs_fs_info *fs_info, 199 struct btrfs_fs_info *fs_info,
203 struct btrfs_block_group_cache *cache, 200 struct btrfs_block_group_cache *cache,
204 struct btrfs_path *path) 201 struct btrfs_path *path,
202 u32 alignment)
205{ 203{
206 struct free_space_extent extents[] = { 204 const struct free_space_extent extents[] = {
207 {cache->key.objectid + BITMAP_RANGE, 205 {cache->key.objectid + alignment,
208 cache->key.offset - BITMAP_RANGE}, 206 cache->key.offset - alignment},
209 }; 207 };
210 int ret; 208 int ret;
211 209
212 ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 210 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
213 cache->key.objectid, BITMAP_RANGE); 211 cache->key.objectid, alignment);
214 if (ret) { 212 if (ret) {
215 test_msg("Could not remove free space\n"); 213 test_msg("Could not remove free space\n");
216 return ret; 214 return ret;
@@ -224,17 +222,18 @@ static int test_remove_beginning(struct btrfs_trans_handle *trans,
224static int test_remove_end(struct btrfs_trans_handle *trans, 222static int test_remove_end(struct btrfs_trans_handle *trans,
225 struct btrfs_fs_info *fs_info, 223 struct btrfs_fs_info *fs_info,
226 struct btrfs_block_group_cache *cache, 224 struct btrfs_block_group_cache *cache,
227 struct btrfs_path *path) 225 struct btrfs_path *path,
226 u32 alignment)
228{ 227{
229 struct free_space_extent extents[] = { 228 const struct free_space_extent extents[] = {
230 {cache->key.objectid, cache->key.offset - BITMAP_RANGE}, 229 {cache->key.objectid, cache->key.offset - alignment},
231 }; 230 };
232 int ret; 231 int ret;
233 232
234 ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 233 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
235 cache->key.objectid + 234 cache->key.objectid +
236 cache->key.offset - BITMAP_RANGE, 235 cache->key.offset - alignment,
237 BITMAP_RANGE); 236 alignment);
238 if (ret) { 237 if (ret) {
239 test_msg("Could not remove free space\n"); 238 test_msg("Could not remove free space\n");
240 return ret; 239 return ret;
@@ -247,18 +246,19 @@ static int test_remove_end(struct btrfs_trans_handle *trans,
247static int test_remove_middle(struct btrfs_trans_handle *trans, 246static int test_remove_middle(struct btrfs_trans_handle *trans,
248 struct btrfs_fs_info *fs_info, 247 struct btrfs_fs_info *fs_info,
249 struct btrfs_block_group_cache *cache, 248 struct btrfs_block_group_cache *cache,
250 struct btrfs_path *path) 249 struct btrfs_path *path,
250 u32 alignment)
251{ 251{
252 struct free_space_extent extents[] = { 252 const struct free_space_extent extents[] = {
253 {cache->key.objectid, BITMAP_RANGE}, 253 {cache->key.objectid, alignment},
254 {cache->key.objectid + 2 * BITMAP_RANGE, 254 {cache->key.objectid + 2 * alignment,
255 cache->key.offset - 2 * BITMAP_RANGE}, 255 cache->key.offset - 2 * alignment},
256 }; 256 };
257 int ret; 257 int ret;
258 258
259 ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 259 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
260 cache->key.objectid + BITMAP_RANGE, 260 cache->key.objectid + alignment,
261 BITMAP_RANGE); 261 alignment);
262 if (ret) { 262 if (ret) {
263 test_msg("Could not remove free space\n"); 263 test_msg("Could not remove free space\n");
264 return ret; 264 return ret;
@@ -271,10 +271,11 @@ static int test_remove_middle(struct btrfs_trans_handle *trans,
271static int test_merge_left(struct btrfs_trans_handle *trans, 271static int test_merge_left(struct btrfs_trans_handle *trans,
272 struct btrfs_fs_info *fs_info, 272 struct btrfs_fs_info *fs_info,
273 struct btrfs_block_group_cache *cache, 273 struct btrfs_block_group_cache *cache,
274 struct btrfs_path *path) 274 struct btrfs_path *path,
275 u32 alignment)
275{ 276{
276 struct free_space_extent extents[] = { 277 const struct free_space_extent extents[] = {
277 {cache->key.objectid, 2 * BITMAP_RANGE}, 278 {cache->key.objectid, 2 * alignment},
278 }; 279 };
279 int ret; 280 int ret;
280 281
@@ -287,15 +288,15 @@ static int test_merge_left(struct btrfs_trans_handle *trans,
287 } 288 }
288 289
289 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 290 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
290 cache->key.objectid, BITMAP_RANGE); 291 cache->key.objectid, alignment);
291 if (ret) { 292 if (ret) {
292 test_msg("Could not add free space\n"); 293 test_msg("Could not add free space\n");
293 return ret; 294 return ret;
294 } 295 }
295 296
296 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 297 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
297 cache->key.objectid + BITMAP_RANGE, 298 cache->key.objectid + alignment,
298 BITMAP_RANGE); 299 alignment);
299 if (ret) { 300 if (ret) {
300 test_msg("Could not add free space\n"); 301 test_msg("Could not add free space\n");
301 return ret; 302 return ret;
@@ -308,10 +309,11 @@ static int test_merge_left(struct btrfs_trans_handle *trans,
308static int test_merge_right(struct btrfs_trans_handle *trans, 309static int test_merge_right(struct btrfs_trans_handle *trans,
309 struct btrfs_fs_info *fs_info, 310 struct btrfs_fs_info *fs_info,
310 struct btrfs_block_group_cache *cache, 311 struct btrfs_block_group_cache *cache,
311 struct btrfs_path *path) 312 struct btrfs_path *path,
313 u32 alignment)
312{ 314{
313 struct free_space_extent extents[] = { 315 const struct free_space_extent extents[] = {
314 {cache->key.objectid + BITMAP_RANGE, 2 * BITMAP_RANGE}, 316 {cache->key.objectid + alignment, 2 * alignment},
315 }; 317 };
316 int ret; 318 int ret;
317 319
@@ -324,16 +326,16 @@ static int test_merge_right(struct btrfs_trans_handle *trans,
324 } 326 }
325 327
326 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 328 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
327 cache->key.objectid + 2 * BITMAP_RANGE, 329 cache->key.objectid + 2 * alignment,
328 BITMAP_RANGE); 330 alignment);
329 if (ret) { 331 if (ret) {
330 test_msg("Could not add free space\n"); 332 test_msg("Could not add free space\n");
331 return ret; 333 return ret;
332 } 334 }
333 335
334 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 336 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
335 cache->key.objectid + BITMAP_RANGE, 337 cache->key.objectid + alignment,
336 BITMAP_RANGE); 338 alignment);
337 if (ret) { 339 if (ret) {
338 test_msg("Could not add free space\n"); 340 test_msg("Could not add free space\n");
339 return ret; 341 return ret;
@@ -346,10 +348,11 @@ static int test_merge_right(struct btrfs_trans_handle *trans,
346static int test_merge_both(struct btrfs_trans_handle *trans, 348static int test_merge_both(struct btrfs_trans_handle *trans,
347 struct btrfs_fs_info *fs_info, 349 struct btrfs_fs_info *fs_info,
348 struct btrfs_block_group_cache *cache, 350 struct btrfs_block_group_cache *cache,
349 struct btrfs_path *path) 351 struct btrfs_path *path,
352 u32 alignment)
350{ 353{
351 struct free_space_extent extents[] = { 354 const struct free_space_extent extents[] = {
352 {cache->key.objectid, 3 * BITMAP_RANGE}, 355 {cache->key.objectid, 3 * alignment},
353 }; 356 };
354 int ret; 357 int ret;
355 358
@@ -362,23 +365,23 @@ static int test_merge_both(struct btrfs_trans_handle *trans,
362 } 365 }
363 366
364 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 367 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
365 cache->key.objectid, BITMAP_RANGE); 368 cache->key.objectid, alignment);
366 if (ret) { 369 if (ret) {
367 test_msg("Could not add free space\n"); 370 test_msg("Could not add free space\n");
368 return ret; 371 return ret;
369 } 372 }
370 373
371 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 374 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
372 cache->key.objectid + 2 * BITMAP_RANGE, 375 cache->key.objectid + 2 * alignment,
373 BITMAP_RANGE); 376 alignment);
374 if (ret) { 377 if (ret) {
375 test_msg("Could not add free space\n"); 378 test_msg("Could not add free space\n");
376 return ret; 379 return ret;
377 } 380 }
378 381
379 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 382 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
380 cache->key.objectid + BITMAP_RANGE, 383 cache->key.objectid + alignment,
381 BITMAP_RANGE); 384 alignment);
382 if (ret) { 385 if (ret) {
383 test_msg("Could not add free space\n"); 386 test_msg("Could not add free space\n");
384 return ret; 387 return ret;
@@ -391,12 +394,13 @@ static int test_merge_both(struct btrfs_trans_handle *trans,
391static int test_merge_none(struct btrfs_trans_handle *trans, 394static int test_merge_none(struct btrfs_trans_handle *trans,
392 struct btrfs_fs_info *fs_info, 395 struct btrfs_fs_info *fs_info,
393 struct btrfs_block_group_cache *cache, 396 struct btrfs_block_group_cache *cache,
394 struct btrfs_path *path) 397 struct btrfs_path *path,
398 u32 alignment)
395{ 399{
396 struct free_space_extent extents[] = { 400 const struct free_space_extent extents[] = {
397 {cache->key.objectid, BITMAP_RANGE}, 401 {cache->key.objectid, alignment},
398 {cache->key.objectid + 2 * BITMAP_RANGE, BITMAP_RANGE}, 402 {cache->key.objectid + 2 * alignment, alignment},
399 {cache->key.objectid + 4 * BITMAP_RANGE, BITMAP_RANGE}, 403 {cache->key.objectid + 4 * alignment, alignment},
400 }; 404 };
401 int ret; 405 int ret;
402 406
@@ -409,23 +413,23 @@ static int test_merge_none(struct btrfs_trans_handle *trans,
409 } 413 }
410 414
411 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 415 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
412 cache->key.objectid, BITMAP_RANGE); 416 cache->key.objectid, alignment);
413 if (ret) { 417 if (ret) {
414 test_msg("Could not add free space\n"); 418 test_msg("Could not add free space\n");
415 return ret; 419 return ret;
416 } 420 }
417 421
418 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 422 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
419 cache->key.objectid + 4 * BITMAP_RANGE, 423 cache->key.objectid + 4 * alignment,
420 BITMAP_RANGE); 424 alignment);
421 if (ret) { 425 if (ret) {
422 test_msg("Could not add free space\n"); 426 test_msg("Could not add free space\n");
423 return ret; 427 return ret;
424 } 428 }
425 429
426 ret = __add_to_free_space_tree(trans, fs_info, cache, path, 430 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
427 cache->key.objectid + 2 * BITMAP_RANGE, 431 cache->key.objectid + 2 * alignment,
428 BITMAP_RANGE); 432 alignment);
429 if (ret) { 433 if (ret) {
430 test_msg("Could not add free space\n"); 434 test_msg("Could not add free space\n");
431 return ret; 435 return ret;
@@ -438,10 +442,11 @@ static int test_merge_none(struct btrfs_trans_handle *trans,
438typedef int (*test_func_t)(struct btrfs_trans_handle *, 442typedef int (*test_func_t)(struct btrfs_trans_handle *,
439 struct btrfs_fs_info *, 443 struct btrfs_fs_info *,
440 struct btrfs_block_group_cache *, 444 struct btrfs_block_group_cache *,
441 struct btrfs_path *); 445 struct btrfs_path *,
446 u32 alignment);
442 447
443static int run_test(test_func_t test_func, int bitmaps, 448static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
444 u32 sectorsize, u32 nodesize) 449 u32 nodesize, u32 alignment)
445{ 450{
446 struct btrfs_fs_info *fs_info; 451 struct btrfs_fs_info *fs_info;
447 struct btrfs_root *root = NULL; 452 struct btrfs_root *root = NULL;
@@ -480,7 +485,7 @@ static int run_test(test_func_t test_func, int bitmaps,
480 btrfs_set_header_nritems(root->node, 0); 485 btrfs_set_header_nritems(root->node, 0);
481 root->alloc_bytenr += 2 * nodesize; 486 root->alloc_bytenr += 2 * nodesize;
482 487
483 cache = btrfs_alloc_dummy_block_group(8 * BITMAP_RANGE, sectorsize); 488 cache = btrfs_alloc_dummy_block_group(8 * alignment, sectorsize);
484 if (!cache) { 489 if (!cache) {
485 test_msg("Couldn't allocate dummy block group cache\n"); 490 test_msg("Couldn't allocate dummy block group cache\n");
486 ret = -ENOMEM; 491 ret = -ENOMEM;
@@ -514,7 +519,7 @@ static int run_test(test_func_t test_func, int bitmaps,
514 } 519 }
515 } 520 }
516 521
517 ret = test_func(&trans, root->fs_info, cache, path); 522 ret = test_func(&trans, root->fs_info, cache, path, alignment);
518 if (ret) 523 if (ret)
519 goto out; 524 goto out;
520 525
@@ -539,15 +544,27 @@ out:
539 return ret; 544 return ret;
540} 545}
541 546
542static int run_test_both_formats(test_func_t test_func, 547static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
543 u32 sectorsize, u32 nodesize) 548 u32 nodesize, u32 alignment)
544{ 549{
550 int test_ret = 0;
545 int ret; 551 int ret;
546 552
547 ret = run_test(test_func, 0, sectorsize, nodesize); 553 ret = run_test(test_func, 0, sectorsize, nodesize, alignment);
548 if (ret) 554 if (ret) {
549 return ret; 555 test_msg("%pf failed with extents, sectorsize=%u, nodesize=%u, alignment=%u\n",
550 return run_test(test_func, 1, sectorsize, nodesize); 556 test_func, sectorsize, nodesize, alignment);
557 test_ret = ret;
558 }
559
560 ret = run_test(test_func, 1, sectorsize, nodesize, alignment);
561 if (ret) {
562 test_msg("%pf failed with bitmaps, sectorsize=%u, nodesize=%u, alignment=%u\n",
563 test_func, sectorsize, nodesize, alignment);
564 test_ret = ret;
565 }
566
567 return test_ret;
551} 568}
552 569
553int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize) 570int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
@@ -563,18 +580,30 @@ int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
563 test_merge_both, 580 test_merge_both,
564 test_merge_none, 581 test_merge_none,
565 }; 582 };
583 u32 bitmap_alignment;
584 int test_ret = 0;
566 int i; 585 int i;
567 586
587 /*
588 * Align some operations to a page to flush out bugs in the extent
589 * buffer bitmap handling of highmem.
590 */
591 bitmap_alignment = BTRFS_FREE_SPACE_BITMAP_BITS * PAGE_SIZE;
592
568 test_msg("Running free space tree tests\n"); 593 test_msg("Running free space tree tests\n");
569 for (i = 0; i < ARRAY_SIZE(tests); i++) { 594 for (i = 0; i < ARRAY_SIZE(tests); i++) {
570 int ret = run_test_both_formats(tests[i], sectorsize, 595 int ret;
571 nodesize); 596
572 if (ret) { 597 ret = run_test_both_formats(tests[i], sectorsize, nodesize,
573 test_msg("%pf : sectorsize %u failed\n", 598 sectorsize);
574 tests[i], sectorsize); 599 if (ret)
575 return ret; 600 test_ret = ret;
576 } 601
602 ret = run_test_both_formats(tests[i], sectorsize, nodesize,
603 bitmap_alignment);
604 if (ret)
605 test_ret = ret;
577 } 606 }
578 607
579 return 0; 608 return test_ret;
580} 609}
diff --git a/include/uapi/linux/btrfs.h b/include/uapi/linux/btrfs.h
index ac5eacd3055b..db4c253f8011 100644
--- a/include/uapi/linux/btrfs.h
+++ b/include/uapi/linux/btrfs.h
@@ -239,7 +239,17 @@ struct btrfs_ioctl_fs_info_args {
239 * Used by: 239 * Used by:
240 * struct btrfs_ioctl_feature_flags 240 * struct btrfs_ioctl_feature_flags
241 */ 241 */
242#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) 242#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0)
243/*
244 * Older kernels (< 4.9) on big-endian systems produced broken free space tree
245 * bitmaps, and btrfs-progs also used to corrupt the free space tree (versions
246 * < 4.7.3). If this bit is clear, then the free space tree cannot be trusted.
247 * btrfs-progs can also intentionally clear this bit to ask the kernel to
248 * rebuild the free space tree, however this might not work on older kernels
249 * that do not know about this bit. If not sure, clear the cache manually on
250 * first mount when booting older kernel versions.
251 */
252#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID (1ULL << 1)
243 253
244#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) 254#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
245#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) 255#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)