aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 20:44:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-10-14 20:44:56 -0400
commitd3304cadb2e24517938e24efd58fd9ee6504fefe (patch)
tree5bf53a560d3df9c89b5b0d5ed095fc386c91fca4
parent1a892b485f328224b4882818f84fcc0a3208677d (diff)
parentd9ed71e5457c8c5bf1dc706e06468eab9e2aa87e (diff)
Merge branch 'for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason: "Some fixes from Omar and Dave Sterba for our new free space tree. This isn't heavily used yet, but as we move toward making it the new default we wanted to nail down an endian bug" * 'for-linus-4.9' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: btrfs: tests: uninline member definitions in free_space_extent btrfs: tests: constify free space extent specs Btrfs: expand free space tree sanity tests to catch endianness bug Btrfs: fix extent buffer bitmap tests on big-endian systems Btrfs: catch invalid free space trees Btrfs: fix mount -o clear_cache,space_cache=v2 Btrfs: fix free space tree bitmaps on big-endian systems
-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 6c21bad26a27..0b8ce2b9f7d0 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)