Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'freespace-tree' into for-linus-4.5

Signed-off-by: Chris Mason <clm@fb.com>

+2934 -113
+3 -2
fs/btrfs/Makefile
··· 9 9 export.o tree-log.o free-space-cache.o zlib.o lzo.o \ 10 10 compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ 11 11 reada.o backref.o ulist.o qgroup.o send.o dev-replace.o raid56.o \ 12 - uuid-tree.o props.o hash.o 12 + uuid-tree.o props.o hash.o free-space-tree.o 13 13 14 14 btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o 15 15 btrfs-$(CONFIG_BTRFS_FS_CHECK_INTEGRITY) += check-integrity.o 16 16 17 17 btrfs-$(CONFIG_BTRFS_FS_RUN_SANITY_TESTS) += tests/free-space-tests.o \ 18 18 tests/extent-buffer-tests.o tests/btrfs-tests.o \ 19 - tests/extent-io-tests.o tests/inode-tests.o tests/qgroup-tests.o 19 + tests/extent-io-tests.o tests/inode-tests.o tests/qgroup-tests.o \ 20 + tests/free-space-tree-tests.o
+155 -2
fs/btrfs/ctree.h
··· 96 96 /* for storing items that use the BTRFS_UUID_KEY* types */ 97 97 #define BTRFS_UUID_TREE_OBJECTID 9ULL 98 98 99 + /* tracks free space in block groups. */ 100 + #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL 101 + 99 102 /* for storing balance parameters in the root tree */ 100 103 #define BTRFS_BALANCE_OBJECTID -4ULL 101 104 ··· 503 500 * Compat flags that we support. If any incompat flags are set other than the 504 501 * ones specified below then we will fail to mount 505 502 */ 503 + #define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0) 504 + 506 505 #define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0) 507 506 #define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1) 508 507 #define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2) ··· 531 526 #define BTRFS_FEATURE_COMPAT_SUPP 0ULL 532 527 #define BTRFS_FEATURE_COMPAT_SAFE_SET 0ULL 533 528 #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL 534 - #define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL 529 + 530 + #define BTRFS_FEATURE_COMPAT_RO_SUPP \ 531 + (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) 532 + 535 533 #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL 536 534 #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL 537 535 ··· 1096 1088 __le64 flags; 1097 1089 } __attribute__ ((__packed__)); 1098 1090 1091 + struct btrfs_free_space_info { 1092 + __le32 extent_count; 1093 + __le32 flags; 1094 + } __attribute__ ((__packed__)); 1095 + 1096 + #define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0) 1097 + 1099 1098 #define BTRFS_QGROUP_LEVEL_SHIFT 48 1100 1099 static inline u64 btrfs_qgroup_level(u64 qgroupid) 1101 1100 { ··· 1311 1296 atomic_t count; 1312 1297 }; 1313 1298 1299 + /* Once caching_thread() finds this much free space, it will wake up waiters. */ 1300 + #define CACHING_CTL_WAKE_UP (1024 * 1024 * 2) 1301 + 1314 1302 struct btrfs_io_ctl { 1315 1303 void *cur, *orig; 1316 1304 struct page *page; ··· 1339 1321 u64 delalloc_bytes; 1340 1322 u64 bytes_super; 1341 1323 u64 flags; 1342 - u64 sectorsize; 1343 1324 u64 cache_generation; 1325 + u32 sectorsize; 1326 + 1327 + /* 1328 + * If the free space extent count exceeds this number, convert the block 1329 + * group to bitmaps. 1330 + */ 1331 + u32 bitmap_high_thresh; 1332 + 1333 + /* 1334 + * If the free space extent count drops below this number, convert the 1335 + * block group back to extents. 1336 + */ 1337 + u32 bitmap_low_thresh; 1344 1338 1345 1339 /* 1346 1340 * It is just used for the delayed data space allocation because ··· 1408 1378 struct list_head io_list; 1409 1379 1410 1380 struct btrfs_io_ctl io_ctl; 1381 + 1382 + /* Lock for free space tree operations. */ 1383 + struct mutex free_space_lock; 1384 + 1385 + /* 1386 + * Does the block group need to be added to the free space tree? 1387 + * Protected by free_space_lock. 1388 + */ 1389 + int needs_free_space; 1411 1390 }; 1412 1391 1413 1392 /* delayed seq elem */ ··· 1468 1429 struct btrfs_root *csum_root; 1469 1430 struct btrfs_root *quota_root; 1470 1431 struct btrfs_root *uuid_root; 1432 + struct btrfs_root *free_space_root; 1471 1433 1472 1434 /* the log root tree is a directory of all the other log roots */ 1473 1435 struct btrfs_root *log_root_tree; ··· 2132 2092 */ 2133 2093 #define BTRFS_BLOCK_GROUP_ITEM_KEY 192 2134 2094 2095 + /* 2096 + * Every block group is represented in the free space tree by a free space info 2097 + * item, which stores some accounting information. It is keyed on 2098 + * (block_group_start, FREE_SPACE_INFO, block_group_length). 2099 + */ 2100 + #define BTRFS_FREE_SPACE_INFO_KEY 198 2101 + 2102 + /* 2103 + * A free space extent tracks an extent of space that is free in a block group. 2104 + * It is keyed on (start, FREE_SPACE_EXTENT, length). 2105 + */ 2106 + #define BTRFS_FREE_SPACE_EXTENT_KEY 199 2107 + 2108 + /* 2109 + * When a block group becomes very fragmented, we convert it to use bitmaps 2110 + * instead of extents. A free space bitmap is keyed on 2111 + * (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with 2112 + * (length / sectorsize) bits. 2113 + */ 2114 + #define BTRFS_FREE_SPACE_BITMAP_KEY 200 2115 + 2135 2116 #define BTRFS_DEV_EXTENT_KEY 204 2136 2117 #define BTRFS_DEV_ITEM_KEY 216 2137 2118 #define BTRFS_CHUNK_ITEM_KEY 228 ··· 2245 2184 #define BTRFS_MOUNT_RESCAN_UUID_TREE (1 << 23) 2246 2185 #define BTRFS_MOUNT_FRAGMENT_DATA (1 << 24) 2247 2186 #define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25) 2187 + #define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26) 2248 2188 2249 2189 #define BTRFS_DEFAULT_COMMIT_INTERVAL (30) 2250 2190 #define BTRFS_DEFAULT_MAX_INLINE (8192) ··· 2567 2505 struct btrfs_block_group_item, flags, 64); 2568 2506 BTRFS_SETGET_STACK_FUNCS(block_group_flags, 2569 2507 struct btrfs_block_group_item, flags, 64); 2508 + 2509 + /* struct btrfs_free_space_info */ 2510 + BTRFS_SETGET_FUNCS(free_space_extent_count, struct btrfs_free_space_info, 2511 + extent_count, 32); 2512 + BTRFS_SETGET_FUNCS(free_space_flags, struct btrfs_free_space_info, flags, 32); 2570 2513 2571 2514 /* struct btrfs_inode_ref */ 2572 2515 BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16); ··· 3640 3573 void check_system_chunk(struct btrfs_trans_handle *trans, 3641 3574 struct btrfs_root *root, 3642 3575 const u64 type); 3576 + u64 add_new_free_space(struct btrfs_block_group_cache *block_group, 3577 + struct btrfs_fs_info *info, u64 start, u64 end); 3578 + 3643 3579 /* ctree.c */ 3644 3580 int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key, 3645 3581 int level, int *slot); ··· 3807 3737 kfree(fs_info->csum_root); 3808 3738 kfree(fs_info->quota_root); 3809 3739 kfree(fs_info->uuid_root); 3740 + kfree(fs_info->free_space_root); 3810 3741 kfree(fs_info->super_copy); 3811 3742 kfree(fs_info->super_for_commit); 3812 3743 security_free_mnt_opts(&fs_info->security_opts); ··· 4318 4247 } 4319 4248 } 4320 4249 4250 + #define btrfs_clear_fs_incompat(__fs_info, opt) \ 4251 + __btrfs_clear_fs_incompat((__fs_info), BTRFS_FEATURE_INCOMPAT_##opt) 4252 + 4253 + static inline void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info, 4254 + u64 flag) 4255 + { 4256 + struct btrfs_super_block *disk_super; 4257 + u64 features; 4258 + 4259 + disk_super = fs_info->super_copy; 4260 + features = btrfs_super_incompat_flags(disk_super); 4261 + if (features & flag) { 4262 + spin_lock(&fs_info->super_lock); 4263 + features = btrfs_super_incompat_flags(disk_super); 4264 + if (features & flag) { 4265 + features &= ~flag; 4266 + btrfs_set_super_incompat_flags(disk_super, features); 4267 + btrfs_info(fs_info, "clearing %llu feature flag", 4268 + flag); 4269 + } 4270 + spin_unlock(&fs_info->super_lock); 4271 + } 4272 + } 4273 + 4321 4274 #define btrfs_fs_incompat(fs_info, opt) \ 4322 4275 __btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt) 4323 4276 ··· 4350 4255 struct btrfs_super_block *disk_super; 4351 4256 disk_super = fs_info->super_copy; 4352 4257 return !!(btrfs_super_incompat_flags(disk_super) & flag); 4258 + } 4259 + 4260 + #define btrfs_set_fs_compat_ro(__fs_info, opt) \ 4261 + __btrfs_set_fs_compat_ro((__fs_info), BTRFS_FEATURE_COMPAT_RO_##opt) 4262 + 4263 + static inline void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info, 4264 + u64 flag) 4265 + { 4266 + struct btrfs_super_block *disk_super; 4267 + u64 features; 4268 + 4269 + disk_super = fs_info->super_copy; 4270 + features = btrfs_super_compat_ro_flags(disk_super); 4271 + if (!(features & flag)) { 4272 + spin_lock(&fs_info->super_lock); 4273 + features = btrfs_super_compat_ro_flags(disk_super); 4274 + if (!(features & flag)) { 4275 + features |= flag; 4276 + btrfs_set_super_compat_ro_flags(disk_super, features); 4277 + btrfs_info(fs_info, "setting %llu ro feature flag", 4278 + flag); 4279 + } 4280 + spin_unlock(&fs_info->super_lock); 4281 + } 4282 + } 4283 + 4284 + #define btrfs_clear_fs_compat_ro(__fs_info, opt) \ 4285 + __btrfs_clear_fs_compat_ro((__fs_info), BTRFS_FEATURE_COMPAT_RO_##opt) 4286 + 4287 + static inline void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info, 4288 + u64 flag) 4289 + { 4290 + struct btrfs_super_block *disk_super; 4291 + u64 features; 4292 + 4293 + disk_super = fs_info->super_copy; 4294 + features = btrfs_super_compat_ro_flags(disk_super); 4295 + if (features & flag) { 4296 + spin_lock(&fs_info->super_lock); 4297 + features = btrfs_super_compat_ro_flags(disk_super); 4298 + if (features & flag) { 4299 + features &= ~flag; 4300 + btrfs_set_super_compat_ro_flags(disk_super, features); 4301 + btrfs_info(fs_info, "clearing %llu ro feature flag", 4302 + flag); 4303 + } 4304 + spin_unlock(&fs_info->super_lock); 4305 + } 4306 + } 4307 + 4308 + #define btrfs_fs_compat_ro(fs_info, opt) \ 4309 + __btrfs_fs_compat_ro((fs_info), BTRFS_FEATURE_COMPAT_RO_##opt) 4310 + 4311 + static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag) 4312 + { 4313 + struct btrfs_super_block *disk_super; 4314 + disk_super = fs_info->super_copy; 4315 + return !!(btrfs_super_compat_ro_flags(disk_super) & flag); 4353 4316 } 4354 4317 4355 4318 /*
+38
fs/btrfs/disk-io.c
··· 42 42 #include "locking.h" 43 43 #include "tree-log.h" 44 44 #include "free-space-cache.h" 45 + #include "free-space-tree.h" 45 46 #include "inode-map.h" 46 47 #include "check-integrity.h" 47 48 #include "rcu-string.h" ··· 1651 1650 if (location->objectid == BTRFS_UUID_TREE_OBJECTID) 1652 1651 return fs_info->uuid_root ? fs_info->uuid_root : 1653 1652 ERR_PTR(-ENOENT); 1653 + if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID) 1654 + return fs_info->free_space_root ? fs_info->free_space_root : 1655 + ERR_PTR(-ENOENT); 1654 1656 again: 1655 1657 root = btrfs_lookup_fs_root(fs_info, location->objectid); 1656 1658 if (root) { ··· 2152 2148 free_root_extent_buffers(info->uuid_root); 2153 2149 if (chunk_root) 2154 2150 free_root_extent_buffers(info->chunk_root); 2151 + free_root_extent_buffers(info->free_space_root); 2155 2152 } 2156 2153 2157 2154 void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info) ··· 2451 2446 } else { 2452 2447 set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state); 2453 2448 fs_info->uuid_root = root; 2449 + } 2450 + 2451 + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 2452 + location.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID; 2453 + root = btrfs_read_tree_root(tree_root, &location); 2454 + if (IS_ERR(root)) 2455 + return PTR_ERR(root); 2456 + set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state); 2457 + fs_info->free_space_root = root; 2454 2458 } 2455 2459 2456 2460 return 0; ··· 3089 3075 } 3090 3076 3091 3077 btrfs_qgroup_rescan_resume(fs_info); 3078 + 3079 + if (btrfs_test_opt(tree_root, CLEAR_CACHE) && 3080 + btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 3081 + pr_info("BTRFS: clearing free space tree\n"); 3082 + ret = btrfs_clear_free_space_tree(fs_info); 3083 + if (ret) { 3084 + pr_warn("BTRFS: failed to clear free space tree %d\n", 3085 + ret); 3086 + close_ctree(tree_root); 3087 + return ret; 3088 + } 3089 + } 3090 + 3091 + if (btrfs_test_opt(tree_root, FREE_SPACE_TREE) && 3092 + !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) { 3093 + pr_info("BTRFS: creating free space tree\n"); 3094 + ret = btrfs_create_free_space_tree(fs_info); 3095 + if (ret) { 3096 + pr_warn("BTRFS: failed to create free space tree %d\n", 3097 + ret); 3098 + close_ctree(tree_root); 3099 + return ret; 3100 + } 3101 + } 3092 3102 3093 3103 if (!fs_info->uuid_root) { 3094 3104 pr_info("BTRFS: creating UUID tree\n");
+71 -30
fs/btrfs/extent-tree.c
··· 33 33 #include "raid56.h" 34 34 #include "locking.h" 35 35 #include "free-space-cache.h" 36 + #include "free-space-tree.h" 36 37 #include "math.h" 37 38 #include "sysfs.h" 38 39 #include "qgroup.h" ··· 358 357 * we need to check the pinned_extents for any extents that can't be used yet 359 358 * since their free space will be released as soon as the transaction commits. 360 359 */ 361 - static u64 add_new_free_space(struct btrfs_block_group_cache *block_group, 362 - struct btrfs_fs_info *info, u64 start, u64 end) 360 + u64 add_new_free_space(struct btrfs_block_group_cache *block_group, 361 + struct btrfs_fs_info *info, u64 start, u64 end) 363 362 { 364 363 u64 extent_start, extent_end, size, total_added = 0; 365 364 int ret; ··· 396 395 return total_added; 397 396 } 398 397 399 - static noinline void caching_thread(struct btrfs_work *work) 398 + static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl) 400 399 { 401 400 struct btrfs_block_group_cache *block_group; 402 401 struct btrfs_fs_info *fs_info; 403 - struct btrfs_caching_control *caching_ctl; 404 402 struct btrfs_root *extent_root; 405 403 struct btrfs_path *path; 406 404 struct extent_buffer *leaf; ··· 407 407 u64 total_found = 0; 408 408 u64 last = 0; 409 409 u32 nritems; 410 - int ret = -ENOMEM; 410 + int ret; 411 411 bool wakeup = true; 412 412 413 - caching_ctl = container_of(work, struct btrfs_caching_control, work); 414 413 block_group = caching_ctl->block_group; 415 414 fs_info = block_group->fs_info; 416 415 extent_root = fs_info->extent_root; 417 416 418 417 path = btrfs_alloc_path(); 419 418 if (!path) 420 - goto out; 419 + return -ENOMEM; 421 420 422 421 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET); 423 422 ··· 442 443 key.objectid = last; 443 444 key.offset = 0; 444 445 key.type = BTRFS_EXTENT_ITEM_KEY; 445 - again: 446 - mutex_lock(&caching_ctl->mutex); 447 - /* need to make sure the commit_root doesn't disappear */ 448 - down_read(&fs_info->commit_root_sem); 449 446 450 447 next: 451 448 ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); 452 449 if (ret < 0) 453 - goto err; 450 + goto out; 454 451 455 452 leaf = path->nodes[0]; 456 453 nritems = btrfs_header_nritems(leaf); ··· 472 477 up_read(&fs_info->commit_root_sem); 473 478 mutex_unlock(&caching_ctl->mutex); 474 479 cond_resched(); 475 - goto again; 480 + mutex_lock(&caching_ctl->mutex); 481 + down_read(&fs_info->commit_root_sem); 482 + goto next; 476 483 } 477 484 478 485 ret = btrfs_next_leaf(extent_root, path); 479 486 if (ret < 0) 480 - goto err; 487 + goto out; 481 488 if (ret) 482 489 break; 483 490 leaf = path->nodes[0]; ··· 518 521 else 519 522 last = key.objectid + key.offset; 520 523 521 - if (total_found > (1024 * 1024 * 2)) { 524 + if (total_found > CACHING_CTL_WAKE_UP) { 522 525 total_found = 0; 523 526 if (wakeup) 524 527 wake_up(&caching_ctl->wait); ··· 531 534 total_found += add_new_free_space(block_group, fs_info, last, 532 535 block_group->key.objectid + 533 536 block_group->key.offset); 537 + caching_ctl->progress = (u64)-1; 538 + 539 + out: 540 + btrfs_free_path(path); 541 + return ret; 542 + } 543 + 544 + static noinline void caching_thread(struct btrfs_work *work) 545 + { 546 + struct btrfs_block_group_cache *block_group; 547 + struct btrfs_fs_info *fs_info; 548 + struct btrfs_caching_control *caching_ctl; 549 + int ret; 550 + 551 + caching_ctl = container_of(work, struct btrfs_caching_control, work); 552 + block_group = caching_ctl->block_group; 553 + fs_info = block_group->fs_info; 554 + 555 + mutex_lock(&caching_ctl->mutex); 556 + down_read(&fs_info->commit_root_sem); 557 + 558 + if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) 559 + ret = load_free_space_tree(caching_ctl); 560 + else 561 + ret = load_extent_tree_free(caching_ctl); 562 + 534 563 spin_lock(&block_group->lock); 535 564 block_group->caching_ctl = NULL; 536 - block_group->cached = BTRFS_CACHE_FINISHED; 565 + block_group->cached = ret ? BTRFS_CACHE_ERROR : BTRFS_CACHE_FINISHED; 537 566 spin_unlock(&block_group->lock); 538 567 539 568 #ifdef CONFIG_BTRFS_DEBUG ··· 578 555 #endif 579 556 580 557 caching_ctl->progress = (u64)-1; 581 - err: 582 - btrfs_free_path(path); 558 + 583 559 up_read(&fs_info->commit_root_sem); 584 - 585 - free_excluded_extents(extent_root, block_group); 586 - 560 + free_excluded_extents(fs_info->extent_root, block_group); 587 561 mutex_unlock(&caching_ctl->mutex); 588 - out: 589 - if (ret) { 590 - spin_lock(&block_group->lock); 591 - block_group->caching_ctl = NULL; 592 - block_group->cached = BTRFS_CACHE_ERROR; 593 - spin_unlock(&block_group->lock); 594 - } 562 + 595 563 wake_up(&caching_ctl->wait); 596 564 597 565 put_caching_control(caching_ctl); ··· 694 680 } 695 681 } else { 696 682 /* 697 - * We are not going to do the fast caching, set cached to the 698 - * appropriate value and wakeup any waiters. 683 + * We're either using the free space tree or no caching at all. 684 + * Set cached to the appropriate value and wakeup any waiters. 699 685 */ 700 686 spin_lock(&cache->lock); 701 687 if (load_cache_only) { ··· 6675 6661 } 6676 6662 } 6677 6663 6664 + ret = add_to_free_space_tree(trans, root->fs_info, bytenr, 6665 + num_bytes); 6666 + if (ret) { 6667 + btrfs_abort_transaction(trans, extent_root, ret); 6668 + goto out; 6669 + } 6670 + 6678 6671 ret = update_block_group(trans, root, bytenr, num_bytes, 0); 6679 6672 if (ret) { 6680 6673 btrfs_abort_transaction(trans, extent_root, ret); ··· 7693 7672 btrfs_mark_buffer_dirty(path->nodes[0]); 7694 7673 btrfs_free_path(path); 7695 7674 7675 + ret = remove_from_free_space_tree(trans, fs_info, ins->objectid, 7676 + ins->offset); 7677 + if (ret) 7678 + return ret; 7679 + 7696 7680 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1); 7697 7681 if (ret) { /* -ENOENT, logic error */ 7698 7682 btrfs_err(fs_info, "update block group failed for %llu %llu", ··· 7777 7751 7778 7752 btrfs_mark_buffer_dirty(leaf); 7779 7753 btrfs_free_path(path); 7754 + 7755 + ret = remove_from_free_space_tree(trans, fs_info, ins->objectid, 7756 + num_bytes); 7757 + if (ret) 7758 + return ret; 7780 7759 7781 7760 ret = update_block_group(trans, root, ins->objectid, root->nodesize, 7782 7761 1); ··· 9687 9656 cache->full_stripe_len = btrfs_full_stripe_len(root, 9688 9657 &root->fs_info->mapping_tree, 9689 9658 start); 9659 + set_free_space_tree_thresholds(cache); 9660 + 9690 9661 atomic_set(&cache->count, 1); 9691 9662 spin_lock_init(&cache->lock); 9692 9663 init_rwsem(&cache->data_rwsem); ··· 9700 9667 INIT_LIST_HEAD(&cache->io_list); 9701 9668 btrfs_init_free_space_ctl(cache); 9702 9669 atomic_set(&cache->trimming, 0); 9670 + mutex_init(&cache->free_space_lock); 9703 9671 9704 9672 return cache; 9705 9673 } ··· 9911 9877 key.objectid, key.offset); 9912 9878 if (ret) 9913 9879 btrfs_abort_transaction(trans, extent_root, ret); 9880 + add_block_group_free_space(trans, root->fs_info, block_group); 9881 + /* already aborted the transaction if it failed. */ 9914 9882 next: 9915 9883 list_del_init(&block_group->bg_list); 9916 9884 } ··· 9943 9907 cache->flags = type; 9944 9908 cache->last_byte_to_unpin = (u64)-1; 9945 9909 cache->cached = BTRFS_CACHE_FINISHED; 9910 + cache->needs_free_space = 1; 9946 9911 ret = exclude_super_stripes(root, cache); 9947 9912 if (ret) { 9948 9913 /* ··· 10313 10276 } 10314 10277 10315 10278 unlock_chunks(root); 10279 + 10280 + ret = remove_block_group_free_space(trans, root->fs_info, block_group); 10281 + if (ret) 10282 + goto out; 10316 10283 10317 10284 btrfs_put_block_group(block_group); 10318 10285 btrfs_put_block_group(block_group);
+170 -13
fs/btrfs/extent_io.c
··· 4797 4797 return new; 4798 4798 } 4799 4799 4800 - struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, 4801 - u64 start) 4800 + struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, 4801 + u64 start, unsigned long len) 4802 4802 { 4803 4803 struct extent_buffer *eb; 4804 - unsigned long len; 4805 4804 unsigned long num_pages; 4806 4805 unsigned long i; 4807 4806 4808 - if (!fs_info) { 4809 - /* 4810 - * Called only from tests that don't always have a fs_info 4811 - * available, but we know that nodesize is 4096 4812 - */ 4813 - len = 4096; 4814 - } else { 4815 - len = fs_info->tree_root->nodesize; 4816 - } 4817 - num_pages = num_extent_pages(0, len); 4807 + num_pages = num_extent_pages(start, len); 4818 4808 4819 4809 eb = __alloc_extent_buffer(fs_info, start, len); 4820 4810 if (!eb) ··· 4825 4835 __free_page(eb->pages[i - 1]); 4826 4836 __free_extent_buffer(eb); 4827 4837 return NULL; 4838 + } 4839 + 4840 + struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, 4841 + u64 start) 4842 + { 4843 + unsigned long len; 4844 + 4845 + if (!fs_info) { 4846 + /* 4847 + * Called only from tests that don't always have a fs_info 4848 + * available, but we know that nodesize is 4096 4849 + */ 4850 + len = 4096; 4851 + } else { 4852 + len = fs_info->tree_root->nodesize; 4853 + } 4854 + 4855 + return __alloc_dummy_extent_buffer(fs_info, start, len); 4828 4856 } 4829 4857 4830 4858 static void check_buffer_tree_ref(struct extent_buffer *eb) ··· 5599 5591 len -= cur; 5600 5592 offset = 0; 5601 5593 i++; 5594 + } 5595 + } 5596 + 5597 + /* 5598 + * The extent buffer bitmap operations are done with byte granularity because 5599 + * bitmap items are not guaranteed to be aligned to a word and therefore a 5600 + * single word in a bitmap may straddle two pages in the extent buffer. 5601 + */ 5602 + #define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE) 5603 + #define BYTE_MASK ((1 << BITS_PER_BYTE) - 1) 5604 + #define BITMAP_FIRST_BYTE_MASK(start) \ 5605 + ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK) 5606 + #define BITMAP_LAST_BYTE_MASK(nbits) \ 5607 + (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1))) 5608 + 5609 + /* 5610 + * eb_bitmap_offset() - calculate the page and offset of the byte containing the 5611 + * given bit number 5612 + * @eb: the extent buffer 5613 + * @start: offset of the bitmap item in the extent buffer 5614 + * @nr: bit number 5615 + * @page_index: return index of the page in the extent buffer that contains the 5616 + * given bit number 5617 + * @page_offset: return offset into the page given by page_index 5618 + * 5619 + * This helper hides the ugliness of finding the byte in an extent buffer which 5620 + * contains a given bit. 5621 + */ 5622 + static inline void eb_bitmap_offset(struct extent_buffer *eb, 5623 + unsigned long start, unsigned long nr, 5624 + unsigned long *page_index, 5625 + size_t *page_offset) 5626 + { 5627 + size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1); 5628 + size_t byte_offset = BIT_BYTE(nr); 5629 + size_t offset; 5630 + 5631 + /* 5632 + * The byte we want is the offset of the extent buffer + the offset of 5633 + * the bitmap item in the extent buffer + the offset of the byte in the 5634 + * bitmap item. 5635 + */ 5636 + offset = start_offset + start + byte_offset; 5637 + 5638 + *page_index = offset >> PAGE_CACHE_SHIFT; 5639 + *page_offset = offset & (PAGE_CACHE_SIZE - 1); 5640 + } 5641 + 5642 + /** 5643 + * extent_buffer_test_bit - determine whether a bit in a bitmap item is set 5644 + * @eb: the extent buffer 5645 + * @start: offset of the bitmap item in the extent buffer 5646 + * @nr: bit number to test 5647 + */ 5648 + int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, 5649 + unsigned long nr) 5650 + { 5651 + char *kaddr; 5652 + struct page *page; 5653 + unsigned long i; 5654 + size_t offset; 5655 + 5656 + eb_bitmap_offset(eb, start, nr, &i, &offset); 5657 + page = eb->pages[i]; 5658 + WARN_ON(!PageUptodate(page)); 5659 + kaddr = page_address(page); 5660 + return 1U & (kaddr[offset] >> (nr & (BITS_PER_BYTE - 1))); 5661 + } 5662 + 5663 + /** 5664 + * extent_buffer_bitmap_set - set an area of a bitmap 5665 + * @eb: the extent buffer 5666 + * @start: offset of the bitmap item in the extent buffer 5667 + * @pos: bit number of the first bit 5668 + * @len: number of bits to set 5669 + */ 5670 + void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, 5671 + unsigned long pos, unsigned long len) 5672 + { 5673 + char *kaddr; 5674 + struct page *page; 5675 + unsigned long i; 5676 + size_t offset; 5677 + const unsigned int size = pos + len; 5678 + int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5679 + unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos); 5680 + 5681 + eb_bitmap_offset(eb, start, pos, &i, &offset); 5682 + page = eb->pages[i]; 5683 + WARN_ON(!PageUptodate(page)); 5684 + kaddr = page_address(page); 5685 + 5686 + while (len >= bits_to_set) { 5687 + kaddr[offset] |= mask_to_set; 5688 + len -= bits_to_set; 5689 + bits_to_set = BITS_PER_BYTE; 5690 + mask_to_set = ~0U; 5691 + if (++offset >= PAGE_CACHE_SIZE && len > 0) { 5692 + offset = 0; 5693 + page = eb->pages[++i]; 5694 + WARN_ON(!PageUptodate(page)); 5695 + kaddr = page_address(page); 5696 + } 5697 + } 5698 + if (len) { 5699 + mask_to_set &= BITMAP_LAST_BYTE_MASK(size); 5700 + kaddr[offset] |= mask_to_set; 5701 + } 5702 + } 5703 + 5704 + 5705 + /** 5706 + * extent_buffer_bitmap_clear - clear an area of a bitmap 5707 + * @eb: the extent buffer 5708 + * @start: offset of the bitmap item in the extent buffer 5709 + * @pos: bit number of the first bit 5710 + * @len: number of bits to clear 5711 + */ 5712 + void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, 5713 + unsigned long pos, unsigned long len) 5714 + { 5715 + char *kaddr; 5716 + struct page *page; 5717 + unsigned long i; 5718 + size_t offset; 5719 + const unsigned int size = pos + len; 5720 + int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE); 5721 + unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos); 5722 + 5723 + eb_bitmap_offset(eb, start, pos, &i, &offset); 5724 + page = eb->pages[i]; 5725 + WARN_ON(!PageUptodate(page)); 5726 + kaddr = page_address(page); 5727 + 5728 + while (len >= bits_to_clear) { 5729 + kaddr[offset] &= ~mask_to_clear; 5730 + len -= bits_to_clear; 5731 + bits_to_clear = BITS_PER_BYTE; 5732 + mask_to_clear = ~0U; 5733 + if (++offset >= PAGE_CACHE_SIZE && len > 0) { 5734 + offset = 0; 5735 + page = eb->pages[++i]; 5736 + WARN_ON(!PageUptodate(page)); 5737 + kaddr = page_address(page); 5738 + } 5739 + } 5740 + if (len) { 5741 + mask_to_clear &= BITMAP_LAST_BYTE_MASK(size); 5742 + kaddr[offset] &= ~mask_to_clear; 5602 5743 } 5603 5744 } 5604 5745
+9 -1
fs/btrfs/extent_io.h
··· 282 282 283 283 struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info, 284 284 u64 start); 285 + struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, 286 + u64 start, unsigned long len); 285 287 struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info, 286 - u64 start); 288 + u64 start); 287 289 struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src); 288 290 struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info, 289 291 u64 start); ··· 330 328 unsigned long src_offset, unsigned long len); 331 329 void memset_extent_buffer(struct extent_buffer *eb, char c, 332 330 unsigned long start, unsigned long len); 331 + int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start, 332 + unsigned long pos); 333 + void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start, 334 + unsigned long pos, unsigned long len); 335 + void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start, 336 + unsigned long pos, unsigned long len); 333 337 void clear_extent_buffer_dirty(struct extent_buffer *eb); 334 338 int set_extent_buffer_dirty(struct extent_buffer *eb); 335 339 int set_extent_buffer_uptodate(struct extent_buffer *eb);
+1584
fs/btrfs/free-space-tree.c
··· 1 + /* 2 + * Copyright (C) 2015 Facebook. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public 6 + * License v2 as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 + * General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public 14 + * License along with this program; if not, write to the 15 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 + * Boston, MA 021110-1307, USA. 17 + */ 18 + 19 + #include <linux/kernel.h> 20 + #include <linux/vmalloc.h> 21 + #include "ctree.h" 22 + #include "disk-io.h" 23 + #include "locking.h" 24 + #include "free-space-tree.h" 25 + #include "transaction.h" 26 + 27 + static int __add_block_group_free_space(struct btrfs_trans_handle *trans, 28 + struct btrfs_fs_info *fs_info, 29 + struct btrfs_block_group_cache *block_group, 30 + struct btrfs_path *path); 31 + 32 + void set_free_space_tree_thresholds(struct btrfs_block_group_cache *cache) 33 + { 34 + u32 bitmap_range; 35 + size_t bitmap_size; 36 + u64 num_bitmaps, total_bitmap_size; 37 + 38 + /* 39 + * We convert to bitmaps when the disk space required for using extents 40 + * exceeds that required for using bitmaps. 41 + */ 42 + bitmap_range = cache->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS; 43 + num_bitmaps = div_u64(cache->key.offset + bitmap_range - 1, 44 + bitmap_range); 45 + bitmap_size = sizeof(struct btrfs_item) + BTRFS_FREE_SPACE_BITMAP_SIZE; 46 + total_bitmap_size = num_bitmaps * bitmap_size; 47 + cache->bitmap_high_thresh = div_u64(total_bitmap_size, 48 + sizeof(struct btrfs_item)); 49 + 50 + /* 51 + * We allow for a small buffer between the high threshold and low 52 + * threshold to avoid thrashing back and forth between the two formats. 53 + */ 54 + if (cache->bitmap_high_thresh > 100) 55 + cache->bitmap_low_thresh = cache->bitmap_high_thresh - 100; 56 + else 57 + cache->bitmap_low_thresh = 0; 58 + } 59 + 60 + static int add_new_free_space_info(struct btrfs_trans_handle *trans, 61 + struct btrfs_fs_info *fs_info, 62 + struct btrfs_block_group_cache *block_group, 63 + struct btrfs_path *path) 64 + { 65 + struct btrfs_root *root = fs_info->free_space_root; 66 + struct btrfs_free_space_info *info; 67 + struct btrfs_key key; 68 + struct extent_buffer *leaf; 69 + int ret; 70 + 71 + key.objectid = block_group->key.objectid; 72 + key.type = BTRFS_FREE_SPACE_INFO_KEY; 73 + key.offset = block_group->key.offset; 74 + 75 + ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*info)); 76 + if (ret) 77 + goto out; 78 + 79 + leaf = path->nodes[0]; 80 + info = btrfs_item_ptr(leaf, path->slots[0], 81 + struct btrfs_free_space_info); 82 + btrfs_set_free_space_extent_count(leaf, info, 0); 83 + btrfs_set_free_space_flags(leaf, info, 0); 84 + btrfs_mark_buffer_dirty(leaf); 85 + 86 + ret = 0; 87 + out: 88 + btrfs_release_path(path); 89 + return ret; 90 + } 91 + 92 + struct btrfs_free_space_info * 93 + search_free_space_info(struct btrfs_trans_handle *trans, 94 + struct btrfs_fs_info *fs_info, 95 + struct btrfs_block_group_cache *block_group, 96 + struct btrfs_path *path, int cow) 97 + { 98 + struct btrfs_root *root = fs_info->free_space_root; 99 + struct btrfs_key key; 100 + int ret; 101 + 102 + key.objectid = block_group->key.objectid; 103 + key.type = BTRFS_FREE_SPACE_INFO_KEY; 104 + key.offset = block_group->key.offset; 105 + 106 + ret = btrfs_search_slot(trans, root, &key, path, 0, cow); 107 + if (ret < 0) 108 + return ERR_PTR(ret); 109 + if (ret != 0) { 110 + btrfs_warn(fs_info, "missing free space info for %llu\n", 111 + block_group->key.objectid); 112 + ASSERT(0); 113 + return ERR_PTR(-ENOENT); 114 + } 115 + 116 + return btrfs_item_ptr(path->nodes[0], path->slots[0], 117 + struct btrfs_free_space_info); 118 + } 119 + 120 + /* 121 + * btrfs_search_slot() but we're looking for the greatest key less than the 122 + * passed key. 123 + */ 124 + static int btrfs_search_prev_slot(struct btrfs_trans_handle *trans, 125 + struct btrfs_root *root, 126 + struct btrfs_key *key, struct btrfs_path *p, 127 + int ins_len, int cow) 128 + { 129 + int ret; 130 + 131 + ret = btrfs_search_slot(trans, root, key, p, ins_len, cow); 132 + if (ret < 0) 133 + return ret; 134 + 135 + if (ret == 0) { 136 + ASSERT(0); 137 + return -EIO; 138 + } 139 + 140 + if (p->slots[0] == 0) { 141 + ASSERT(0); 142 + return -EIO; 143 + } 144 + p->slots[0]--; 145 + 146 + return 0; 147 + } 148 + 149 + static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize) 150 + { 151 + return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE); 152 + } 153 + 154 + static unsigned long *alloc_bitmap(u32 bitmap_size) 155 + { 156 + return __vmalloc(bitmap_size, GFP_NOFS | __GFP_HIGHMEM | __GFP_ZERO, 157 + PAGE_KERNEL); 158 + } 159 + 160 + int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, 161 + struct btrfs_fs_info *fs_info, 162 + struct btrfs_block_group_cache *block_group, 163 + struct btrfs_path *path) 164 + { 165 + struct btrfs_root *root = fs_info->free_space_root; 166 + struct btrfs_free_space_info *info; 167 + struct btrfs_key key, found_key; 168 + struct extent_buffer *leaf; 169 + unsigned long *bitmap; 170 + char *bitmap_cursor; 171 + u64 start, end; 172 + u64 bitmap_range, i; 173 + u32 bitmap_size, flags, expected_extent_count; 174 + u32 extent_count = 0; 175 + int done = 0, nr; 176 + int ret; 177 + 178 + bitmap_size = free_space_bitmap_size(block_group->key.offset, 179 + block_group->sectorsize); 180 + bitmap = alloc_bitmap(bitmap_size); 181 + if (!bitmap) { 182 + ret = -ENOMEM; 183 + goto out; 184 + } 185 + 186 + start = block_group->key.objectid; 187 + end = block_group->key.objectid + block_group->key.offset; 188 + 189 + key.objectid = end - 1; 190 + key.type = (u8)-1; 191 + key.offset = (u64)-1; 192 + 193 + while (!done) { 194 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 195 + if (ret) 196 + goto out; 197 + 198 + leaf = path->nodes[0]; 199 + nr = 0; 200 + path->slots[0]++; 201 + while (path->slots[0] > 0) { 202 + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); 203 + 204 + if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { 205 + ASSERT(found_key.objectid == block_group->key.objectid); 206 + ASSERT(found_key.offset == block_group->key.offset); 207 + done = 1; 208 + break; 209 + } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) { 210 + u64 first, last; 211 + 212 + ASSERT(found_key.objectid >= start); 213 + ASSERT(found_key.objectid < end); 214 + ASSERT(found_key.objectid + found_key.offset <= end); 215 + 216 + first = div_u64(found_key.objectid - start, 217 + block_group->sectorsize); 218 + last = div_u64(found_key.objectid + found_key.offset - start, 219 + block_group->sectorsize); 220 + bitmap_set(bitmap, first, last - first); 221 + 222 + extent_count++; 223 + nr++; 224 + path->slots[0]--; 225 + } else { 226 + ASSERT(0); 227 + } 228 + } 229 + 230 + ret = btrfs_del_items(trans, root, path, path->slots[0], nr); 231 + if (ret) 232 + goto out; 233 + btrfs_release_path(path); 234 + } 235 + 236 + info = search_free_space_info(trans, fs_info, block_group, path, 1); 237 + if (IS_ERR(info)) { 238 + ret = PTR_ERR(info); 239 + goto out; 240 + } 241 + leaf = path->nodes[0]; 242 + flags = btrfs_free_space_flags(leaf, info); 243 + flags |= BTRFS_FREE_SPACE_USING_BITMAPS; 244 + btrfs_set_free_space_flags(leaf, info, flags); 245 + expected_extent_count = btrfs_free_space_extent_count(leaf, info); 246 + btrfs_mark_buffer_dirty(leaf); 247 + btrfs_release_path(path); 248 + 249 + if (extent_count != expected_extent_count) { 250 + btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u", 251 + block_group->key.objectid, extent_count, 252 + expected_extent_count); 253 + ASSERT(0); 254 + ret = -EIO; 255 + goto out; 256 + } 257 + 258 + bitmap_cursor = (char *)bitmap; 259 + bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS; 260 + i = start; 261 + while (i < end) { 262 + unsigned long ptr; 263 + u64 extent_size; 264 + u32 data_size; 265 + 266 + extent_size = min(end - i, bitmap_range); 267 + data_size = free_space_bitmap_size(extent_size, 268 + block_group->sectorsize); 269 + 270 + key.objectid = i; 271 + key.type = BTRFS_FREE_SPACE_BITMAP_KEY; 272 + key.offset = extent_size; 273 + 274 + ret = btrfs_insert_empty_item(trans, root, path, &key, 275 + data_size); 276 + if (ret) 277 + goto out; 278 + 279 + leaf = path->nodes[0]; 280 + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 281 + write_extent_buffer(leaf, bitmap_cursor, ptr, 282 + data_size); 283 + btrfs_mark_buffer_dirty(leaf); 284 + btrfs_release_path(path); 285 + 286 + i += extent_size; 287 + bitmap_cursor += data_size; 288 + } 289 + 290 + ret = 0; 291 + out: 292 + vfree(bitmap); 293 + if (ret) 294 + btrfs_abort_transaction(trans, root, ret); 295 + return ret; 296 + } 297 + 298 + int convert_free_space_to_extents(struct btrfs_trans_handle *trans, 299 + struct btrfs_fs_info *fs_info, 300 + struct btrfs_block_group_cache *block_group, 301 + struct btrfs_path *path) 302 + { 303 + struct btrfs_root *root = fs_info->free_space_root; 304 + struct btrfs_free_space_info *info; 305 + struct btrfs_key key, found_key; 306 + struct extent_buffer *leaf; 307 + unsigned long *bitmap; 308 + u64 start, end; 309 + /* Initialize to silence GCC. */ 310 + u64 extent_start = 0; 311 + u64 offset; 312 + u32 bitmap_size, flags, expected_extent_count; 313 + int prev_bit = 0, bit, bitnr; 314 + u32 extent_count = 0; 315 + int done = 0, nr; 316 + int ret; 317 + 318 + bitmap_size = free_space_bitmap_size(block_group->key.offset, 319 + block_group->sectorsize); 320 + bitmap = alloc_bitmap(bitmap_size); 321 + if (!bitmap) { 322 + ret = -ENOMEM; 323 + goto out; 324 + } 325 + 326 + start = block_group->key.objectid; 327 + end = block_group->key.objectid + block_group->key.offset; 328 + 329 + key.objectid = end - 1; 330 + key.type = (u8)-1; 331 + key.offset = (u64)-1; 332 + 333 + while (!done) { 334 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 335 + if (ret) 336 + goto out; 337 + 338 + leaf = path->nodes[0]; 339 + nr = 0; 340 + path->slots[0]++; 341 + while (path->slots[0] > 0) { 342 + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); 343 + 344 + if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { 345 + ASSERT(found_key.objectid == block_group->key.objectid); 346 + ASSERT(found_key.offset == block_group->key.offset); 347 + done = 1; 348 + break; 349 + } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { 350 + unsigned long ptr; 351 + char *bitmap_cursor; 352 + u32 bitmap_pos, data_size; 353 + 354 + ASSERT(found_key.objectid >= start); 355 + ASSERT(found_key.objectid < end); 356 + ASSERT(found_key.objectid + found_key.offset <= end); 357 + 358 + bitmap_pos = div_u64(found_key.objectid - start, 359 + block_group->sectorsize * 360 + BITS_PER_BYTE); 361 + bitmap_cursor = ((char *)bitmap) + bitmap_pos; 362 + data_size = free_space_bitmap_size(found_key.offset, 363 + block_group->sectorsize); 364 + 365 + ptr = btrfs_item_ptr_offset(leaf, path->slots[0] - 1); 366 + read_extent_buffer(leaf, bitmap_cursor, ptr, 367 + data_size); 368 + 369 + nr++; 370 + path->slots[0]--; 371 + } else { 372 + ASSERT(0); 373 + } 374 + } 375 + 376 + ret = btrfs_del_items(trans, root, path, path->slots[0], nr); 377 + if (ret) 378 + goto out; 379 + btrfs_release_path(path); 380 + } 381 + 382 + info = search_free_space_info(trans, fs_info, block_group, path, 1); 383 + if (IS_ERR(info)) { 384 + ret = PTR_ERR(info); 385 + goto out; 386 + } 387 + leaf = path->nodes[0]; 388 + flags = btrfs_free_space_flags(leaf, info); 389 + flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS; 390 + btrfs_set_free_space_flags(leaf, info, flags); 391 + expected_extent_count = btrfs_free_space_extent_count(leaf, info); 392 + btrfs_mark_buffer_dirty(leaf); 393 + btrfs_release_path(path); 394 + 395 + offset = start; 396 + bitnr = 0; 397 + while (offset < end) { 398 + bit = !!test_bit(bitnr, bitmap); 399 + if (prev_bit == 0 && bit == 1) { 400 + extent_start = offset; 401 + } else if (prev_bit == 1 && bit == 0) { 402 + key.objectid = extent_start; 403 + key.type = BTRFS_FREE_SPACE_EXTENT_KEY; 404 + key.offset = offset - extent_start; 405 + 406 + ret = btrfs_insert_empty_item(trans, root, path, &key, 0); 407 + if (ret) 408 + goto out; 409 + btrfs_release_path(path); 410 + 411 + extent_count++; 412 + } 413 + prev_bit = bit; 414 + offset += block_group->sectorsize; 415 + bitnr++; 416 + } 417 + if (prev_bit == 1) { 418 + key.objectid = extent_start; 419 + key.type = BTRFS_FREE_SPACE_EXTENT_KEY; 420 + key.offset = end - extent_start; 421 + 422 + ret = btrfs_insert_empty_item(trans, root, path, &key, 0); 423 + if (ret) 424 + goto out; 425 + btrfs_release_path(path); 426 + 427 + extent_count++; 428 + } 429 + 430 + if (extent_count != expected_extent_count) { 431 + btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u", 432 + block_group->key.objectid, extent_count, 433 + expected_extent_count); 434 + ASSERT(0); 435 + ret = -EIO; 436 + goto out; 437 + } 438 + 439 + ret = 0; 440 + out: 441 + vfree(bitmap); 442 + if (ret) 443 + btrfs_abort_transaction(trans, root, ret); 444 + return ret; 445 + } 446 + 447 + static int update_free_space_extent_count(struct btrfs_trans_handle *trans, 448 + struct btrfs_fs_info *fs_info, 449 + struct btrfs_block_group_cache *block_group, 450 + struct btrfs_path *path, 451 + int new_extents) 452 + { 453 + struct btrfs_free_space_info *info; 454 + u32 flags; 455 + u32 extent_count; 456 + int ret = 0; 457 + 458 + if (new_extents == 0) 459 + return 0; 460 + 461 + info = search_free_space_info(trans, fs_info, block_group, path, 1); 462 + if (IS_ERR(info)) { 463 + ret = PTR_ERR(info); 464 + goto out; 465 + } 466 + flags = btrfs_free_space_flags(path->nodes[0], info); 467 + extent_count = btrfs_free_space_extent_count(path->nodes[0], info); 468 + 469 + extent_count += new_extents; 470 + btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count); 471 + btrfs_mark_buffer_dirty(path->nodes[0]); 472 + btrfs_release_path(path); 473 + 474 + if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) && 475 + extent_count > block_group->bitmap_high_thresh) { 476 + ret = convert_free_space_to_bitmaps(trans, fs_info, block_group, 477 + path); 478 + } else if ((flags & BTRFS_FREE_SPACE_USING_BITMAPS) && 479 + extent_count < block_group->bitmap_low_thresh) { 480 + ret = convert_free_space_to_extents(trans, fs_info, block_group, 481 + path); 482 + } 483 + 484 + out: 485 + return ret; 486 + } 487 + 488 + int free_space_test_bit(struct btrfs_block_group_cache *block_group, 489 + struct btrfs_path *path, u64 offset) 490 + { 491 + struct extent_buffer *leaf; 492 + struct btrfs_key key; 493 + u64 found_start, found_end; 494 + unsigned long ptr, i; 495 + 496 + leaf = path->nodes[0]; 497 + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 498 + ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY); 499 + 500 + found_start = key.objectid; 501 + found_end = key.objectid + key.offset; 502 + ASSERT(offset >= found_start && offset < found_end); 503 + 504 + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 505 + i = div_u64(offset - found_start, block_group->sectorsize); 506 + return !!extent_buffer_test_bit(leaf, ptr, i); 507 + } 508 + 509 + static void free_space_set_bits(struct btrfs_block_group_cache *block_group, 510 + struct btrfs_path *path, u64 *start, u64 *size, 511 + int bit) 512 + { 513 + struct extent_buffer *leaf; 514 + struct btrfs_key key; 515 + u64 end = *start + *size; 516 + u64 found_start, found_end; 517 + unsigned long ptr, first, last; 518 + 519 + leaf = path->nodes[0]; 520 + btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 521 + ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY); 522 + 523 + found_start = key.objectid; 524 + found_end = key.objectid + key.offset; 525 + ASSERT(*start >= found_start && *start < found_end); 526 + ASSERT(end > found_start); 527 + 528 + if (end > found_end) 529 + end = found_end; 530 + 531 + ptr = btrfs_item_ptr_offset(leaf, path->slots[0]); 532 + first = div_u64(*start - found_start, block_group->sectorsize); 533 + last = div_u64(end - found_start, block_group->sectorsize); 534 + if (bit) 535 + extent_buffer_bitmap_set(leaf, ptr, first, last - first); 536 + else 537 + extent_buffer_bitmap_clear(leaf, ptr, first, last - first); 538 + btrfs_mark_buffer_dirty(leaf); 539 + 540 + *size -= end - *start; 541 + *start = end; 542 + } 543 + 544 + /* 545 + * We can't use btrfs_next_item() in modify_free_space_bitmap() because 546 + * btrfs_next_leaf() doesn't get the path for writing. We can forgo the fancy 547 + * tree walking in btrfs_next_leaf() anyways because we know exactly what we're 548 + * looking for. 549 + */ 550 + static int free_space_next_bitmap(struct btrfs_trans_handle *trans, 551 + struct btrfs_root *root, struct btrfs_path *p) 552 + { 553 + struct btrfs_key key; 554 + 555 + if (p->slots[0] + 1 < btrfs_header_nritems(p->nodes[0])) { 556 + p->slots[0]++; 557 + return 0; 558 + } 559 + 560 + btrfs_item_key_to_cpu(p->nodes[0], &key, p->slots[0]); 561 + btrfs_release_path(p); 562 + 563 + key.objectid += key.offset; 564 + key.type = (u8)-1; 565 + key.offset = (u64)-1; 566 + 567 + return btrfs_search_prev_slot(trans, root, &key, p, 0, 1); 568 + } 569 + 570 + /* 571 + * If remove is 1, then we are removing free space, thus clearing bits in the 572 + * bitmap. If remove is 0, then we are adding free space, thus setting bits in 573 + * the bitmap. 574 + */ 575 + static int modify_free_space_bitmap(struct btrfs_trans_handle *trans, 576 + struct btrfs_fs_info *fs_info, 577 + struct btrfs_block_group_cache *block_group, 578 + struct btrfs_path *path, 579 + u64 start, u64 size, int remove) 580 + { 581 + struct btrfs_root *root = fs_info->free_space_root; 582 + struct btrfs_key key; 583 + u64 end = start + size; 584 + u64 cur_start, cur_size; 585 + int prev_bit, next_bit; 586 + int new_extents; 587 + int ret; 588 + 589 + /* 590 + * Read the bit for the block immediately before the extent of space if 591 + * that block is within the block group. 592 + */ 593 + if (start > block_group->key.objectid) { 594 + u64 prev_block = start - block_group->sectorsize; 595 + 596 + key.objectid = prev_block; 597 + key.type = (u8)-1; 598 + key.offset = (u64)-1; 599 + 600 + ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1); 601 + if (ret) 602 + goto out; 603 + 604 + prev_bit = free_space_test_bit(block_group, path, prev_block); 605 + 606 + /* The previous block may have been in the previous bitmap. */ 607 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 608 + if (start >= key.objectid + key.offset) { 609 + ret = free_space_next_bitmap(trans, root, path); 610 + if (ret) 611 + goto out; 612 + } 613 + } else { 614 + key.objectid = start; 615 + key.type = (u8)-1; 616 + key.offset = (u64)-1; 617 + 618 + ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1); 619 + if (ret) 620 + goto out; 621 + 622 + prev_bit = -1; 623 + } 624 + 625 + /* 626 + * Iterate over all of the bitmaps overlapped by the extent of space, 627 + * clearing/setting bits as required. 628 + */ 629 + cur_start = start; 630 + cur_size = size; 631 + while (1) { 632 + free_space_set_bits(block_group, path, &cur_start, &cur_size, 633 + !remove); 634 + if (cur_size == 0) 635 + break; 636 + ret = free_space_next_bitmap(trans, root, path); 637 + if (ret) 638 + goto out; 639 + } 640 + 641 + /* 642 + * Read the bit for the block immediately after the extent of space if 643 + * that block is within the block group. 644 + */ 645 + if (end < block_group->key.objectid + block_group->key.offset) { 646 + /* The next block may be in the next bitmap. */ 647 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 648 + if (end >= key.objectid + key.offset) { 649 + ret = free_space_next_bitmap(trans, root, path); 650 + if (ret) 651 + goto out; 652 + } 653 + 654 + next_bit = free_space_test_bit(block_group, path, end); 655 + } else { 656 + next_bit = -1; 657 + } 658 + 659 + if (remove) { 660 + new_extents = -1; 661 + if (prev_bit == 1) { 662 + /* Leftover on the left. */ 663 + new_extents++; 664 + } 665 + if (next_bit == 1) { 666 + /* Leftover on the right. */ 667 + new_extents++; 668 + } 669 + } else { 670 + new_extents = 1; 671 + if (prev_bit == 1) { 672 + /* Merging with neighbor on the left. */ 673 + new_extents--; 674 + } 675 + if (next_bit == 1) { 676 + /* Merging with neighbor on the right. */ 677 + new_extents--; 678 + } 679 + } 680 + 681 + btrfs_release_path(path); 682 + ret = update_free_space_extent_count(trans, fs_info, block_group, path, 683 + new_extents); 684 + 685 + out: 686 + return ret; 687 + } 688 + 689 + static int remove_free_space_extent(struct btrfs_trans_handle *trans, 690 + struct btrfs_fs_info *fs_info, 691 + struct btrfs_block_group_cache *block_group, 692 + struct btrfs_path *path, 693 + u64 start, u64 size) 694 + { 695 + struct btrfs_root *root = fs_info->free_space_root; 696 + struct btrfs_key key; 697 + u64 found_start, found_end; 698 + u64 end = start + size; 699 + int new_extents = -1; 700 + int ret; 701 + 702 + key.objectid = start; 703 + key.type = (u8)-1; 704 + key.offset = (u64)-1; 705 + 706 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 707 + if (ret) 708 + goto out; 709 + 710 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 711 + 712 + ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY); 713 + 714 + found_start = key.objectid; 715 + found_end = key.objectid + key.offset; 716 + ASSERT(start >= found_start && end <= found_end); 717 + 718 + /* 719 + * Okay, now that we've found the free space extent which contains the 720 + * free space that we are removing, there are four cases: 721 + * 722 + * 1. We're using the whole extent: delete the key we found and 723 + * decrement the free space extent count. 724 + * 2. We are using part of the extent starting at the beginning: delete 725 + * the key we found and insert a new key representing the leftover at 726 + * the end. There is no net change in the number of extents. 727 + * 3. We are using part of the extent ending at the end: delete the key 728 + * we found and insert a new key representing the leftover at the 729 + * beginning. There is no net change in the number of extents. 730 + * 4. We are using part of the extent in the middle: delete the key we 731 + * found and insert two new keys representing the leftovers on each 732 + * side. Where we used to have one extent, we now have two, so increment 733 + * the extent count. We may need to convert the block group to bitmaps 734 + * as a result. 735 + */ 736 + 737 + /* Delete the existing key (cases 1-4). */ 738 + ret = btrfs_del_item(trans, root, path); 739 + if (ret) 740 + goto out; 741 + 742 + /* Add a key for leftovers at the beginning (cases 3 and 4). */ 743 + if (start > found_start) { 744 + key.objectid = found_start; 745 + key.type = BTRFS_FREE_SPACE_EXTENT_KEY; 746 + key.offset = start - found_start; 747 + 748 + btrfs_release_path(path); 749 + ret = btrfs_insert_empty_item(trans, root, path, &key, 0); 750 + if (ret) 751 + goto out; 752 + new_extents++; 753 + } 754 + 755 + /* Add a key for leftovers at the end (cases 2 and 4). */ 756 + if (end < found_end) { 757 + key.objectid = end; 758 + key.type = BTRFS_FREE_SPACE_EXTENT_KEY; 759 + key.offset = found_end - end; 760 + 761 + btrfs_release_path(path); 762 + ret = btrfs_insert_empty_item(trans, root, path, &key, 0); 763 + if (ret) 764 + goto out; 765 + new_extents++; 766 + } 767 + 768 + btrfs_release_path(path); 769 + ret = update_free_space_extent_count(trans, fs_info, block_group, path, 770 + new_extents); 771 + 772 + out: 773 + return ret; 774 + } 775 + 776 + int __remove_from_free_space_tree(struct btrfs_trans_handle *trans, 777 + struct btrfs_fs_info *fs_info, 778 + struct btrfs_block_group_cache *block_group, 779 + struct btrfs_path *path, u64 start, u64 size) 780 + { 781 + struct btrfs_free_space_info *info; 782 + u32 flags; 783 + int ret; 784 + 785 + if (block_group->needs_free_space) { 786 + ret = __add_block_group_free_space(trans, fs_info, block_group, 787 + path); 788 + if (ret) 789 + return ret; 790 + } 791 + 792 + info = search_free_space_info(NULL, fs_info, block_group, path, 0); 793 + if (IS_ERR(info)) 794 + return PTR_ERR(info); 795 + flags = btrfs_free_space_flags(path->nodes[0], info); 796 + btrfs_release_path(path); 797 + 798 + if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) { 799 + return modify_free_space_bitmap(trans, fs_info, block_group, 800 + path, start, size, 1); 801 + } else { 802 + return remove_free_space_extent(trans, fs_info, block_group, 803 + path, start, size); 804 + } 805 + } 806 + 807 + int remove_from_free_space_tree(struct btrfs_trans_handle *trans, 808 + struct btrfs_fs_info *fs_info, 809 + u64 start, u64 size) 810 + { 811 + struct btrfs_block_group_cache *block_group; 812 + struct btrfs_path *path; 813 + int ret; 814 + 815 + if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) 816 + return 0; 817 + 818 + path = btrfs_alloc_path(); 819 + if (!path) { 820 + ret = -ENOMEM; 821 + goto out; 822 + } 823 + 824 + block_group = btrfs_lookup_block_group(fs_info, start); 825 + if (!block_group) { 826 + ASSERT(0); 827 + ret = -ENOENT; 828 + goto out; 829 + } 830 + 831 + mutex_lock(&block_group->free_space_lock); 832 + ret = __remove_from_free_space_tree(trans, fs_info, block_group, path, 833 + start, size); 834 + mutex_unlock(&block_group->free_space_lock); 835 + 836 + btrfs_put_block_group(block_group); 837 + out: 838 + btrfs_free_path(path); 839 + if (ret) 840 + btrfs_abort_transaction(trans, fs_info->free_space_root, ret); 841 + return ret; 842 + } 843 + 844 + static int add_free_space_extent(struct btrfs_trans_handle *trans, 845 + struct btrfs_fs_info *fs_info, 846 + struct btrfs_block_group_cache *block_group, 847 + struct btrfs_path *path, 848 + u64 start, u64 size) 849 + { 850 + struct btrfs_root *root = fs_info->free_space_root; 851 + struct btrfs_key key, new_key; 852 + u64 found_start, found_end; 853 + u64 end = start + size; 854 + int new_extents = 1; 855 + int ret; 856 + 857 + /* 858 + * We are adding a new extent of free space, but we need to merge 859 + * extents. There are four cases here: 860 + * 861 + * 1. The new extent does not have any immediate neighbors to merge 862 + * with: add the new key and increment the free space extent count. We 863 + * may need to convert the block group to bitmaps as a result. 864 + * 2. The new extent has an immediate neighbor before it: remove the 865 + * previous key and insert a new key combining both of them. There is no 866 + * net change in the number of extents. 867 + * 3. The new extent has an immediate neighbor after it: remove the next 868 + * key and insert a new key combining both of them. There is no net 869 + * change in the number of extents. 870 + * 4. The new extent has immediate neighbors on both sides: remove both 871 + * of the keys and insert a new key combining all of them. Where we used 872 + * to have two extents, we now have one, so decrement the extent count. 873 + */ 874 + 875 + new_key.objectid = start; 876 + new_key.type = BTRFS_FREE_SPACE_EXTENT_KEY; 877 + new_key.offset = size; 878 + 879 + /* Search for a neighbor on the left. */ 880 + if (start == block_group->key.objectid) 881 + goto right; 882 + key.objectid = start - 1; 883 + key.type = (u8)-1; 884 + key.offset = (u64)-1; 885 + 886 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 887 + if (ret) 888 + goto out; 889 + 890 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 891 + 892 + if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) { 893 + ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY); 894 + btrfs_release_path(path); 895 + goto right; 896 + } 897 + 898 + found_start = key.objectid; 899 + found_end = key.objectid + key.offset; 900 + ASSERT(found_start >= block_group->key.objectid && 901 + found_end > block_group->key.objectid); 902 + ASSERT(found_start < start && found_end <= start); 903 + 904 + /* 905 + * Delete the neighbor on the left and absorb it into the new key (cases 906 + * 2 and 4). 907 + */ 908 + if (found_end == start) { 909 + ret = btrfs_del_item(trans, root, path); 910 + if (ret) 911 + goto out; 912 + new_key.objectid = found_start; 913 + new_key.offset += key.offset; 914 + new_extents--; 915 + } 916 + btrfs_release_path(path); 917 + 918 + right: 919 + /* Search for a neighbor on the right. */ 920 + if (end == block_group->key.objectid + block_group->key.offset) 921 + goto insert; 922 + key.objectid = end; 923 + key.type = (u8)-1; 924 + key.offset = (u64)-1; 925 + 926 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 927 + if (ret) 928 + goto out; 929 + 930 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 931 + 932 + if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) { 933 + ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY); 934 + btrfs_release_path(path); 935 + goto insert; 936 + } 937 + 938 + found_start = key.objectid; 939 + found_end = key.objectid + key.offset; 940 + ASSERT(found_start >= block_group->key.objectid && 941 + found_end > block_group->key.objectid); 942 + ASSERT((found_start < start && found_end <= start) || 943 + (found_start >= end && found_end > end)); 944 + 945 + /* 946 + * Delete the neighbor on the right and absorb it into the new key 947 + * (cases 3 and 4). 948 + */ 949 + if (found_start == end) { 950 + ret = btrfs_del_item(trans, root, path); 951 + if (ret) 952 + goto out; 953 + new_key.offset += key.offset; 954 + new_extents--; 955 + } 956 + btrfs_release_path(path); 957 + 958 + insert: 959 + /* Insert the new key (cases 1-4). */ 960 + ret = btrfs_insert_empty_item(trans, root, path, &new_key, 0); 961 + if (ret) 962 + goto out; 963 + 964 + btrfs_release_path(path); 965 + ret = update_free_space_extent_count(trans, fs_info, block_group, path, 966 + new_extents); 967 + 968 + out: 969 + return ret; 970 + } 971 + 972 + int __add_to_free_space_tree(struct btrfs_trans_handle *trans, 973 + struct btrfs_fs_info *fs_info, 974 + struct btrfs_block_group_cache *block_group, 975 + struct btrfs_path *path, u64 start, u64 size) 976 + { 977 + struct btrfs_free_space_info *info; 978 + u32 flags; 979 + int ret; 980 + 981 + if (block_group->needs_free_space) { 982 + ret = __add_block_group_free_space(trans, fs_info, block_group, 983 + path); 984 + if (ret) 985 + return ret; 986 + } 987 + 988 + info = search_free_space_info(NULL, fs_info, block_group, path, 0); 989 + if (IS_ERR(info)) 990 + return PTR_ERR(info); 991 + flags = btrfs_free_space_flags(path->nodes[0], info); 992 + btrfs_release_path(path); 993 + 994 + if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) { 995 + return modify_free_space_bitmap(trans, fs_info, block_group, 996 + path, start, size, 0); 997 + } else { 998 + return add_free_space_extent(trans, fs_info, block_group, path, 999 + start, size); 1000 + } 1001 + } 1002 + 1003 + int add_to_free_space_tree(struct btrfs_trans_handle *trans, 1004 + struct btrfs_fs_info *fs_info, 1005 + u64 start, u64 size) 1006 + { 1007 + struct btrfs_block_group_cache *block_group; 1008 + struct btrfs_path *path; 1009 + int ret; 1010 + 1011 + if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) 1012 + return 0; 1013 + 1014 + path = btrfs_alloc_path(); 1015 + if (!path) { 1016 + ret = -ENOMEM; 1017 + goto out; 1018 + } 1019 + 1020 + block_group = btrfs_lookup_block_group(fs_info, start); 1021 + if (!block_group) { 1022 + ASSERT(0); 1023 + ret = -ENOENT; 1024 + goto out; 1025 + } 1026 + 1027 + mutex_lock(&block_group->free_space_lock); 1028 + ret = __add_to_free_space_tree(trans, fs_info, block_group, path, start, 1029 + size); 1030 + mutex_unlock(&block_group->free_space_lock); 1031 + 1032 + btrfs_put_block_group(block_group); 1033 + out: 1034 + btrfs_free_path(path); 1035 + if (ret) 1036 + btrfs_abort_transaction(trans, fs_info->free_space_root, ret); 1037 + return ret; 1038 + } 1039 + 1040 + /* 1041 + * Populate the free space tree by walking the extent tree. Operations on the 1042 + * extent tree that happen as a result of writes to the free space tree will go 1043 + * through the normal add/remove hooks. 1044 + */ 1045 + static int populate_free_space_tree(struct btrfs_trans_handle *trans, 1046 + struct btrfs_fs_info *fs_info, 1047 + struct btrfs_block_group_cache *block_group) 1048 + { 1049 + struct btrfs_root *extent_root = fs_info->extent_root; 1050 + struct btrfs_path *path, *path2; 1051 + struct btrfs_key key; 1052 + u64 start, end; 1053 + int ret; 1054 + 1055 + path = btrfs_alloc_path(); 1056 + if (!path) 1057 + return -ENOMEM; 1058 + path->reada = 1; 1059 + 1060 + path2 = btrfs_alloc_path(); 1061 + if (!path2) { 1062 + btrfs_free_path(path); 1063 + return -ENOMEM; 1064 + } 1065 + 1066 + ret = add_new_free_space_info(trans, fs_info, block_group, path2); 1067 + if (ret) 1068 + goto out; 1069 + 1070 + /* 1071 + * Iterate through all of the extent and metadata items in this block 1072 + * group, adding the free space between them and the free space at the 1073 + * end. Note that EXTENT_ITEM and METADATA_ITEM are less than 1074 + * BLOCK_GROUP_ITEM, so an extent may precede the block group that it's 1075 + * contained in. 1076 + */ 1077 + key.objectid = block_group->key.objectid; 1078 + key.type = BTRFS_EXTENT_ITEM_KEY; 1079 + key.offset = 0; 1080 + 1081 + ret = btrfs_search_slot_for_read(extent_root, &key, path, 1, 0); 1082 + if (ret < 0) 1083 + goto out; 1084 + ASSERT(ret == 0); 1085 + 1086 + start = block_group->key.objectid; 1087 + end = block_group->key.objectid + block_group->key.offset; 1088 + while (1) { 1089 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 1090 + 1091 + if (key.type == BTRFS_EXTENT_ITEM_KEY || 1092 + key.type == BTRFS_METADATA_ITEM_KEY) { 1093 + if (key.objectid >= end) 1094 + break; 1095 + 1096 + if (start < key.objectid) { 1097 + ret = __add_to_free_space_tree(trans, fs_info, 1098 + block_group, 1099 + path2, start, 1100 + key.objectid - 1101 + start); 1102 + if (ret) 1103 + goto out; 1104 + } 1105 + start = key.objectid; 1106 + if (key.type == BTRFS_METADATA_ITEM_KEY) 1107 + start += fs_info->tree_root->nodesize; 1108 + else 1109 + start += key.offset; 1110 + } else if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) { 1111 + if (key.objectid != block_group->key.objectid) 1112 + break; 1113 + } 1114 + 1115 + ret = btrfs_next_item(extent_root, path); 1116 + if (ret < 0) 1117 + goto out; 1118 + if (ret) 1119 + break; 1120 + } 1121 + if (start < end) { 1122 + ret = __add_to_free_space_tree(trans, fs_info, block_group, 1123 + path2, start, end - start); 1124 + if (ret) 1125 + goto out; 1126 + } 1127 + 1128 + ret = 0; 1129 + out: 1130 + btrfs_free_path(path2); 1131 + btrfs_free_path(path); 1132 + return ret; 1133 + } 1134 + 1135 + int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info) 1136 + { 1137 + struct btrfs_trans_handle *trans; 1138 + struct btrfs_root *tree_root = fs_info->tree_root; 1139 + struct btrfs_root *free_space_root; 1140 + struct btrfs_block_group_cache *block_group; 1141 + struct rb_node *node; 1142 + int ret; 1143 + 1144 + trans = btrfs_start_transaction(tree_root, 0); 1145 + if (IS_ERR(trans)) 1146 + return PTR_ERR(trans); 1147 + 1148 + free_space_root = btrfs_create_tree(trans, fs_info, 1149 + BTRFS_FREE_SPACE_TREE_OBJECTID); 1150 + if (IS_ERR(free_space_root)) { 1151 + ret = PTR_ERR(free_space_root); 1152 + goto abort; 1153 + } 1154 + fs_info->free_space_root = free_space_root; 1155 + 1156 + node = rb_first(&fs_info->block_group_cache_tree); 1157 + while (node) { 1158 + block_group = rb_entry(node, struct btrfs_block_group_cache, 1159 + cache_node); 1160 + ret = populate_free_space_tree(trans, fs_info, block_group); 1161 + if (ret) 1162 + goto abort; 1163 + node = rb_next(node); 1164 + } 1165 + 1166 + btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE); 1167 + 1168 + ret = btrfs_commit_transaction(trans, tree_root); 1169 + if (ret) 1170 + return ret; 1171 + 1172 + return 0; 1173 + 1174 + abort: 1175 + btrfs_abort_transaction(trans, tree_root, ret); 1176 + btrfs_end_transaction(trans, tree_root); 1177 + return ret; 1178 + } 1179 + 1180 + static int clear_free_space_tree(struct btrfs_trans_handle *trans, 1181 + struct btrfs_root *root) 1182 + { 1183 + struct btrfs_path *path; 1184 + struct btrfs_key key; 1185 + int nr; 1186 + int ret; 1187 + 1188 + path = btrfs_alloc_path(); 1189 + if (!path) 1190 + return -ENOMEM; 1191 + 1192 + path->leave_spinning = 1; 1193 + 1194 + key.objectid = 0; 1195 + key.type = 0; 1196 + key.offset = 0; 1197 + 1198 + while (1) { 1199 + ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 1200 + if (ret < 0) 1201 + goto out; 1202 + 1203 + nr = btrfs_header_nritems(path->nodes[0]); 1204 + if (!nr) 1205 + break; 1206 + 1207 + path->slots[0] = 0; 1208 + ret = btrfs_del_items(trans, root, path, 0, nr); 1209 + if (ret) 1210 + goto out; 1211 + 1212 + btrfs_release_path(path); 1213 + } 1214 + 1215 + ret = 0; 1216 + out: 1217 + btrfs_free_path(path); 1218 + return ret; 1219 + } 1220 + 1221 + int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info) 1222 + { 1223 + struct btrfs_trans_handle *trans; 1224 + struct btrfs_root *tree_root = fs_info->tree_root; 1225 + struct btrfs_root *free_space_root = fs_info->free_space_root; 1226 + int ret; 1227 + 1228 + trans = btrfs_start_transaction(tree_root, 0); 1229 + if (IS_ERR(trans)) 1230 + return PTR_ERR(trans); 1231 + 1232 + btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE); 1233 + fs_info->free_space_root = NULL; 1234 + 1235 + ret = clear_free_space_tree(trans, free_space_root); 1236 + if (ret) 1237 + goto abort; 1238 + 1239 + ret = btrfs_del_root(trans, tree_root, &free_space_root->root_key); 1240 + if (ret) 1241 + goto abort; 1242 + 1243 + list_del(&free_space_root->dirty_list); 1244 + 1245 + btrfs_tree_lock(free_space_root->node); 1246 + clean_tree_block(trans, tree_root->fs_info, free_space_root->node); 1247 + btrfs_tree_unlock(free_space_root->node); 1248 + btrfs_free_tree_block(trans, free_space_root, free_space_root->node, 1249 + 0, 1); 1250 + 1251 + free_extent_buffer(free_space_root->node); 1252 + free_extent_buffer(free_space_root->commit_root); 1253 + kfree(free_space_root); 1254 + 1255 + ret = btrfs_commit_transaction(trans, tree_root); 1256 + if (ret) 1257 + return ret; 1258 + 1259 + return 0; 1260 + 1261 + abort: 1262 + btrfs_abort_transaction(trans, tree_root, ret); 1263 + btrfs_end_transaction(trans, tree_root); 1264 + return ret; 1265 + } 1266 + 1267 + static int __add_block_group_free_space(struct btrfs_trans_handle *trans, 1268 + struct btrfs_fs_info *fs_info, 1269 + struct btrfs_block_group_cache *block_group, 1270 + struct btrfs_path *path) 1271 + { 1272 + u64 start, end; 1273 + int ret; 1274 + 1275 + start = block_group->key.objectid; 1276 + end = block_group->key.objectid + block_group->key.offset; 1277 + 1278 + block_group->needs_free_space = 0; 1279 + 1280 + ret = add_new_free_space_info(trans, fs_info, block_group, path); 1281 + if (ret) 1282 + return ret; 1283 + 1284 + return __add_to_free_space_tree(trans, fs_info, block_group, path, 1285 + block_group->key.objectid, 1286 + block_group->key.offset); 1287 + } 1288 + 1289 + int add_block_group_free_space(struct btrfs_trans_handle *trans, 1290 + struct btrfs_fs_info *fs_info, 1291 + struct btrfs_block_group_cache *block_group) 1292 + { 1293 + struct btrfs_path *path = NULL; 1294 + int ret = 0; 1295 + 1296 + if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) 1297 + return 0; 1298 + 1299 + mutex_lock(&block_group->free_space_lock); 1300 + if (!block_group->needs_free_space) 1301 + goto out; 1302 + 1303 + path = btrfs_alloc_path(); 1304 + if (!path) { 1305 + ret = -ENOMEM; 1306 + goto out; 1307 + } 1308 + 1309 + ret = __add_block_group_free_space(trans, fs_info, block_group, path); 1310 + 1311 + out: 1312 + btrfs_free_path(path); 1313 + mutex_unlock(&block_group->free_space_lock); 1314 + if (ret) 1315 + btrfs_abort_transaction(trans, fs_info->free_space_root, ret); 1316 + return ret; 1317 + } 1318 + 1319 + int remove_block_group_free_space(struct btrfs_trans_handle *trans, 1320 + struct btrfs_fs_info *fs_info, 1321 + struct btrfs_block_group_cache *block_group) 1322 + { 1323 + struct btrfs_root *root = fs_info->free_space_root; 1324 + struct btrfs_path *path; 1325 + struct btrfs_key key, found_key; 1326 + struct extent_buffer *leaf; 1327 + u64 start, end; 1328 + int done = 0, nr; 1329 + int ret; 1330 + 1331 + if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) 1332 + return 0; 1333 + 1334 + if (block_group->needs_free_space) { 1335 + /* We never added this block group to the free space tree. */ 1336 + return 0; 1337 + } 1338 + 1339 + path = btrfs_alloc_path(); 1340 + if (!path) { 1341 + ret = -ENOMEM; 1342 + goto out; 1343 + } 1344 + 1345 + start = block_group->key.objectid; 1346 + end = block_group->key.objectid + block_group->key.offset; 1347 + 1348 + key.objectid = end - 1; 1349 + key.type = (u8)-1; 1350 + key.offset = (u64)-1; 1351 + 1352 + while (!done) { 1353 + ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1); 1354 + if (ret) 1355 + goto out; 1356 + 1357 + leaf = path->nodes[0]; 1358 + nr = 0; 1359 + path->slots[0]++; 1360 + while (path->slots[0] > 0) { 1361 + btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1); 1362 + 1363 + if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) { 1364 + ASSERT(found_key.objectid == block_group->key.objectid); 1365 + ASSERT(found_key.offset == block_group->key.offset); 1366 + done = 1; 1367 + nr++; 1368 + path->slots[0]--; 1369 + break; 1370 + } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY || 1371 + found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) { 1372 + ASSERT(found_key.objectid >= start); 1373 + ASSERT(found_key.objectid < end); 1374 + ASSERT(found_key.objectid + found_key.offset <= end); 1375 + nr++; 1376 + path->slots[0]--; 1377 + } else { 1378 + ASSERT(0); 1379 + } 1380 + } 1381 + 1382 + ret = btrfs_del_items(trans, root, path, path->slots[0], nr); 1383 + if (ret) 1384 + goto out; 1385 + btrfs_release_path(path); 1386 + } 1387 + 1388 + ret = 0; 1389 + out: 1390 + btrfs_free_path(path); 1391 + if (ret) 1392 + btrfs_abort_transaction(trans, root, ret); 1393 + return ret; 1394 + } 1395 + 1396 + static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl, 1397 + struct btrfs_path *path, 1398 + u32 expected_extent_count) 1399 + { 1400 + struct btrfs_block_group_cache *block_group; 1401 + struct btrfs_fs_info *fs_info; 1402 + struct btrfs_root *root; 1403 + struct btrfs_key key; 1404 + int prev_bit = 0, bit; 1405 + /* Initialize to silence GCC. */ 1406 + u64 extent_start = 0; 1407 + u64 end, offset; 1408 + u64 total_found = 0; 1409 + u32 extent_count = 0; 1410 + int ret; 1411 + 1412 + block_group = caching_ctl->block_group; 1413 + fs_info = block_group->fs_info; 1414 + root = fs_info->free_space_root; 1415 + 1416 + end = block_group->key.objectid + block_group->key.offset; 1417 + 1418 + while (1) { 1419 + ret = btrfs_next_item(root, path); 1420 + if (ret < 0) 1421 + goto out; 1422 + if (ret) 1423 + break; 1424 + 1425 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 1426 + 1427 + if (key.type == BTRFS_FREE_SPACE_INFO_KEY) 1428 + break; 1429 + 1430 + ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY); 1431 + ASSERT(key.objectid < end && key.objectid + key.offset <= end); 1432 + 1433 + caching_ctl->progress = key.objectid; 1434 + 1435 + offset = key.objectid; 1436 + while (offset < key.objectid + key.offset) { 1437 + bit = free_space_test_bit(block_group, path, offset); 1438 + if (prev_bit == 0 && bit == 1) { 1439 + extent_start = offset; 1440 + } else if (prev_bit == 1 && bit == 0) { 1441 + total_found += add_new_free_space(block_group, 1442 + fs_info, 1443 + extent_start, 1444 + offset); 1445 + if (total_found > CACHING_CTL_WAKE_UP) { 1446 + total_found = 0; 1447 + wake_up(&caching_ctl->wait); 1448 + } 1449 + extent_count++; 1450 + } 1451 + prev_bit = bit; 1452 + offset += block_group->sectorsize; 1453 + } 1454 + } 1455 + if (prev_bit == 1) { 1456 + total_found += add_new_free_space(block_group, fs_info, 1457 + extent_start, end); 1458 + extent_count++; 1459 + } 1460 + 1461 + if (extent_count != expected_extent_count) { 1462 + btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u", 1463 + block_group->key.objectid, extent_count, 1464 + expected_extent_count); 1465 + ASSERT(0); 1466 + ret = -EIO; 1467 + goto out; 1468 + } 1469 + 1470 + caching_ctl->progress = (u64)-1; 1471 + 1472 + ret = 0; 1473 + out: 1474 + return ret; 1475 + } 1476 + 1477 + static int load_free_space_extents(struct btrfs_caching_control *caching_ctl, 1478 + struct btrfs_path *path, 1479 + u32 expected_extent_count) 1480 + { 1481 + struct btrfs_block_group_cache *block_group; 1482 + struct btrfs_fs_info *fs_info; 1483 + struct btrfs_root *root; 1484 + struct btrfs_key key; 1485 + u64 end; 1486 + u64 total_found = 0; 1487 + u32 extent_count = 0; 1488 + int ret; 1489 + 1490 + block_group = caching_ctl->block_group; 1491 + fs_info = block_group->fs_info; 1492 + root = fs_info->free_space_root; 1493 + 1494 + end = block_group->key.objectid + block_group->key.offset; 1495 + 1496 + while (1) { 1497 + ret = btrfs_next_item(root, path); 1498 + if (ret < 0) 1499 + goto out; 1500 + if (ret) 1501 + break; 1502 + 1503 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 1504 + 1505 + if (key.type == BTRFS_FREE_SPACE_INFO_KEY) 1506 + break; 1507 + 1508 + ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY); 1509 + ASSERT(key.objectid < end && key.objectid + key.offset <= end); 1510 + 1511 + caching_ctl->progress = key.objectid; 1512 + 1513 + total_found += add_new_free_space(block_group, fs_info, 1514 + key.objectid, 1515 + key.objectid + key.offset); 1516 + if (total_found > CACHING_CTL_WAKE_UP) { 1517 + total_found = 0; 1518 + wake_up(&caching_ctl->wait); 1519 + } 1520 + extent_count++; 1521 + } 1522 + 1523 + if (extent_count != expected_extent_count) { 1524 + btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u", 1525 + block_group->key.objectid, extent_count, 1526 + expected_extent_count); 1527 + ASSERT(0); 1528 + ret = -EIO; 1529 + goto out; 1530 + } 1531 + 1532 + caching_ctl->progress = (u64)-1; 1533 + 1534 + ret = 0; 1535 + out: 1536 + return ret; 1537 + } 1538 + 1539 + int load_free_space_tree(struct btrfs_caching_control *caching_ctl) 1540 + { 1541 + struct btrfs_block_group_cache *block_group; 1542 + struct btrfs_fs_info *fs_info; 1543 + struct btrfs_free_space_info *info; 1544 + struct btrfs_path *path; 1545 + u32 extent_count, flags; 1546 + int ret; 1547 + 1548 + block_group = caching_ctl->block_group; 1549 + fs_info = block_group->fs_info; 1550 + 1551 + path = btrfs_alloc_path(); 1552 + if (!path) 1553 + return -ENOMEM; 1554 + 1555 + /* 1556 + * Just like caching_thread() doesn't want to deadlock on the extent 1557 + * tree, we don't want to deadlock on the free space tree. 1558 + */ 1559 + path->skip_locking = 1; 1560 + path->search_commit_root = 1; 1561 + path->reada = 1; 1562 + 1563 + info = search_free_space_info(NULL, fs_info, block_group, path, 0); 1564 + if (IS_ERR(info)) { 1565 + ret = PTR_ERR(info); 1566 + goto out; 1567 + } 1568 + extent_count = btrfs_free_space_extent_count(path->nodes[0], info); 1569 + flags = btrfs_free_space_flags(path->nodes[0], info); 1570 + 1571 + /* 1572 + * We left path pointing to the free space info item, so now 1573 + * load_free_space_foo can just iterate through the free space tree from 1574 + * there. 1575 + */ 1576 + if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) 1577 + ret = load_free_space_bitmaps(caching_ctl, path, extent_count); 1578 + else 1579 + ret = load_free_space_extents(caching_ctl, path, extent_count); 1580 + 1581 + out: 1582 + btrfs_free_path(path); 1583 + return ret; 1584 + }
+72
fs/btrfs/free-space-tree.h
··· 1 + /* 2 + * Copyright (C) 2015 Facebook. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public 6 + * License v2 as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 + * General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public 14 + * License along with this program; if not, write to the 15 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 + * Boston, MA 021110-1307, USA. 17 + */ 18 + 19 + #ifndef __BTRFS_FREE_SPACE_TREE 20 + #define __BTRFS_FREE_SPACE_TREE 21 + 22 + /* 23 + * The default size for new free space bitmap items. The last bitmap in a block 24 + * group may be truncated, and none of the free space tree code assumes that 25 + * existing bitmaps are this size. 26 + */ 27 + #define BTRFS_FREE_SPACE_BITMAP_SIZE 256 28 + #define BTRFS_FREE_SPACE_BITMAP_BITS (BTRFS_FREE_SPACE_BITMAP_SIZE * BITS_PER_BYTE) 29 + 30 + void set_free_space_tree_thresholds(struct btrfs_block_group_cache *block_group); 31 + int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info); 32 + int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info); 33 + int load_free_space_tree(struct btrfs_caching_control *caching_ctl); 34 + int add_block_group_free_space(struct btrfs_trans_handle *trans, 35 + struct btrfs_fs_info *fs_info, 36 + struct btrfs_block_group_cache *block_group); 37 + int remove_block_group_free_space(struct btrfs_trans_handle *trans, 38 + struct btrfs_fs_info *fs_info, 39 + struct btrfs_block_group_cache *block_group); 40 + int add_to_free_space_tree(struct btrfs_trans_handle *trans, 41 + struct btrfs_fs_info *fs_info, 42 + u64 start, u64 size); 43 + int remove_from_free_space_tree(struct btrfs_trans_handle *trans, 44 + struct btrfs_fs_info *fs_info, 45 + u64 start, u64 size); 46 + 47 + /* Exposed for testing. */ 48 + struct btrfs_free_space_info * 49 + search_free_space_info(struct btrfs_trans_handle *trans, 50 + struct btrfs_fs_info *fs_info, 51 + struct btrfs_block_group_cache *block_group, 52 + struct btrfs_path *path, int cow); 53 + int __add_to_free_space_tree(struct btrfs_trans_handle *trans, 54 + struct btrfs_fs_info *fs_info, 55 + struct btrfs_block_group_cache *block_group, 56 + struct btrfs_path *path, u64 start, u64 size); 57 + int __remove_from_free_space_tree(struct btrfs_trans_handle *trans, 58 + struct btrfs_fs_info *fs_info, 59 + struct btrfs_block_group_cache *block_group, 60 + struct btrfs_path *path, u64 start, u64 size); 61 + int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans, 62 + struct btrfs_fs_info *fs_info, 63 + struct btrfs_block_group_cache *block_group, 64 + struct btrfs_path *path); 65 + int convert_free_space_to_extents(struct btrfs_trans_handle *trans, 66 + struct btrfs_fs_info *fs_info, 67 + struct btrfs_block_group_cache *block_group, 68 + struct btrfs_path *path); 69 + int free_space_test_bit(struct btrfs_block_group_cache *block_group, 70 + struct btrfs_path *path, u64 offset); 71 + 72 + #endif
+47 -9
fs/btrfs/super.c
··· 295 295 Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress, 296 296 Opt_compress_type, Opt_compress_force, Opt_compress_force_type, 297 297 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard, 298 - Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed, 299 - Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache, 300 - Opt_no_space_cache, Opt_recovery, Opt_skip_balance, 301 - Opt_check_integrity, Opt_check_integrity_including_extent_data, 298 + Opt_space_cache, Opt_space_cache_version, Opt_clear_cache, 299 + Opt_user_subvol_rm_allowed, Opt_enospc_debug, Opt_subvolrootid, 300 + Opt_defrag, Opt_inode_cache, Opt_no_space_cache, Opt_recovery, 301 + Opt_skip_balance, Opt_check_integrity, 302 + Opt_check_integrity_including_extent_data, 302 303 Opt_check_integrity_print_mask, Opt_fatal_errors, Opt_rescan_uuid_tree, 303 304 Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard, 304 305 Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow, ··· 341 340 {Opt_discard, "discard"}, 342 341 {Opt_nodiscard, "nodiscard"}, 343 342 {Opt_space_cache, "space_cache"}, 343 + {Opt_space_cache_version, "space_cache=%s"}, 344 344 {Opt_clear_cache, "clear_cache"}, 345 345 {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"}, 346 346 {Opt_enospc_debug, "enospc_debug"}, ··· 385 383 bool compress_force = false; 386 384 387 385 cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy); 388 - if (cache_gen) 386 + if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE)) 387 + btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE); 388 + else if (cache_gen) 389 389 btrfs_set_opt(info->mount_opt, SPACE_CACHE); 390 390 391 391 if (!options) ··· 621 617 "turning off discard"); 622 618 break; 623 619 case Opt_space_cache: 624 - btrfs_set_and_info(root, SPACE_CACHE, 625 - "enabling disk space caching"); 620 + case Opt_space_cache_version: 621 + if (token == Opt_space_cache || 622 + strcmp(args[0].from, "v1") == 0) { 623 + btrfs_clear_opt(root->fs_info->mount_opt, 624 + FREE_SPACE_TREE); 625 + btrfs_set_and_info(root, SPACE_CACHE, 626 + "enabling disk space caching"); 627 + } else if (strcmp(args[0].from, "v2") == 0) { 628 + btrfs_clear_opt(root->fs_info->mount_opt, 629 + SPACE_CACHE); 630 + btrfs_set_and_info(root, FREE_SPACE_TREE, 631 + "enabling free space tree"); 632 + } else { 633 + ret = -EINVAL; 634 + goto out; 635 + } 626 636 break; 627 637 case Opt_rescan_uuid_tree: 628 638 btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE); 629 639 break; 630 640 case Opt_no_space_cache: 631 - btrfs_clear_and_info(root, SPACE_CACHE, 632 - "disabling disk space caching"); 641 + if (btrfs_test_opt(root, SPACE_CACHE)) { 642 + btrfs_clear_and_info(root, SPACE_CACHE, 643 + "disabling disk space caching"); 644 + } 645 + if (btrfs_test_opt(root, FREE_SPACE_TREE)) { 646 + btrfs_clear_and_info(root, FREE_SPACE_TREE, 647 + "disabling free space tree"); 648 + } 633 649 break; 634 650 case Opt_inode_cache: 635 651 btrfs_set_pending_and_info(info, INODE_MAP_CACHE, ··· 778 754 } 779 755 } 780 756 out: 757 + if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) && 758 + !btrfs_test_opt(root, FREE_SPACE_TREE) && 759 + !btrfs_test_opt(root, CLEAR_CACHE)) { 760 + btrfs_err(root->fs_info, "cannot disable free space tree"); 761 + ret = -EINVAL; 762 + 763 + } 781 764 if (!ret && btrfs_test_opt(root, SPACE_CACHE)) 782 765 btrfs_info(root->fs_info, "disk space caching is enabled"); 766 + if (!ret && btrfs_test_opt(root, FREE_SPACE_TREE)) 767 + btrfs_info(root->fs_info, "using free space tree"); 783 768 kfree(orig); 784 769 return ret; 785 770 } ··· 1195 1162 seq_puts(seq, ",noacl"); 1196 1163 if (btrfs_test_opt(root, SPACE_CACHE)) 1197 1164 seq_puts(seq, ",space_cache"); 1165 + else if (btrfs_test_opt(root, FREE_SPACE_TREE)) 1166 + seq_puts(seq, ",space_cache=v2"); 1198 1167 else 1199 1168 seq_puts(seq, ",nospace_cache"); 1200 1169 if (btrfs_test_opt(root, RESCAN_UUID_TREE)) ··· 2260 2225 if (ret) 2261 2226 goto out; 2262 2227 ret = btrfs_test_qgroups(); 2228 + if (ret) 2229 + goto out; 2230 + ret = btrfs_test_free_space_tree(); 2263 2231 out: 2264 2232 btrfs_destroy_test_fs(); 2265 2233 return ret;
+58
fs/btrfs/tests/btrfs-tests.c
··· 21 21 #include <linux/magic.h> 22 22 #include "btrfs-tests.h" 23 23 #include "../ctree.h" 24 + #include "../free-space-cache.h" 25 + #include "../free-space-tree.h" 26 + #include "../transaction.h" 24 27 #include "../volumes.h" 25 28 #include "../disk-io.h" 26 29 #include "../qgroup.h" ··· 125 122 INIT_LIST_HEAD(&fs_info->tree_mod_seq_list); 126 123 INIT_RADIX_TREE(&fs_info->buffer_radix, GFP_ATOMIC); 127 124 INIT_RADIX_TREE(&fs_info->fs_roots_radix, GFP_ATOMIC); 125 + extent_io_tree_init(&fs_info->freed_extents[0], NULL); 126 + extent_io_tree_init(&fs_info->freed_extents[1], NULL); 127 + fs_info->pinned_extents = &fs_info->freed_extents[0]; 128 128 return fs_info; 129 129 } 130 130 ··· 175 169 kfree(root); 176 170 } 177 171 172 + struct btrfs_block_group_cache * 173 + btrfs_alloc_dummy_block_group(unsigned long length) 174 + { 175 + struct btrfs_block_group_cache *cache; 176 + 177 + cache = kzalloc(sizeof(*cache), GFP_NOFS); 178 + if (!cache) 179 + return NULL; 180 + cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), 181 + GFP_NOFS); 182 + if (!cache->free_space_ctl) { 183 + kfree(cache); 184 + return NULL; 185 + } 186 + cache->fs_info = btrfs_alloc_dummy_fs_info(); 187 + if (!cache->fs_info) { 188 + kfree(cache->free_space_ctl); 189 + kfree(cache); 190 + return NULL; 191 + } 192 + 193 + cache->key.objectid = 0; 194 + cache->key.offset = length; 195 + cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; 196 + cache->sectorsize = 4096; 197 + cache->full_stripe_len = 4096; 198 + 199 + INIT_LIST_HEAD(&cache->list); 200 + INIT_LIST_HEAD(&cache->cluster_list); 201 + INIT_LIST_HEAD(&cache->bg_list); 202 + btrfs_init_free_space_ctl(cache); 203 + mutex_init(&cache->free_space_lock); 204 + 205 + return cache; 206 + } 207 + 208 + void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache) 209 + { 210 + if (!cache) 211 + return; 212 + __btrfs_remove_free_space_cache(cache->free_space_ctl); 213 + kfree(cache->free_space_ctl); 214 + kfree(cache); 215 + } 216 + 217 + void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans) 218 + { 219 + memset(trans, 0, sizeof(*trans)); 220 + trans->transid = 1; 221 + INIT_LIST_HEAD(&trans->qgroup_ref_list); 222 + trans->type = __TRANS_DUMMY; 223 + }
+10
fs/btrfs/tests/btrfs-tests.h
··· 24 24 #define test_msg(fmt, ...) pr_info("BTRFS: selftest: " fmt, ##__VA_ARGS__) 25 25 26 26 struct btrfs_root; 27 + struct btrfs_trans_handle; 27 28 28 29 int btrfs_test_free_space_cache(void); 29 30 int btrfs_test_extent_buffer_operations(void); 30 31 int btrfs_test_extent_io(void); 31 32 int btrfs_test_inodes(void); 32 33 int btrfs_test_qgroups(void); 34 + int btrfs_test_free_space_tree(void); 33 35 int btrfs_init_test_fs(void); 34 36 void btrfs_destroy_test_fs(void); 35 37 struct inode *btrfs_new_test_inode(void); 36 38 struct btrfs_fs_info *btrfs_alloc_dummy_fs_info(void); 37 39 void btrfs_free_dummy_root(struct btrfs_root *root); 40 + struct btrfs_block_group_cache * 41 + btrfs_alloc_dummy_block_group(unsigned long length); 42 + void btrfs_free_dummy_block_group(struct btrfs_block_group_cache *cache); 43 + void btrfs_init_dummy_trans(struct btrfs_trans_handle *trans); 38 44 #else 39 45 static inline int btrfs_test_free_space_cache(void) 40 46 { ··· 66 60 return 0; 67 61 } 68 62 static inline int btrfs_test_qgroups(void) 63 + { 64 + return 0; 65 + } 66 + static inline int btrfs_test_free_space_tree(void) 69 67 { 70 68 return 0; 71 69 }
+136 -2
fs/btrfs/tests/extent-io-tests.c
··· 18 18 19 19 #include <linux/pagemap.h> 20 20 #include <linux/sched.h> 21 + #include <linux/slab.h> 21 22 #include "btrfs-tests.h" 22 23 #include "../extent_io.h" 23 24 ··· 76 75 u64 start, end, test_start; 77 76 u64 found; 78 77 int ret = -EINVAL; 78 + 79 + test_msg("Running find delalloc tests\n"); 79 80 80 81 inode = btrfs_new_test_inode(); 81 82 if (!inode) { ··· 271 268 return ret; 272 269 } 273 270 271 + static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb, 272 + unsigned long len) 273 + { 274 + unsigned long i, x; 275 + 276 + memset(bitmap, 0, len); 277 + memset_extent_buffer(eb, 0, 0, len); 278 + if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 279 + test_msg("Bitmap was not zeroed\n"); 280 + return -EINVAL; 281 + } 282 + 283 + bitmap_set(bitmap, 0, len * BITS_PER_BYTE); 284 + extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); 285 + if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 286 + test_msg("Setting all bits failed\n"); 287 + return -EINVAL; 288 + } 289 + 290 + bitmap_clear(bitmap, 0, len * BITS_PER_BYTE); 291 + extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE); 292 + if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 293 + test_msg("Clearing all bits failed\n"); 294 + return -EINVAL; 295 + } 296 + 297 + bitmap_set(bitmap, (PAGE_CACHE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, 298 + sizeof(long) * BITS_PER_BYTE); 299 + extent_buffer_bitmap_set(eb, PAGE_CACHE_SIZE - sizeof(long) / 2, 0, 300 + sizeof(long) * BITS_PER_BYTE); 301 + if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 302 + test_msg("Setting straddling pages failed\n"); 303 + return -EINVAL; 304 + } 305 + 306 + bitmap_set(bitmap, 0, len * BITS_PER_BYTE); 307 + bitmap_clear(bitmap, 308 + (PAGE_CACHE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE, 309 + sizeof(long) * BITS_PER_BYTE); 310 + extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE); 311 + extent_buffer_bitmap_clear(eb, PAGE_CACHE_SIZE - sizeof(long) / 2, 0, 312 + sizeof(long) * BITS_PER_BYTE); 313 + if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) { 314 + test_msg("Clearing straddling pages failed\n"); 315 + return -EINVAL; 316 + } 317 + 318 + /* 319 + * Generate a wonky pseudo-random bit pattern for the sake of not using 320 + * something repetitive that could miss some hypothetical off-by-n bug. 321 + */ 322 + x = 0; 323 + for (i = 0; i < len / sizeof(long); i++) { 324 + x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffUL; 325 + bitmap[i] = x; 326 + } 327 + write_extent_buffer(eb, bitmap, 0, len); 328 + 329 + for (i = 0; i < len * BITS_PER_BYTE; i++) { 330 + int bit, bit1; 331 + 332 + bit = !!test_bit(i, bitmap); 333 + bit1 = !!extent_buffer_test_bit(eb, 0, i); 334 + if (bit1 != bit) { 335 + test_msg("Testing bit pattern failed\n"); 336 + return -EINVAL; 337 + } 338 + 339 + bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE, 340 + i % BITS_PER_BYTE); 341 + if (bit1 != bit) { 342 + test_msg("Testing bit pattern with offset failed\n"); 343 + return -EINVAL; 344 + } 345 + } 346 + 347 + return 0; 348 + } 349 + 350 + static int test_eb_bitmaps(void) 351 + { 352 + unsigned long len = PAGE_CACHE_SIZE * 4; 353 + unsigned long *bitmap; 354 + struct extent_buffer *eb; 355 + int ret; 356 + 357 + test_msg("Running extent buffer bitmap tests\n"); 358 + 359 + bitmap = kmalloc(len, GFP_NOFS); 360 + if (!bitmap) { 361 + test_msg("Couldn't allocate test bitmap\n"); 362 + return -ENOMEM; 363 + } 364 + 365 + eb = __alloc_dummy_extent_buffer(NULL, 0, len); 366 + if (!eb) { 367 + test_msg("Couldn't allocate test extent buffer\n"); 368 + kfree(bitmap); 369 + return -ENOMEM; 370 + } 371 + 372 + ret = __test_eb_bitmaps(bitmap, eb, len); 373 + if (ret) 374 + goto out; 375 + 376 + /* Do it over again with an extent buffer which isn't page-aligned. */ 377 + free_extent_buffer(eb); 378 + eb = __alloc_dummy_extent_buffer(NULL, PAGE_CACHE_SIZE / 2, len); 379 + if (!eb) { 380 + test_msg("Couldn't allocate test extent buffer\n"); 381 + kfree(bitmap); 382 + return -ENOMEM; 383 + } 384 + 385 + ret = __test_eb_bitmaps(bitmap, eb, len); 386 + out: 387 + free_extent_buffer(eb); 388 + kfree(bitmap); 389 + return ret; 390 + } 391 + 274 392 int btrfs_test_extent_io(void) 275 393 { 276 - test_msg("Running find delalloc tests\n"); 277 - return test_find_delalloc(); 394 + int ret; 395 + 396 + test_msg("Running extent I/O tests\n"); 397 + 398 + ret = test_find_delalloc(); 399 + if (ret) 400 + goto out; 401 + 402 + ret = test_eb_bitmaps(); 403 + out: 404 + test_msg("Extent I/O tests finished\n"); 405 + return ret; 278 406 }
+2 -39
fs/btrfs/tests/free-space-tests.c
··· 23 23 #include "../free-space-cache.h" 24 24 25 25 #define BITS_PER_BITMAP (PAGE_CACHE_SIZE * 8) 26 - static struct btrfs_block_group_cache *init_test_block_group(void) 27 - { 28 - struct btrfs_block_group_cache *cache; 29 - 30 - cache = kzalloc(sizeof(*cache), GFP_NOFS); 31 - if (!cache) 32 - return NULL; 33 - cache->free_space_ctl = kzalloc(sizeof(*cache->free_space_ctl), 34 - GFP_NOFS); 35 - if (!cache->free_space_ctl) { 36 - kfree(cache); 37 - return NULL; 38 - } 39 - cache->fs_info = btrfs_alloc_dummy_fs_info(); 40 - if (!cache->fs_info) { 41 - kfree(cache->free_space_ctl); 42 - kfree(cache); 43 - return NULL; 44 - } 45 - 46 - cache->key.objectid = 0; 47 - cache->key.offset = 1024 * 1024 * 1024; 48 - cache->key.type = BTRFS_BLOCK_GROUP_ITEM_KEY; 49 - cache->sectorsize = 4096; 50 - cache->full_stripe_len = 4096; 51 - 52 - spin_lock_init(&cache->lock); 53 - INIT_LIST_HEAD(&cache->list); 54 - INIT_LIST_HEAD(&cache->cluster_list); 55 - INIT_LIST_HEAD(&cache->bg_list); 56 - 57 - btrfs_init_free_space_ctl(cache); 58 - 59 - return cache; 60 - } 61 26 62 27 /* 63 28 * This test just does basic sanity checking, making sure we can add an exten ··· 856 891 857 892 test_msg("Running btrfs free space cache tests\n"); 858 893 859 - cache = init_test_block_group(); 894 + cache = btrfs_alloc_dummy_block_group(1024 * 1024 * 1024); 860 895 if (!cache) { 861 896 test_msg("Couldn't run the tests\n"); 862 897 return 0; ··· 887 922 888 923 ret = test_steal_space_from_bitmap_to_extent(cache); 889 924 out: 890 - __btrfs_remove_free_space_cache(cache->free_space_ctl); 891 - kfree(cache->free_space_ctl); 892 - kfree(cache); 925 + btrfs_free_dummy_block_group(cache); 893 926 btrfs_free_dummy_root(root); 894 927 test_msg("Free space cache tests finished\n"); 895 928 return ret;
+571
fs/btrfs/tests/free-space-tree-tests.c
··· 1 + /* 2 + * Copyright (C) 2015 Facebook. All rights reserved. 3 + * 4 + * This program is free software; you can redistribute it and/or 5 + * modify it under the terms of the GNU General Public 6 + * License v2 as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 + * General Public License for more details. 12 + * 13 + * You should have received a copy of the GNU General Public 14 + * License along with this program; if not, write to the 15 + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 + * Boston, MA 021110-1307, USA. 17 + */ 18 + 19 + #include "btrfs-tests.h" 20 + #include "../ctree.h" 21 + #include "../disk-io.h" 22 + #include "../free-space-tree.h" 23 + #include "../transaction.h" 24 + 25 + struct free_space_extent { 26 + u64 start, length; 27 + }; 28 + 29 + /* 30 + * The test cases align their operations to this in order to hit some of the 31 + * edge cases in the bitmap code. 32 + */ 33 + #define BITMAP_RANGE (BTRFS_FREE_SPACE_BITMAP_BITS * 4096) 34 + 35 + static int __check_free_space_extents(struct btrfs_trans_handle *trans, 36 + struct btrfs_fs_info *fs_info, 37 + struct btrfs_block_group_cache *cache, 38 + struct btrfs_path *path, 39 + struct free_space_extent *extents, 40 + unsigned int num_extents) 41 + { 42 + struct btrfs_free_space_info *info; 43 + struct btrfs_key key; 44 + int prev_bit = 0, bit; 45 + u64 extent_start = 0, offset, end; 46 + u32 flags, extent_count; 47 + unsigned int i; 48 + int ret; 49 + 50 + info = search_free_space_info(trans, fs_info, cache, path, 0); 51 + if (IS_ERR(info)) { 52 + test_msg("Could not find free space info\n"); 53 + ret = PTR_ERR(info); 54 + goto out; 55 + } 56 + flags = btrfs_free_space_flags(path->nodes[0], info); 57 + extent_count = btrfs_free_space_extent_count(path->nodes[0], info); 58 + 59 + if (extent_count != num_extents) { 60 + test_msg("Extent count is wrong\n"); 61 + ret = -EINVAL; 62 + goto out; 63 + } 64 + if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) { 65 + if (path->slots[0] != 0) 66 + goto invalid; 67 + end = cache->key.objectid + cache->key.offset; 68 + i = 0; 69 + while (++path->slots[0] < btrfs_header_nritems(path->nodes[0])) { 70 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 71 + if (key.type != BTRFS_FREE_SPACE_BITMAP_KEY) 72 + goto invalid; 73 + offset = key.objectid; 74 + while (offset < key.objectid + key.offset) { 75 + bit = free_space_test_bit(cache, path, offset); 76 + if (prev_bit == 0 && bit == 1) { 77 + extent_start = offset; 78 + } else if (prev_bit == 1 && bit == 0) { 79 + if (i >= num_extents) 80 + goto invalid; 81 + if (i >= num_extents || 82 + extent_start != extents[i].start || 83 + offset - extent_start != extents[i].length) 84 + goto invalid; 85 + i++; 86 + } 87 + prev_bit = bit; 88 + offset += cache->sectorsize; 89 + } 90 + } 91 + if (prev_bit == 1) { 92 + if (i >= num_extents || 93 + extent_start != extents[i].start || 94 + end - extent_start != extents[i].length) 95 + goto invalid; 96 + i++; 97 + } 98 + if (i != num_extents) 99 + goto invalid; 100 + } else { 101 + if (btrfs_header_nritems(path->nodes[0]) != num_extents + 1 || 102 + path->slots[0] != 0) 103 + goto invalid; 104 + for (i = 0; i < num_extents; i++) { 105 + path->slots[0]++; 106 + btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]); 107 + if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY || 108 + key.objectid != extents[i].start || 109 + key.offset != extents[i].length) 110 + goto invalid; 111 + } 112 + } 113 + 114 + ret = 0; 115 + out: 116 + btrfs_release_path(path); 117 + return ret; 118 + invalid: 119 + test_msg("Free space tree is invalid\n"); 120 + ret = -EINVAL; 121 + goto out; 122 + } 123 + 124 + static int check_free_space_extents(struct btrfs_trans_handle *trans, 125 + struct btrfs_fs_info *fs_info, 126 + struct btrfs_block_group_cache *cache, 127 + struct btrfs_path *path, 128 + struct free_space_extent *extents, 129 + unsigned int num_extents) 130 + { 131 + struct btrfs_free_space_info *info; 132 + u32 flags; 133 + int ret; 134 + 135 + info = search_free_space_info(trans, fs_info, cache, path, 0); 136 + if (IS_ERR(info)) { 137 + test_msg("Could not find free space info\n"); 138 + btrfs_release_path(path); 139 + return PTR_ERR(info); 140 + } 141 + flags = btrfs_free_space_flags(path->nodes[0], info); 142 + btrfs_release_path(path); 143 + 144 + ret = __check_free_space_extents(trans, fs_info, cache, path, extents, 145 + num_extents); 146 + if (ret) 147 + return ret; 148 + 149 + /* Flip it to the other format and check that for good measure. */ 150 + if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) { 151 + ret = convert_free_space_to_extents(trans, fs_info, cache, path); 152 + if (ret) { 153 + test_msg("Could not convert to extents\n"); 154 + return ret; 155 + } 156 + } else { 157 + ret = convert_free_space_to_bitmaps(trans, fs_info, cache, path); 158 + if (ret) { 159 + test_msg("Could not convert to bitmaps\n"); 160 + return ret; 161 + } 162 + } 163 + return __check_free_space_extents(trans, fs_info, cache, path, extents, 164 + num_extents); 165 + } 166 + 167 + static int test_empty_block_group(struct btrfs_trans_handle *trans, 168 + struct btrfs_fs_info *fs_info, 169 + struct btrfs_block_group_cache *cache, 170 + struct btrfs_path *path) 171 + { 172 + struct free_space_extent extents[] = { 173 + {cache->key.objectid, cache->key.offset}, 174 + }; 175 + 176 + return check_free_space_extents(trans, fs_info, cache, path, 177 + extents, ARRAY_SIZE(extents)); 178 + } 179 + 180 + static int test_remove_all(struct btrfs_trans_handle *trans, 181 + struct btrfs_fs_info *fs_info, 182 + struct btrfs_block_group_cache *cache, 183 + struct btrfs_path *path) 184 + { 185 + struct free_space_extent extents[] = {}; 186 + int ret; 187 + 188 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 189 + cache->key.objectid, 190 + cache->key.offset); 191 + if (ret) { 192 + test_msg("Could not remove free space\n"); 193 + return ret; 194 + } 195 + 196 + return check_free_space_extents(trans, fs_info, cache, path, 197 + extents, ARRAY_SIZE(extents)); 198 + } 199 + 200 + static int test_remove_beginning(struct btrfs_trans_handle *trans, 201 + struct btrfs_fs_info *fs_info, 202 + struct btrfs_block_group_cache *cache, 203 + struct btrfs_path *path) 204 + { 205 + struct free_space_extent extents[] = { 206 + {cache->key.objectid + BITMAP_RANGE, 207 + cache->key.offset - BITMAP_RANGE}, 208 + }; 209 + int ret; 210 + 211 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 212 + cache->key.objectid, BITMAP_RANGE); 213 + if (ret) { 214 + test_msg("Could not remove free space\n"); 215 + return ret; 216 + } 217 + 218 + return check_free_space_extents(trans, fs_info, cache, path, 219 + extents, ARRAY_SIZE(extents)); 220 + 221 + } 222 + 223 + static int test_remove_end(struct btrfs_trans_handle *trans, 224 + struct btrfs_fs_info *fs_info, 225 + struct btrfs_block_group_cache *cache, 226 + struct btrfs_path *path) 227 + { 228 + struct free_space_extent extents[] = { 229 + {cache->key.objectid, cache->key.offset - BITMAP_RANGE}, 230 + }; 231 + int ret; 232 + 233 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 234 + cache->key.objectid + 235 + cache->key.offset - BITMAP_RANGE, 236 + BITMAP_RANGE); 237 + if (ret) { 238 + test_msg("Could not remove free space\n"); 239 + return ret; 240 + } 241 + 242 + return check_free_space_extents(trans, fs_info, cache, path, 243 + extents, ARRAY_SIZE(extents)); 244 + } 245 + 246 + static int test_remove_middle(struct btrfs_trans_handle *trans, 247 + struct btrfs_fs_info *fs_info, 248 + struct btrfs_block_group_cache *cache, 249 + struct btrfs_path *path) 250 + { 251 + struct free_space_extent extents[] = { 252 + {cache->key.objectid, BITMAP_RANGE}, 253 + {cache->key.objectid + 2 * BITMAP_RANGE, 254 + cache->key.offset - 2 * BITMAP_RANGE}, 255 + }; 256 + int ret; 257 + 258 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 259 + cache->key.objectid + BITMAP_RANGE, 260 + BITMAP_RANGE); 261 + if (ret) { 262 + test_msg("Could not remove free space\n"); 263 + return ret; 264 + } 265 + 266 + return check_free_space_extents(trans, fs_info, cache, path, 267 + extents, ARRAY_SIZE(extents)); 268 + } 269 + 270 + static int test_merge_left(struct btrfs_trans_handle *trans, 271 + struct btrfs_fs_info *fs_info, 272 + struct btrfs_block_group_cache *cache, 273 + struct btrfs_path *path) 274 + { 275 + struct free_space_extent extents[] = { 276 + {cache->key.objectid, 2 * BITMAP_RANGE}, 277 + }; 278 + int ret; 279 + 280 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 281 + cache->key.objectid, 282 + cache->key.offset); 283 + if (ret) { 284 + test_msg("Could not remove free space\n"); 285 + return ret; 286 + } 287 + 288 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 289 + cache->key.objectid, BITMAP_RANGE); 290 + if (ret) { 291 + test_msg("Could not add free space\n"); 292 + return ret; 293 + } 294 + 295 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 296 + cache->key.objectid + BITMAP_RANGE, 297 + BITMAP_RANGE); 298 + if (ret) { 299 + test_msg("Could not add free space\n"); 300 + return ret; 301 + } 302 + 303 + return check_free_space_extents(trans, fs_info, cache, path, 304 + extents, ARRAY_SIZE(extents)); 305 + } 306 + 307 + static int test_merge_right(struct btrfs_trans_handle *trans, 308 + struct btrfs_fs_info *fs_info, 309 + struct btrfs_block_group_cache *cache, 310 + struct btrfs_path *path) 311 + { 312 + struct free_space_extent extents[] = { 313 + {cache->key.objectid + BITMAP_RANGE, 2 * BITMAP_RANGE}, 314 + }; 315 + int ret; 316 + 317 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 318 + cache->key.objectid, 319 + cache->key.offset); 320 + if (ret) { 321 + test_msg("Could not remove free space\n"); 322 + return ret; 323 + } 324 + 325 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 326 + cache->key.objectid + 2 * BITMAP_RANGE, 327 + BITMAP_RANGE); 328 + if (ret) { 329 + test_msg("Could not add free space\n"); 330 + return ret; 331 + } 332 + 333 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 334 + cache->key.objectid + BITMAP_RANGE, 335 + BITMAP_RANGE); 336 + if (ret) { 337 + test_msg("Could not add free space\n"); 338 + return ret; 339 + } 340 + 341 + return check_free_space_extents(trans, fs_info, cache, path, 342 + extents, ARRAY_SIZE(extents)); 343 + } 344 + 345 + static int test_merge_both(struct btrfs_trans_handle *trans, 346 + struct btrfs_fs_info *fs_info, 347 + struct btrfs_block_group_cache *cache, 348 + struct btrfs_path *path) 349 + { 350 + struct free_space_extent extents[] = { 351 + {cache->key.objectid, 3 * BITMAP_RANGE}, 352 + }; 353 + int ret; 354 + 355 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 356 + cache->key.objectid, 357 + cache->key.offset); 358 + if (ret) { 359 + test_msg("Could not remove free space\n"); 360 + return ret; 361 + } 362 + 363 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 364 + cache->key.objectid, BITMAP_RANGE); 365 + if (ret) { 366 + test_msg("Could not add free space\n"); 367 + return ret; 368 + } 369 + 370 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 371 + cache->key.objectid + 2 * BITMAP_RANGE, 372 + BITMAP_RANGE); 373 + if (ret) { 374 + test_msg("Could not add free space\n"); 375 + return ret; 376 + } 377 + 378 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 379 + cache->key.objectid + BITMAP_RANGE, 380 + BITMAP_RANGE); 381 + if (ret) { 382 + test_msg("Could not add free space\n"); 383 + return ret; 384 + } 385 + 386 + return check_free_space_extents(trans, fs_info, cache, path, 387 + extents, ARRAY_SIZE(extents)); 388 + } 389 + 390 + static int test_merge_none(struct btrfs_trans_handle *trans, 391 + struct btrfs_fs_info *fs_info, 392 + struct btrfs_block_group_cache *cache, 393 + struct btrfs_path *path) 394 + { 395 + struct free_space_extent extents[] = { 396 + {cache->key.objectid, BITMAP_RANGE}, 397 + {cache->key.objectid + 2 * BITMAP_RANGE, BITMAP_RANGE}, 398 + {cache->key.objectid + 4 * BITMAP_RANGE, BITMAP_RANGE}, 399 + }; 400 + int ret; 401 + 402 + ret = __remove_from_free_space_tree(trans, fs_info, cache, path, 403 + cache->key.objectid, 404 + cache->key.offset); 405 + if (ret) { 406 + test_msg("Could not remove free space\n"); 407 + return ret; 408 + } 409 + 410 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 411 + cache->key.objectid, BITMAP_RANGE); 412 + if (ret) { 413 + test_msg("Could not add free space\n"); 414 + return ret; 415 + } 416 + 417 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 418 + cache->key.objectid + 4 * BITMAP_RANGE, 419 + BITMAP_RANGE); 420 + if (ret) { 421 + test_msg("Could not add free space\n"); 422 + return ret; 423 + } 424 + 425 + ret = __add_to_free_space_tree(trans, fs_info, cache, path, 426 + cache->key.objectid + 2 * BITMAP_RANGE, 427 + BITMAP_RANGE); 428 + if (ret) { 429 + test_msg("Could not add free space\n"); 430 + return ret; 431 + } 432 + 433 + return check_free_space_extents(trans, fs_info, cache, path, 434 + extents, ARRAY_SIZE(extents)); 435 + } 436 + 437 + typedef int (*test_func_t)(struct btrfs_trans_handle *, 438 + struct btrfs_fs_info *, 439 + struct btrfs_block_group_cache *, 440 + struct btrfs_path *); 441 + 442 + static int run_test(test_func_t test_func, int bitmaps) 443 + { 444 + struct btrfs_root *root = NULL; 445 + struct btrfs_block_group_cache *cache = NULL; 446 + struct btrfs_trans_handle trans; 447 + struct btrfs_path *path = NULL; 448 + int ret; 449 + 450 + root = btrfs_alloc_dummy_root(); 451 + if (IS_ERR(root)) { 452 + test_msg("Couldn't allocate dummy root\n"); 453 + ret = PTR_ERR(root); 454 + goto out; 455 + } 456 + 457 + root->fs_info = btrfs_alloc_dummy_fs_info(); 458 + if (!root->fs_info) { 459 + test_msg("Couldn't allocate dummy fs info\n"); 460 + ret = -ENOMEM; 461 + goto out; 462 + } 463 + 464 + btrfs_set_super_compat_ro_flags(root->fs_info->super_copy, 465 + BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE); 466 + root->fs_info->free_space_root = root; 467 + root->fs_info->tree_root = root; 468 + 469 + root->node = alloc_test_extent_buffer(root->fs_info, 4096); 470 + if (!root->node) { 471 + test_msg("Couldn't allocate dummy buffer\n"); 472 + ret = -ENOMEM; 473 + goto out; 474 + } 475 + btrfs_set_header_level(root->node, 0); 476 + btrfs_set_header_nritems(root->node, 0); 477 + root->alloc_bytenr += 8192; 478 + 479 + cache = btrfs_alloc_dummy_block_group(8 * BITMAP_RANGE); 480 + if (!cache) { 481 + test_msg("Couldn't allocate dummy block group cache\n"); 482 + ret = -ENOMEM; 483 + goto out; 484 + } 485 + cache->bitmap_low_thresh = 0; 486 + cache->bitmap_high_thresh = (u32)-1; 487 + cache->needs_free_space = 1; 488 + 489 + btrfs_init_dummy_trans(&trans); 490 + 491 + path = btrfs_alloc_path(); 492 + if (!path) { 493 + test_msg("Couldn't allocate path\n"); 494 + return -ENOMEM; 495 + } 496 + 497 + ret = add_block_group_free_space(&trans, root->fs_info, cache); 498 + if (ret) { 499 + test_msg("Could not add block group free space\n"); 500 + goto out; 501 + } 502 + 503 + if (bitmaps) { 504 + ret = convert_free_space_to_bitmaps(&trans, root->fs_info, 505 + cache, path); 506 + if (ret) { 507 + test_msg("Could not convert block group to bitmaps\n"); 508 + goto out; 509 + } 510 + } 511 + 512 + ret = test_func(&trans, root->fs_info, cache, path); 513 + if (ret) 514 + goto out; 515 + 516 + ret = remove_block_group_free_space(&trans, root->fs_info, cache); 517 + if (ret) { 518 + test_msg("Could not remove block group free space\n"); 519 + goto out; 520 + } 521 + 522 + if (btrfs_header_nritems(root->node) != 0) { 523 + test_msg("Free space tree has leftover items\n"); 524 + ret = -EINVAL; 525 + goto out; 526 + } 527 + 528 + ret = 0; 529 + out: 530 + btrfs_free_path(path); 531 + btrfs_free_dummy_block_group(cache); 532 + btrfs_free_dummy_root(root); 533 + return ret; 534 + } 535 + 536 + static int run_test_both_formats(test_func_t test_func) 537 + { 538 + int ret; 539 + 540 + ret = run_test(test_func, 0); 541 + if (ret) 542 + return ret; 543 + return run_test(test_func, 1); 544 + } 545 + 546 + int btrfs_test_free_space_tree(void) 547 + { 548 + test_func_t tests[] = { 549 + test_empty_block_group, 550 + test_remove_all, 551 + test_remove_beginning, 552 + test_remove_end, 553 + test_remove_middle, 554 + test_merge_left, 555 + test_merge_right, 556 + test_merge_both, 557 + test_merge_none, 558 + }; 559 + int i; 560 + 561 + test_msg("Running free space tree tests\n"); 562 + for (i = 0; i < ARRAY_SIZE(tests); i++) { 563 + int ret = run_test_both_formats(tests[i]); 564 + if (ret) { 565 + test_msg("%pf failed\n", tests[i]); 566 + return ret; 567 + } 568 + } 569 + 570 + return 0; 571 + }
+6 -14
fs/btrfs/tests/qgroup-tests.c
··· 23 23 #include "../qgroup.h" 24 24 #include "../backref.h" 25 25 26 - static void init_dummy_trans(struct btrfs_trans_handle *trans) 27 - { 28 - memset(trans, 0, sizeof(*trans)); 29 - trans->transid = 1; 30 - INIT_LIST_HEAD(&trans->qgroup_ref_list); 31 - trans->type = __TRANS_DUMMY; 32 - } 33 - 34 26 static int insert_normal_tree_ref(struct btrfs_root *root, u64 bytenr, 35 27 u64 num_bytes, u64 parent, u64 root_objectid) 36 28 { ··· 36 44 u32 size = sizeof(*item) + sizeof(*iref) + sizeof(*block_info); 37 45 int ret; 38 46 39 - init_dummy_trans(&trans); 47 + btrfs_init_dummy_trans(&trans); 40 48 41 49 ins.objectid = bytenr; 42 50 ins.type = BTRFS_EXTENT_ITEM_KEY; ··· 86 94 u64 refs; 87 95 int ret; 88 96 89 - init_dummy_trans(&trans); 97 + btrfs_init_dummy_trans(&trans); 90 98 91 99 key.objectid = bytenr; 92 100 key.type = BTRFS_EXTENT_ITEM_KEY; ··· 136 144 struct btrfs_path *path; 137 145 int ret; 138 146 139 - init_dummy_trans(&trans); 147 + btrfs_init_dummy_trans(&trans); 140 148 141 149 key.objectid = bytenr; 142 150 key.type = BTRFS_EXTENT_ITEM_KEY; ··· 170 178 u64 refs; 171 179 int ret; 172 180 173 - init_dummy_trans(&trans); 181 + btrfs_init_dummy_trans(&trans); 174 182 175 183 key.objectid = bytenr; 176 184 key.type = BTRFS_EXTENT_ITEM_KEY; ··· 224 232 struct ulist *new_roots = NULL; 225 233 int ret; 226 234 227 - init_dummy_trans(&trans); 235 + btrfs_init_dummy_trans(&trans); 228 236 229 237 test_msg("Qgroup basic add\n"); 230 238 ret = btrfs_create_qgroup(NULL, fs_info, 5); ··· 318 326 struct ulist *new_roots = NULL; 319 327 int ret; 320 328 321 - init_dummy_trans(&trans); 329 + btrfs_init_dummy_trans(&trans); 322 330 323 331 test_msg("Qgroup multiple refs test\n"); 324 332
+2 -1
include/trace/events/btrfs.h
··· 45 45 { BTRFS_TREE_LOG_OBJECTID, "TREE_LOG" }, \ 46 46 { BTRFS_QUOTA_TREE_OBJECTID, "QUOTA_TREE" }, \ 47 47 { BTRFS_TREE_RELOC_OBJECTID, "TREE_RELOC" }, \ 48 - { BTRFS_UUID_TREE_OBJECTID, "UUID_RELOC" }, \ 48 + { BTRFS_UUID_TREE_OBJECTID, "UUID_TREE" }, \ 49 + { BTRFS_FREE_SPACE_TREE_OBJECTID, "FREE_SPACE_TREE" }, \ 49 50 { BTRFS_DATA_RELOC_TREE_OBJECTID, "DATA_RELOC_TREE" }) 50 51 51 52 #define show_root_type(obj) \