History

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

Linus Torvalds committed 10 years ago

Commit d3304ca2 parents 1a892b4 d9ed71e8 files · +272 −157Browse files

Unified · Split

8 files
  1. fs/btrfs/ctree.h +2 −1
  2. fs/btrfs/disk-io.c +21 −12
  3. fs/btrfs/extent_io.c +46 −18
  4. fs/btrfs/extent_io.h +22 −0
  5. fs/btrfs/free-space-tree.c +10 −9
  6. fs/btrfs/tests/extent-io-tests.c +51 −36
  7. fs/btrfs/tests/free-space-tree-tests.c +109 −80
  8. include/uapi/linux/btrfs.h +11 −1
fs/btrfs/ctree.h+2−1
@@ -252,7 +252,8 @@ struct btrfs_super_block { · 251 unmodified lines
252252 #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL
253253
254254 #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)
256257
257258 #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL
258259 #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL
fs/btrfs/disk-io.c+21−12
@@ -2586,6 +2586,7 @@ int open_ctree(struct super_block *sb, · 2585 unmodified lines
25862586 int num_backups_tried = 0;
25872587 int backup_index = 0;
25882588 int max_active;
2589+ int clear_free_space_tree = 0;
25892590
25902591 tree_root = fs_info->tree_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
25912592 chunk_root = fs_info->chunk_root = btrfs_alloc_root(fs_info, GFP_KERNEL);
@@ -3148,6 +3149,26 @@ retry_root_backup: · 556 unmodified lines
31483149 if (sb->s_flags & MS_RDONLY)
31493150 return 0;
31503151
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+
31513172 if (btrfs_test_opt(tree_root->fs_info, FREE_SPACE_TREE) &&
31523173 !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {
31533174 btrfs_info(fs_info, "creating free space tree");
@@ -3185,18 +3206,6 @@ retry_root_backup: · 31 unmodified lines
31853206
31863207 btrfs_qgroup_rescan_resume(fs_info);
31873208
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−
32003209 if (!fs_info->uuid_root) {
32013210 btrfs_info(fs_info, "creating UUID tree");
32023211 ret = btrfs_create_uuid_tree(fs_info);
fs/btrfs/extent_io.c+46−18
@@ -5558,17 +5558,45 @@ void copy_extent_buffer(struct extent_buffer *dst, struct extent_buffer *src, · 5557 unmodified lines
55585558 }
55595559 }
55605560
5561−/*
5562− * The extent buffer bitmap operations are done with byte granularity because
5563− * bitmap items are not guaranteed to be aligned to a word and therefore a
5564− * single word in a bitmap may straddle two pages in the extent buffer.
5565− */
5566−#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)
5567−#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)
5568−#define BITMAP_FIRST_BYTE_MASK(start) \
5569− ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)
5570−#define BITMAP_LAST_BYTE_MASK(nbits) \
5571− (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))
5561+void le_bitmap_set(u8 *map, unsigned int start, int len)
5562+{
5563+ u8 *p = map + BIT_BYTE(start);
5564+ const unsigned int size = start + len;
5565+ int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
5566+ u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
5567+
5568+ while (len - bits_to_set >= 0) {
5569+ *p |= mask_to_set;
5570+ len -= bits_to_set;
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+
5581+void 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+}
55725600
55735601 /*
55745602 * 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, · 37 unmodified lines
56125640 int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,
56135641 unsigned long nr)
56145642 {
5615− char *kaddr;
5643+ u8 *kaddr;
56165644 struct page *page;
56175645 unsigned long i;
56185646 size_t offset;
@@ -5634,13 +5662,13 @@ int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, · 15 unmodified lines
56345662 void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,
56355663 unsigned long pos, unsigned long len)
56365664 {
5637− char *kaddr;
5665+ u8 *kaddr;
56385666 struct page *page;
56395667 unsigned long i;
56405668 size_t offset;
56415669 const unsigned int size = pos + len;
56425670 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);
56445672
56455673 eb_bitmap_offset(eb, start, pos, &i, &offset);
56465674 page = eb->pages[i];
@@ -5651,7 +5679,7 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, · 4 unmodified lines
56515679 kaddr[offset] |= mask_to_set;
56525680 len -= bits_to_set;
56535681 bits_to_set = BITS_PER_BYTE;
5654− mask_to_set = ~0U;
5682+ mask_to_set = ~(u8)0;
56555683 if (++offset >= PAGE_SIZE && len > 0) {
56565684 offset = 0;
56575685 page = eb->pages[++i];
@@ -5676,13 +5704,13 @@ void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, · 18 unmodified lines
56765704 void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,
56775705 unsigned long pos, unsigned long len)
56785706 {
5679− char *kaddr;
5707+ u8 *kaddr;
56805708 struct page *page;
56815709 unsigned long i;
56825710 size_t offset;
56835711 const unsigned int size = pos + len;
56845712 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);
56865714
56875715 eb_bitmap_offset(eb, start, pos, &i, &offset);
56885716 page = eb->pages[i];
@@ -5693,7 +5721,7 @@ void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, · 4 unmodified lines
56935721 kaddr[offset] &= ~mask_to_clear;
56945722 len -= bits_to_clear;
56955723 bits_to_clear = BITS_PER_BYTE;
5696− mask_to_clear = ~0U;
5724+ mask_to_clear = ~(u8)0;
56975725 if (++offset >= PAGE_SIZE && len > 0) {
56985726 offset = 0;
56995727 page = eb->pages[++i];
fs/btrfs/extent_io.h+22−0
@@ -59,6 +59,28 @@ · 58 unmodified lines
5959 */
6060 #define EXTENT_PAGE_PRIVATE 1
6161
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+
76+static 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+
81+extern void le_bitmap_set(u8 *map, unsigned int start, int len);
82+extern void le_bitmap_clear(u8 *map, unsigned int start, int len);
83+
6284 struct extent_state;
6385 struct btrfs_root;
6486 struct btrfs_io_bio;
fs/btrfs/free-space-tree.c+10−9
@@ -151,7 +151,7 @@ static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize) · 150 unmodified lines
151151 return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE);
152152 }
153153
154−static unsigned long *alloc_bitmap(u32 bitmap_size)
154+static u8 *alloc_bitmap(u32 bitmap_size)
155155 {
156156 void *mem;
157157
@@ -180,8 +180,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, · 22 unmodified lines
180180 struct btrfs_free_space_info *info;
181181 struct btrfs_key key, found_key;
182182 struct extent_buffer *leaf;
183− unsigned long *bitmap;
184− char *bitmap_cursor;
183+ u8 *bitmap, *bitmap_cursor;
185184 u64 start, end;
186185 u64 bitmap_range, i;
187186 u32 bitmap_size, flags, expected_extent_count;
@@ -231,7 +230,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, · 43 unmodified lines
231230 block_group->sectorsize);
232231 last = div_u64(found_key.objectid + found_key.offset - start,
233232 block_group->sectorsize);
234− bitmap_set(bitmap, first, last - first);
233+ le_bitmap_set(bitmap, first, last - first);
235234
236235 extent_count++;
237236 nr++;
@@ -270,7 +269,7 @@ int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, · 32 unmodified lines
270269 goto out;
271270 }
272271
273− bitmap_cursor = (char *)bitmap;
272+ bitmap_cursor = bitmap;
274273 bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
275274 i = start;
276275 while (i < end) {
@@ -319,7 +318,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, · 42 unmodified lines
319318 struct btrfs_free_space_info *info;
320319 struct btrfs_key key, found_key;
321320 struct extent_buffer *leaf;
322− unsigned long *bitmap;
321+ u8 *bitmap;
323322 u64 start, end;
324323 /* Initialize to silence GCC. */
325324 u64 extent_start = 0;
@@ -363,7 +362,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, · 37 unmodified lines
363362 break;
364363 } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
365364 unsigned long ptr;
366− char *bitmap_cursor;
365+ u8 *bitmap_cursor;
367366 u32 bitmap_pos, data_size;
368367
369368 ASSERT(found_key.objectid >= start);
@@ -373,7 +372,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, · 3 unmodified lines
373372 bitmap_pos = div_u64(found_key.objectid - start,
374373 block_group->sectorsize *
375374 BITS_PER_BYTE);
376− bitmap_cursor = ((char *)bitmap) + bitmap_pos;
375+ bitmap_cursor = bitmap + bitmap_pos;
377376 data_size = free_space_bitmap_size(found_key.offset,
378377 block_group->sectorsize);
379378
@@ -410,7 +409,7 @@ int convert_free_space_to_extents(struct btrfs_trans_handle *trans, · 30 unmodified lines
410409 offset = start;
411410 bitnr = 0;
412411 while (offset < end) {
413− bit = !!test_bit(bitnr, bitmap);
412+ bit = !!le_test_bit(bitnr, bitmap);
414413 if (prev_bit == 0 && bit == 1) {
415414 extent_start = offset;
416415 } else if (prev_bit == 1 && bit == 0) {
@@ -1185,6 +1184,7 @@ int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) · 768 unmodified lines
11851184 }
11861185
11871186 btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
1187+ btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
11881188 clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
11891189
11901190 ret = btrfs_commit_transaction(trans, tree_root);
@@ -1253,6 +1253,7 @@ int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) · 62 unmodified lines
12531253 return PTR_ERR(trans);
12541254
12551255 btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);
1256+ btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
12561257 fs_info->free_space_root = NULL;
12571258
12581259 ret = clear_free_space_tree(trans, free_space_root);
fs/btrfs/tests/extent-io-tests.c+51−36
@@ -273,20 +273,37 @@ out: · 272 unmodified lines
273273 return ret;
274274 }
275275
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)
276+static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb,
277+ unsigned long len)
282278 {
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;
284299 }
285300
286301 static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
287302 unsigned long len)
288303 {
289− unsigned long i, x;
304+ unsigned long i, j;
305+ u32 x;
306+ int ret;
290307
291308 memset(bitmap, 0, len);
292309 memset_extent_buffer(eb, 0, 0, len);
@@ -297,16 +314,18 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, · 4 unmodified lines
297314
298315 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
299316 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) {
301319 test_msg("Setting all bits failed\n");
302− return -EINVAL;
320+ return ret;
303321 }
304322
305323 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
306324 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) {
308327 test_msg("Clearing all bits failed\n");
309− return -EINVAL;
328+ return ret;
310329 }
311330
312331 /* Straddling pages test */
@@ -316,9 +335,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, · 3 unmodified lines
316335 sizeof(long) * BITS_PER_BYTE);
317336 extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0,
318337 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) {
320340 test_msg("Setting straddling pages failed\n");
321− return -EINVAL;
341+ return ret;
322342 }
323343
324344 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
@@ -328,9 +348,10 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, · 3 unmodified lines
328348 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
329349 extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0,
330350 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) {
332353 test_msg("Clearing straddling pages failed\n");
333− return -EINVAL;
354+ return ret;
334355 }
335356 }
336357
@@ -339,28 +360,22 @@ static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, · 2 unmodified lines
339360 * something repetitive that could miss some hypothetical off-by-n bug.
340361 */
341362 x = 0;
342− for (i = 0; i < len / sizeof(long); i++) {
343− x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffUL;
344− bitmap[i] = x;
345− }
346− write_extent_buffer(eb, bitmap, 0, len);
347−
348− for (i = 0; i < len * BITS_PER_BYTE; i++) {
349− int bit, bit1;
350−
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;
363+ bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
364+ extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
365+ for (i = 0; i < len * BITS_PER_BYTE / 32; i++) {
366+ x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffU;
367+ for (j = 0; j < 32; j++) {
368+ if (x & (1U << j)) {
369+ bitmap_set(bitmap, i * 32 + j, 1);
370+ extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
371+ }
356372 }
373+ }
357374
358− bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
359− i % BITS_PER_BYTE);
360− if (bit1 != bit) {
361− test_msg("Testing bit pattern with offset failed\n");
362− return -EINVAL;
363− }
375+ ret = check_eb_bitmap(bitmap, eb, len);
376+ if (ret) {
377+ test_msg("Random bit pattern failed\n");
378+ return ret;
364379 }
365380
366381 return 0;
fs/btrfs/tests/free-space-tree-tests.c+109−80
@@ -24,20 +24,15 @@ · 23 unmodified lines
2424 #include "../transaction.h"
2525
2626 struct free_space_extent {
27− u64 start, length;
27+ u64 start;
28+ u64 length;
2829 };
2930
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−
3631 static int __check_free_space_extents(struct btrfs_trans_handle *trans,
3732 struct btrfs_fs_info *fs_info,
3833 struct btrfs_block_group_cache *cache,
3934 struct btrfs_path *path,
40− struct free_space_extent *extents,
35+ const struct free_space_extent * const extents,
4136 unsigned int num_extents)
4237 {
4338 struct btrfs_free_space_info *info;
@@ -126,7 +121,7 @@ static int check_free_space_extents(struct btrfs_trans_handle *trans, · 82 unmodified lines
126121 struct btrfs_fs_info *fs_info,
127122 struct btrfs_block_group_cache *cache,
128123 struct btrfs_path *path,
129− struct free_space_extent *extents,
124+ const struct free_space_extent * const extents,
130125 unsigned int num_extents)
131126 {
132127 struct btrfs_free_space_info *info;
@@ -168,9 +163,10 @@ static int check_free_space_extents(struct btrfs_trans_handle *trans, · 35 unmodified lines
168163 static int test_empty_block_group(struct btrfs_trans_handle *trans,
169164 struct btrfs_fs_info *fs_info,
170165 struct btrfs_block_group_cache *cache,
171− struct btrfs_path *path)
166+ struct btrfs_path *path,
167+ u32 alignment)
172168 {
173− struct free_space_extent extents[] = {
169+ const struct free_space_extent extents[] = {
174170 {cache->key.objectid, cache->key.offset},
175171 };
176172
@@ -181,9 +177,10 @@ static int test_empty_block_group(struct btrfs_trans_handle *trans, · 4 unmodified lines
181177 static int test_remove_all(struct btrfs_trans_handle *trans,
182178 struct btrfs_fs_info *fs_info,
183179 struct btrfs_block_group_cache *cache,
184− struct btrfs_path *path)
180+ struct btrfs_path *path,
181+ u32 alignment)
185182 {
186− struct free_space_extent extents[] = {};
183+ const struct free_space_extent extents[] = {};
187184 int ret;
188185
189186 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, · 11 unmodified lines
201198 static int test_remove_beginning(struct btrfs_trans_handle *trans,
202199 struct btrfs_fs_info *fs_info,
203200 struct btrfs_block_group_cache *cache,
204− struct btrfs_path *path)
201+ struct btrfs_path *path,
202+ u32 alignment)
205203 {
206− struct free_space_extent extents[] = {
207− {cache->key.objectid + BITMAP_RANGE,
208− cache->key.offset - BITMAP_RANGE},
204+ const struct free_space_extent extents[] = {
205+ {cache->key.objectid + alignment,
206+ cache->key.offset - alignment},
209207 };
210208 int ret;
211209
212210 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
213− cache->key.objectid, BITMAP_RANGE);
211+ cache->key.objectid, alignment);
214212 if (ret) {
215213 test_msg("Could not remove free space\n");
216214 return ret;
@@ -224,17 +222,18 @@ static int test_remove_beginning(struct btrfs_trans_handle *trans, · 7 unmodified lines
224222 static int test_remove_end(struct btrfs_trans_handle *trans,
225223 struct btrfs_fs_info *fs_info,
226224 struct btrfs_block_group_cache *cache,
227− struct btrfs_path *path)
225+ struct btrfs_path *path,
226+ u32 alignment)
228227 {
229− struct free_space_extent extents[] = {
230− {cache->key.objectid, cache->key.offset - BITMAP_RANGE},
228+ const struct free_space_extent extents[] = {
229+ {cache->key.objectid, cache->key.offset - alignment},
231230 };
232231 int ret;
233232
234233 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
235234 cache->key.objectid +
236− cache->key.offset - BITMAP_RANGE,
237− BITMAP_RANGE);
235+ cache->key.offset - alignment,
236+ alignment);
238237 if (ret) {
239238 test_msg("Could not remove free space\n");
240239 return ret;
@@ -247,18 +246,19 @@ static int test_remove_end(struct btrfs_trans_handle *trans, · 6 unmodified lines
247246 static int test_remove_middle(struct btrfs_trans_handle *trans,
248247 struct btrfs_fs_info *fs_info,
249248 struct btrfs_block_group_cache *cache,
250− struct btrfs_path *path)
249+ struct btrfs_path *path,
250+ u32 alignment)
251251 {
252− struct free_space_extent extents[] = {
253− {cache->key.objectid, BITMAP_RANGE},
254− {cache->key.objectid + 2 * BITMAP_RANGE,
255− cache->key.offset - 2 * BITMAP_RANGE},
252+ const struct free_space_extent extents[] = {
253+ {cache->key.objectid, alignment},
254+ {cache->key.objectid + 2 * alignment,
255+ cache->key.offset - 2 * alignment},
256256 };
257257 int ret;
258258
259259 ret = __remove_from_free_space_tree(trans, fs_info, cache, path,
260− cache->key.objectid + BITMAP_RANGE,
261− BITMAP_RANGE);
260+ cache->key.objectid + alignment,
261+ alignment);
262262 if (ret) {
263263 test_msg("Could not remove free space\n");
264264 return ret;
@@ -271,10 +271,11 @@ static int test_remove_middle(struct btrfs_trans_handle *trans, · 6 unmodified lines
271271 static int test_merge_left(struct btrfs_trans_handle *trans,
272272 struct btrfs_fs_info *fs_info,
273273 struct btrfs_block_group_cache *cache,
274− struct btrfs_path *path)
274+ struct btrfs_path *path,
275+ u32 alignment)
275276 {
276− struct free_space_extent extents[] = {
277− {cache->key.objectid, 2 * BITMAP_RANGE},
277+ const struct free_space_extent extents[] = {
278+ {cache->key.objectid, 2 * alignment},
278279 };
279280 int ret;
280281
@@ -287,15 +288,15 @@ static int test_merge_left(struct btrfs_trans_handle *trans, · 6 unmodified lines
287288 }
288289
289290 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
290− cache->key.objectid, BITMAP_RANGE);
291+ cache->key.objectid, alignment);
291292 if (ret) {
292293 test_msg("Could not add free space\n");
293294 return ret;
294295 }
295296
296297 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
297− cache->key.objectid + BITMAP_RANGE,
298− BITMAP_RANGE);
298+ cache->key.objectid + alignment,
299+ alignment);
299300 if (ret) {
300301 test_msg("Could not add free space\n");
301302 return ret;
@@ -308,10 +309,11 @@ static int test_merge_left(struct btrfs_trans_handle *trans, · 6 unmodified lines
308309 static int test_merge_right(struct btrfs_trans_handle *trans,
309310 struct btrfs_fs_info *fs_info,
310311 struct btrfs_block_group_cache *cache,
311− struct btrfs_path *path)
312+ struct btrfs_path *path,
313+ u32 alignment)
312314 {
313− struct free_space_extent extents[] = {
314− {cache->key.objectid + BITMAP_RANGE, 2 * BITMAP_RANGE},
315+ const struct free_space_extent extents[] = {
316+ {cache->key.objectid + alignment, 2 * alignment},
315317 };
316318 int ret;
317319
@@ -324,16 +326,16 @@ static int test_merge_right(struct btrfs_trans_handle *trans, · 6 unmodified lines
324326 }
325327
326328 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
327− cache->key.objectid + 2 * BITMAP_RANGE,
328− BITMAP_RANGE);
329+ cache->key.objectid + 2 * alignment,
330+ alignment);
329331 if (ret) {
330332 test_msg("Could not add free space\n");
331333 return ret;
332334 }
333335
334336 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
335− cache->key.objectid + BITMAP_RANGE,
336− BITMAP_RANGE);
337+ cache->key.objectid + alignment,
338+ alignment);
337339 if (ret) {
338340 test_msg("Could not add free space\n");
339341 return ret;
@@ -346,10 +348,11 @@ static int test_merge_right(struct btrfs_trans_handle *trans, · 6 unmodified lines
346348 static int test_merge_both(struct btrfs_trans_handle *trans,
347349 struct btrfs_fs_info *fs_info,
348350 struct btrfs_block_group_cache *cache,
349− struct btrfs_path *path)
351+ struct btrfs_path *path,
352+ u32 alignment)
350353 {
351− struct free_space_extent extents[] = {
352− {cache->key.objectid, 3 * BITMAP_RANGE},
354+ const struct free_space_extent extents[] = {
355+ {cache->key.objectid, 3 * alignment},
353356 };
354357 int ret;
355358
@@ -362,23 +365,23 @@ static int test_merge_both(struct btrfs_trans_handle *trans, · 6 unmodified lines
362365 }
363366
364367 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
365− cache->key.objectid, BITMAP_RANGE);
368+ cache->key.objectid, alignment);
366369 if (ret) {
367370 test_msg("Could not add free space\n");
368371 return ret;
369372 }
370373
371374 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
372− cache->key.objectid + 2 * BITMAP_RANGE,
373− BITMAP_RANGE);
375+ cache->key.objectid + 2 * alignment,
376+ alignment);
374377 if (ret) {
375378 test_msg("Could not add free space\n");
376379 return ret;
377380 }
378381
379382 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
380− cache->key.objectid + BITMAP_RANGE,
381− BITMAP_RANGE);
383+ cache->key.objectid + alignment,
384+ alignment);
382385 if (ret) {
383386 test_msg("Could not add free space\n");
384387 return ret;
@@ -391,12 +394,13 @@ static int test_merge_both(struct btrfs_trans_handle *trans, · 6 unmodified lines
391394 static int test_merge_none(struct btrfs_trans_handle *trans,
392395 struct btrfs_fs_info *fs_info,
393396 struct btrfs_block_group_cache *cache,
394− struct btrfs_path *path)
397+ struct btrfs_path *path,
398+ u32 alignment)
395399 {
396− struct free_space_extent extents[] = {
397− {cache->key.objectid, BITMAP_RANGE},
398− {cache->key.objectid + 2 * BITMAP_RANGE, BITMAP_RANGE},
399− {cache->key.objectid + 4 * BITMAP_RANGE, BITMAP_RANGE},
400+ const struct free_space_extent extents[] = {
401+ {cache->key.objectid, alignment},
402+ {cache->key.objectid + 2 * alignment, alignment},
403+ {cache->key.objectid + 4 * alignment, alignment},
400404 };
401405 int ret;
402406
@@ -409,23 +413,23 @@ static int test_merge_none(struct btrfs_trans_handle *trans, · 6 unmodified lines
409413 }
410414
411415 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
412− cache->key.objectid, BITMAP_RANGE);
416+ cache->key.objectid, alignment);
413417 if (ret) {
414418 test_msg("Could not add free space\n");
415419 return ret;
416420 }
417421
418422 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
419− cache->key.objectid + 4 * BITMAP_RANGE,
420− BITMAP_RANGE);
423+ cache->key.objectid + 4 * alignment,
424+ alignment);
421425 if (ret) {
422426 test_msg("Could not add free space\n");
423427 return ret;
424428 }
425429
426430 ret = __add_to_free_space_tree(trans, fs_info, cache, path,
427− cache->key.objectid + 2 * BITMAP_RANGE,
428− BITMAP_RANGE);
431+ cache->key.objectid + 2 * alignment,
432+ alignment);
429433 if (ret) {
430434 test_msg("Could not add free space\n");
431435 return ret;
@@ -438,10 +442,11 @@ static int test_merge_none(struct btrfs_trans_handle *trans, · 6 unmodified lines
438442 typedef int (*test_func_t)(struct btrfs_trans_handle *,
439443 struct btrfs_fs_info *,
440444 struct btrfs_block_group_cache *,
441− struct btrfs_path *);
445+ struct btrfs_path *,
446+ u32 alignment);
442447
443−static int run_test(test_func_t test_func, int bitmaps,
444− u32 sectorsize, u32 nodesize)
448+static int run_test(test_func_t test_func, int bitmaps, u32 sectorsize,
449+ u32 nodesize, u32 alignment)
445450 {
446451 struct btrfs_fs_info *fs_info;
447452 struct btrfs_root *root = NULL;
@@ -480,7 +485,7 @@ static int run_test(test_func_t test_func, int bitmaps, · 32 unmodified lines
480485 btrfs_set_header_nritems(root->node, 0);
481486 root->alloc_bytenr += 2 * nodesize;
482487
483− cache = btrfs_alloc_dummy_block_group(8 * BITMAP_RANGE, sectorsize);
488+ cache = btrfs_alloc_dummy_block_group(8 * alignment, sectorsize);
484489 if (!cache) {
485490 test_msg("Couldn't allocate dummy block group cache\n");
486491 ret = -ENOMEM;
@@ -514,7 +519,7 @@ static int run_test(test_func_t test_func, int bitmaps, · 27 unmodified lines
514519 }
515520 }
516521
517− ret = test_func(&trans, root->fs_info, cache, path);
522+ ret = test_func(&trans, root->fs_info, cache, path, alignment);
518523 if (ret)
519524 goto out;
520525
@@ -539,15 +544,27 @@ out: · 18 unmodified lines
539544 return ret;
540545 }
541546
542−static int run_test_both_formats(test_func_t test_func,
543− u32 sectorsize, u32 nodesize)
547+static int run_test_both_formats(test_func_t test_func, u32 sectorsize,
548+ u32 nodesize, u32 alignment)
544549 {
550+ int test_ret = 0;
545551 int ret;
546552
547− ret = run_test(test_func, 0, sectorsize, nodesize);
548− if (ret)
549− return ret;
550− return run_test(test_func, 1, sectorsize, nodesize);
553+ ret = run_test(test_func, 0, sectorsize, nodesize, alignment);
554+ if (ret) {
555+ test_msg("%pf failed with extents, sectorsize=%u, nodesize=%u, alignment=%u\n",
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;
551568 }
552569
553570 int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize)
@@ -563,18 +580,30 @@ int btrfs_test_free_space_tree(u32 sectorsize, u32 nodesize) · 9 unmodified lines
563580 test_merge_both,
564581 test_merge_none,
565582 };
583+ u32 bitmap_alignment;
584+ int test_ret = 0;
566585 int i;
567586
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+
568593 test_msg("Running free space tree tests\n");
569594 for (i = 0; i < ARRAY_SIZE(tests); i++) {
570− int ret = run_test_both_formats(tests[i], sectorsize,
571− nodesize);
572− if (ret) {
573− test_msg("%pf : sectorsize %u failed\n",
574− tests[i], sectorsize);
575− return ret;
576− }
595+ int ret;
596+
597+ ret = run_test_both_formats(tests[i], sectorsize, nodesize,
598+ sectorsize);
599+ if (ret)
600+ test_ret = ret;
601+
602+ ret = run_test_both_formats(tests[i], sectorsize, nodesize,
603+ bitmap_alignment);
604+ if (ret)
605+ test_ret = ret;
577606 }
578607
579− return 0;
608+ return test_ret;
580609 }
include/uapi/linux/btrfs.h+11−1
@@ -239,7 +239,17 @@ struct btrfs_ioctl_fs_info_args { · 238 unmodified lines
239239 * Used by:
240240 * struct btrfs_ioctl_feature_flags
241241 */
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)
243253
244254 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)
245255 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t