···9696/* for storing items that use the BTRFS_UUID_KEY* types */9797#define BTRFS_UUID_TREE_OBJECTID 9ULL98989999+/* tracks free space in block groups. */100100+#define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL101101+99102/* for storing balance parameters in the root tree */100103#define BTRFS_BALANCE_OBJECTID -4ULL101104···503500 * Compat flags that we support. If any incompat flags are set other than the504501 * ones specified below then we will fail to mount505502 */503503+#define BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE (1ULL << 0)504504+506505#define BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF (1ULL << 0)507506#define BTRFS_FEATURE_INCOMPAT_DEFAULT_SUBVOL (1ULL << 1)508507#define BTRFS_FEATURE_INCOMPAT_MIXED_GROUPS (1ULL << 2)···531526#define BTRFS_FEATURE_COMPAT_SUPP 0ULL532527#define BTRFS_FEATURE_COMPAT_SAFE_SET 0ULL533528#define BTRFS_FEATURE_COMPAT_SAFE_CLEAR 0ULL534534-#define BTRFS_FEATURE_COMPAT_RO_SUPP 0ULL529529+530530+#define BTRFS_FEATURE_COMPAT_RO_SUPP \531531+ (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE)532532+535533#define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL536534#define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL537535···10961088 __le64 flags;10971089} __attribute__ ((__packed__));1098109010911091+struct btrfs_free_space_info {10921092+ __le32 extent_count;10931093+ __le32 flags;10941094+} __attribute__ ((__packed__));10951095+10961096+#define BTRFS_FREE_SPACE_USING_BITMAPS (1ULL << 0)10971097+10991098#define BTRFS_QGROUP_LEVEL_SHIFT 4811001099static inline u64 btrfs_qgroup_level(u64 qgroupid)11011100{···13111296 atomic_t count;13121297};1313129812991299+/* Once caching_thread() finds this much free space, it will wake up waiters. */13001300+#define CACHING_CTL_WAKE_UP (1024 * 1024 * 2)13011301+13141302struct btrfs_io_ctl {13151303 void *cur, *orig;13161304 struct page *page;···13391321 u64 delalloc_bytes;13401322 u64 bytes_super;13411323 u64 flags;13421342- u64 sectorsize;13431324 u64 cache_generation;13251325+ u32 sectorsize;13261326+13271327+ /*13281328+ * If the free space extent count exceeds this number, convert the block13291329+ * group to bitmaps.13301330+ */13311331+ u32 bitmap_high_thresh;13321332+13331333+ /*13341334+ * If the free space extent count drops below this number, convert the13351335+ * block group back to extents.13361336+ */13371337+ u32 bitmap_low_thresh;1344133813451339 /*13461340 * It is just used for the delayed data space allocation because···14081378 struct list_head io_list;1409137914101380 struct btrfs_io_ctl io_ctl;13811381+13821382+ /* Lock for free space tree operations. */13831383+ struct mutex free_space_lock;13841384+13851385+ /*13861386+ * Does the block group need to be added to the free space tree?13871387+ * Protected by free_space_lock.13881388+ */13891389+ int needs_free_space;14111390};1412139114131392/* delayed seq elem */···14681429 struct btrfs_root *csum_root;14691430 struct btrfs_root *quota_root;14701431 struct btrfs_root *uuid_root;14321432+ struct btrfs_root *free_space_root;1471143314721434 /* the log root tree is a directory of all the other log roots */14731435 struct btrfs_root *log_root_tree;···21322092 */21332093#define BTRFS_BLOCK_GROUP_ITEM_KEY 1922134209420952095+/*20962096+ * Every block group is represented in the free space tree by a free space info20972097+ * item, which stores some accounting information. It is keyed on20982098+ * (block_group_start, FREE_SPACE_INFO, block_group_length).20992099+ */21002100+#define BTRFS_FREE_SPACE_INFO_KEY 19821012101+21022102+/*21032103+ * A free space extent tracks an extent of space that is free in a block group.21042104+ * It is keyed on (start, FREE_SPACE_EXTENT, length).21052105+ */21062106+#define BTRFS_FREE_SPACE_EXTENT_KEY 19921072107+21082108+/*21092109+ * When a block group becomes very fragmented, we convert it to use bitmaps21102110+ * instead of extents. A free space bitmap is keyed on21112111+ * (start, FREE_SPACE_BITMAP, length); the corresponding item is a bitmap with21122112+ * (length / sectorsize) bits.21132113+ */21142114+#define BTRFS_FREE_SPACE_BITMAP_KEY 20021152115+21352116#define BTRFS_DEV_EXTENT_KEY 20421362117#define BTRFS_DEV_ITEM_KEY 21621372118#define BTRFS_CHUNK_ITEM_KEY 228···22452184#define BTRFS_MOUNT_RESCAN_UUID_TREE (1 << 23)22462185#define BTRFS_MOUNT_FRAGMENT_DATA (1 << 24)22472186#define BTRFS_MOUNT_FRAGMENT_METADATA (1 << 25)21872187+#define BTRFS_MOUNT_FREE_SPACE_TREE (1 << 26)2248218822492189#define BTRFS_DEFAULT_COMMIT_INTERVAL (30)22502190#define BTRFS_DEFAULT_MAX_INLINE (8192)···25672505 struct btrfs_block_group_item, flags, 64);25682506BTRFS_SETGET_STACK_FUNCS(block_group_flags,25692507 struct btrfs_block_group_item, flags, 64);25082508+25092509+/* struct btrfs_free_space_info */25102510+BTRFS_SETGET_FUNCS(free_space_extent_count, struct btrfs_free_space_info,25112511+ extent_count, 32);25122512+BTRFS_SETGET_FUNCS(free_space_flags, struct btrfs_free_space_info, flags, 32);2570251325712514/* struct btrfs_inode_ref */25722515BTRFS_SETGET_FUNCS(inode_ref_name_len, struct btrfs_inode_ref, name_len, 16);···36403573void check_system_chunk(struct btrfs_trans_handle *trans,36413574 struct btrfs_root *root,36423575 const u64 type);35763576+u64 add_new_free_space(struct btrfs_block_group_cache *block_group,35773577+ struct btrfs_fs_info *info, u64 start, u64 end);35783578+36433579/* ctree.c */36443580int btrfs_bin_search(struct extent_buffer *eb, struct btrfs_key *key,36453581 int level, int *slot);···38073737 kfree(fs_info->csum_root);38083738 kfree(fs_info->quota_root);38093739 kfree(fs_info->uuid_root);37403740+ kfree(fs_info->free_space_root);38103741 kfree(fs_info->super_copy);38113742 kfree(fs_info->super_for_commit);38123743 security_free_mnt_opts(&fs_info->security_opts);···43184247 }43194248}4320424942504250+#define btrfs_clear_fs_incompat(__fs_info, opt) \42514251+ __btrfs_clear_fs_incompat((__fs_info), BTRFS_FEATURE_INCOMPAT_##opt)42524252+42534253+static inline void __btrfs_clear_fs_incompat(struct btrfs_fs_info *fs_info,42544254+ u64 flag)42554255+{42564256+ struct btrfs_super_block *disk_super;42574257+ u64 features;42584258+42594259+ disk_super = fs_info->super_copy;42604260+ features = btrfs_super_incompat_flags(disk_super);42614261+ if (features & flag) {42624262+ spin_lock(&fs_info->super_lock);42634263+ features = btrfs_super_incompat_flags(disk_super);42644264+ if (features & flag) {42654265+ features &= ~flag;42664266+ btrfs_set_super_incompat_flags(disk_super, features);42674267+ btrfs_info(fs_info, "clearing %llu feature flag",42684268+ flag);42694269+ }42704270+ spin_unlock(&fs_info->super_lock);42714271+ }42724272+}42734273+43214274#define btrfs_fs_incompat(fs_info, opt) \43224275 __btrfs_fs_incompat((fs_info), BTRFS_FEATURE_INCOMPAT_##opt)43234276···43504255 struct btrfs_super_block *disk_super;43514256 disk_super = fs_info->super_copy;43524257 return !!(btrfs_super_incompat_flags(disk_super) & flag);42584258+}42594259+42604260+#define btrfs_set_fs_compat_ro(__fs_info, opt) \42614261+ __btrfs_set_fs_compat_ro((__fs_info), BTRFS_FEATURE_COMPAT_RO_##opt)42624262+42634263+static inline void __btrfs_set_fs_compat_ro(struct btrfs_fs_info *fs_info,42644264+ u64 flag)42654265+{42664266+ struct btrfs_super_block *disk_super;42674267+ u64 features;42684268+42694269+ disk_super = fs_info->super_copy;42704270+ features = btrfs_super_compat_ro_flags(disk_super);42714271+ if (!(features & flag)) {42724272+ spin_lock(&fs_info->super_lock);42734273+ features = btrfs_super_compat_ro_flags(disk_super);42744274+ if (!(features & flag)) {42754275+ features |= flag;42764276+ btrfs_set_super_compat_ro_flags(disk_super, features);42774277+ btrfs_info(fs_info, "setting %llu ro feature flag",42784278+ flag);42794279+ }42804280+ spin_unlock(&fs_info->super_lock);42814281+ }42824282+}42834283+42844284+#define btrfs_clear_fs_compat_ro(__fs_info, opt) \42854285+ __btrfs_clear_fs_compat_ro((__fs_info), BTRFS_FEATURE_COMPAT_RO_##opt)42864286+42874287+static inline void __btrfs_clear_fs_compat_ro(struct btrfs_fs_info *fs_info,42884288+ u64 flag)42894289+{42904290+ struct btrfs_super_block *disk_super;42914291+ u64 features;42924292+42934293+ disk_super = fs_info->super_copy;42944294+ features = btrfs_super_compat_ro_flags(disk_super);42954295+ if (features & flag) {42964296+ spin_lock(&fs_info->super_lock);42974297+ features = btrfs_super_compat_ro_flags(disk_super);42984298+ if (features & flag) {42994299+ features &= ~flag;43004300+ btrfs_set_super_compat_ro_flags(disk_super, features);43014301+ btrfs_info(fs_info, "clearing %llu ro feature flag",43024302+ flag);43034303+ }43044304+ spin_unlock(&fs_info->super_lock);43054305+ }43064306+}43074307+43084308+#define btrfs_fs_compat_ro(fs_info, opt) \43094309+ __btrfs_fs_compat_ro((fs_info), BTRFS_FEATURE_COMPAT_RO_##opt)43104310+43114311+static inline int __btrfs_fs_compat_ro(struct btrfs_fs_info *fs_info, u64 flag)43124312+{43134313+ struct btrfs_super_block *disk_super;43144314+ disk_super = fs_info->super_copy;43154315+ return !!(btrfs_super_compat_ro_flags(disk_super) & flag);43534316}4354431743554318/*
+38
fs/btrfs/disk-io.c
···4242#include "locking.h"4343#include "tree-log.h"4444#include "free-space-cache.h"4545+#include "free-space-tree.h"4546#include "inode-map.h"4647#include "check-integrity.h"4748#include "rcu-string.h"···16511650 if (location->objectid == BTRFS_UUID_TREE_OBJECTID)16521651 return fs_info->uuid_root ? fs_info->uuid_root :16531652 ERR_PTR(-ENOENT);16531653+ if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)16541654+ return fs_info->free_space_root ? fs_info->free_space_root :16551655+ ERR_PTR(-ENOENT);16541656again:16551657 root = btrfs_lookup_fs_root(fs_info, location->objectid);16561658 if (root) {···21522148 free_root_extent_buffers(info->uuid_root);21532149 if (chunk_root)21542150 free_root_extent_buffers(info->chunk_root);21512151+ free_root_extent_buffers(info->free_space_root);21552152}2156215321572154void btrfs_free_fs_roots(struct btrfs_fs_info *fs_info)···24512446 } else {24522447 set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);24532448 fs_info->uuid_root = root;24492449+ }24502450+24512451+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {24522452+ location.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID;24532453+ root = btrfs_read_tree_root(tree_root, &location);24542454+ if (IS_ERR(root))24552455+ return PTR_ERR(root);24562456+ set_bit(BTRFS_ROOT_TRACK_DIRTY, &root->state);24572457+ fs_info->free_space_root = root;24542458 }2455245924562460 return 0;···30893075 }3090307630913077 btrfs_qgroup_rescan_resume(fs_info);30783078+30793079+ if (btrfs_test_opt(tree_root, CLEAR_CACHE) &&30803080+ btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {30813081+ pr_info("BTRFS: clearing free space tree\n");30823082+ ret = btrfs_clear_free_space_tree(fs_info);30833083+ if (ret) {30843084+ pr_warn("BTRFS: failed to clear free space tree %d\n",30853085+ ret);30863086+ close_ctree(tree_root);30873087+ return ret;30883088+ }30893089+ }30903090+30913091+ if (btrfs_test_opt(tree_root, FREE_SPACE_TREE) &&30923092+ !btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE)) {30933093+ pr_info("BTRFS: creating free space tree\n");30943094+ ret = btrfs_create_free_space_tree(fs_info);30953095+ if (ret) {30963096+ pr_warn("BTRFS: failed to create free space tree %d\n",30973097+ ret);30983098+ close_ctree(tree_root);30993099+ return ret;31003100+ }31013101+ }3092310230933103 if (!fs_info->uuid_root) {30943104 pr_info("BTRFS: creating UUID tree\n");
+71-30
fs/btrfs/extent-tree.c
···3333#include "raid56.h"3434#include "locking.h"3535#include "free-space-cache.h"3636+#include "free-space-tree.h"3637#include "math.h"3738#include "sysfs.h"3839#include "qgroup.h"···358357 * we need to check the pinned_extents for any extents that can't be used yet359358 * since their free space will be released as soon as the transaction commits.360359 */361361-static u64 add_new_free_space(struct btrfs_block_group_cache *block_group,362362- struct btrfs_fs_info *info, u64 start, u64 end)360360+u64 add_new_free_space(struct btrfs_block_group_cache *block_group,361361+ struct btrfs_fs_info *info, u64 start, u64 end)363362{364363 u64 extent_start, extent_end, size, total_added = 0;365364 int ret;···396395 return total_added;397396}398397399399-static noinline void caching_thread(struct btrfs_work *work)398398+static int load_extent_tree_free(struct btrfs_caching_control *caching_ctl)400399{401400 struct btrfs_block_group_cache *block_group;402401 struct btrfs_fs_info *fs_info;403403- struct btrfs_caching_control *caching_ctl;404402 struct btrfs_root *extent_root;405403 struct btrfs_path *path;406404 struct extent_buffer *leaf;···407407 u64 total_found = 0;408408 u64 last = 0;409409 u32 nritems;410410- int ret = -ENOMEM;410410+ int ret;411411 bool wakeup = true;412412413413- caching_ctl = container_of(work, struct btrfs_caching_control, work);414413 block_group = caching_ctl->block_group;415414 fs_info = block_group->fs_info;416415 extent_root = fs_info->extent_root;417416418417 path = btrfs_alloc_path();419418 if (!path)420420- goto out;419419+ return -ENOMEM;421420422421 last = max_t(u64, block_group->key.objectid, BTRFS_SUPER_INFO_OFFSET);423422···442443 key.objectid = last;443444 key.offset = 0;444445 key.type = BTRFS_EXTENT_ITEM_KEY;445445-again:446446- mutex_lock(&caching_ctl->mutex);447447- /* need to make sure the commit_root doesn't disappear */448448- down_read(&fs_info->commit_root_sem);449446450447next:451448 ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0);452449 if (ret < 0)453453- goto err;450450+ goto out;454451455452 leaf = path->nodes[0];456453 nritems = btrfs_header_nritems(leaf);···472477 up_read(&fs_info->commit_root_sem);473478 mutex_unlock(&caching_ctl->mutex);474479 cond_resched();475475- goto again;480480+ mutex_lock(&caching_ctl->mutex);481481+ down_read(&fs_info->commit_root_sem);482482+ goto next;476483 }477484478485 ret = btrfs_next_leaf(extent_root, path);479486 if (ret < 0)480480- goto err;487487+ goto out;481488 if (ret)482489 break;483490 leaf = path->nodes[0];···518521 else519522 last = key.objectid + key.offset;520523521521- if (total_found > (1024 * 1024 * 2)) {524524+ if (total_found > CACHING_CTL_WAKE_UP) {522525 total_found = 0;523526 if (wakeup)524527 wake_up(&caching_ctl->wait);···531534 total_found += add_new_free_space(block_group, fs_info, last,532535 block_group->key.objectid +533536 block_group->key.offset);537537+ caching_ctl->progress = (u64)-1;538538+539539+out:540540+ btrfs_free_path(path);541541+ return ret;542542+}543543+544544+static noinline void caching_thread(struct btrfs_work *work)545545+{546546+ struct btrfs_block_group_cache *block_group;547547+ struct btrfs_fs_info *fs_info;548548+ struct btrfs_caching_control *caching_ctl;549549+ int ret;550550+551551+ caching_ctl = container_of(work, struct btrfs_caching_control, work);552552+ block_group = caching_ctl->block_group;553553+ fs_info = block_group->fs_info;554554+555555+ mutex_lock(&caching_ctl->mutex);556556+ down_read(&fs_info->commit_root_sem);557557+558558+ if (btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))559559+ ret = load_free_space_tree(caching_ctl);560560+ else561561+ ret = load_extent_tree_free(caching_ctl);562562+534563 spin_lock(&block_group->lock);535564 block_group->caching_ctl = NULL;536536- block_group->cached = BTRFS_CACHE_FINISHED;565565+ block_group->cached = ret ? BTRFS_CACHE_ERROR : BTRFS_CACHE_FINISHED;537566 spin_unlock(&block_group->lock);538567539568#ifdef CONFIG_BTRFS_DEBUG···578555#endif579556580557 caching_ctl->progress = (u64)-1;581581-err:582582- btrfs_free_path(path);558558+583559 up_read(&fs_info->commit_root_sem);584584-585585- free_excluded_extents(extent_root, block_group);586586-560560+ free_excluded_extents(fs_info->extent_root, block_group);587561 mutex_unlock(&caching_ctl->mutex);588588-out:589589- if (ret) {590590- spin_lock(&block_group->lock);591591- block_group->caching_ctl = NULL;592592- block_group->cached = BTRFS_CACHE_ERROR;593593- spin_unlock(&block_group->lock);594594- }562562+595563 wake_up(&caching_ctl->wait);596564597565 put_caching_control(caching_ctl);···694680 }695681 } else {696682 /*697697- * We are not going to do the fast caching, set cached to the698698- * appropriate value and wakeup any waiters.683683+ * We're either using the free space tree or no caching at all.684684+ * Set cached to the appropriate value and wakeup any waiters.699685 */700686 spin_lock(&cache->lock);701687 if (load_cache_only) {···66756661 }66766662 }6677666366646664+ ret = add_to_free_space_tree(trans, root->fs_info, bytenr,66656665+ num_bytes);66666666+ if (ret) {66676667+ btrfs_abort_transaction(trans, extent_root, ret);66686668+ goto out;66696669+ }66706670+66786671 ret = update_block_group(trans, root, bytenr, num_bytes, 0);66796672 if (ret) {66806673 btrfs_abort_transaction(trans, extent_root, ret);···76937672 btrfs_mark_buffer_dirty(path->nodes[0]);76947673 btrfs_free_path(path);7695767476757675+ ret = remove_from_free_space_tree(trans, fs_info, ins->objectid,76767676+ ins->offset);76777677+ if (ret)76787678+ return ret;76797679+76967680 ret = update_block_group(trans, root, ins->objectid, ins->offset, 1);76977681 if (ret) { /* -ENOENT, logic error */76987682 btrfs_err(fs_info, "update block group failed for %llu %llu",···7777775177787752 btrfs_mark_buffer_dirty(leaf);77797753 btrfs_free_path(path);77547754+77557755+ ret = remove_from_free_space_tree(trans, fs_info, ins->objectid,77567756+ num_bytes);77577757+ if (ret)77587758+ return ret;7780775977817760 ret = update_block_group(trans, root, ins->objectid, root->nodesize,77827761 1);···96879656 cache->full_stripe_len = btrfs_full_stripe_len(root,96889657 &root->fs_info->mapping_tree,96899658 start);96599659+ set_free_space_tree_thresholds(cache);96609660+96909661 atomic_set(&cache->count, 1);96919662 spin_lock_init(&cache->lock);96929663 init_rwsem(&cache->data_rwsem);···97009667 INIT_LIST_HEAD(&cache->io_list);97019668 btrfs_init_free_space_ctl(cache);97029669 atomic_set(&cache->trimming, 0);96709670+ mutex_init(&cache->free_space_lock);9703967197049672 return cache;97059673}···99119877 key.objectid, key.offset);99129878 if (ret)99139879 btrfs_abort_transaction(trans, extent_root, ret);98809880+ add_block_group_free_space(trans, root->fs_info, block_group);98819881+ /* already aborted the transaction if it failed. */99149882next:99159883 list_del_init(&block_group->bg_list);99169884 }···99439907 cache->flags = type;99449908 cache->last_byte_to_unpin = (u64)-1;99459909 cache->cached = BTRFS_CACHE_FINISHED;99109910+ cache->needs_free_space = 1;99469911 ret = exclude_super_stripes(root, cache);99479912 if (ret) {99489913 /*···1031310276 }10314102771031510278 unlock_chunks(root);1027910279+1028010280+ ret = remove_block_group_free_space(trans, root->fs_info, block_group);1028110281+ if (ret)1028210282+ goto out;10316102831031710284 btrfs_put_block_group(block_group);1031810285 btrfs_put_block_group(block_group);
+170-13
fs/btrfs/extent_io.c
···47974797 return new;47984798}4799479948004800-struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,48014801- u64 start)48004800+struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,48014801+ u64 start, unsigned long len)48024802{48034803 struct extent_buffer *eb;48044804- unsigned long len;48054804 unsigned long num_pages;48064805 unsigned long i;4807480648084808- if (!fs_info) {48094809- /*48104810- * Called only from tests that don't always have a fs_info48114811- * available, but we know that nodesize is 409648124812- */48134813- len = 4096;48144814- } else {48154815- len = fs_info->tree_root->nodesize;48164816- }48174817- num_pages = num_extent_pages(0, len);48074807+ num_pages = num_extent_pages(start, len);4818480848194809 eb = __alloc_extent_buffer(fs_info, start, len);48204810 if (!eb)···48254835 __free_page(eb->pages[i - 1]);48264836 __free_extent_buffer(eb);48274837 return NULL;48384838+}48394839+48404840+struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,48414841+ u64 start)48424842+{48434843+ unsigned long len;48444844+48454845+ if (!fs_info) {48464846+ /*48474847+ * Called only from tests that don't always have a fs_info48484848+ * available, but we know that nodesize is 409648494849+ */48504850+ len = 4096;48514851+ } else {48524852+ len = fs_info->tree_root->nodesize;48534853+ }48544854+48554855+ return __alloc_dummy_extent_buffer(fs_info, start, len);48284856}4829485748304858static void check_buffer_tree_ref(struct extent_buffer *eb)···55995591 len -= cur;56005592 offset = 0;56015593 i++;55945594+ }55955595+}55965596+55975597+/*55985598+ * The extent buffer bitmap operations are done with byte granularity because55995599+ * bitmap items are not guaranteed to be aligned to a word and therefore a56005600+ * single word in a bitmap may straddle two pages in the extent buffer.56015601+ */56025602+#define BIT_BYTE(nr) ((nr) / BITS_PER_BYTE)56035603+#define BYTE_MASK ((1 << BITS_PER_BYTE) - 1)56045604+#define BITMAP_FIRST_BYTE_MASK(start) \56055605+ ((BYTE_MASK << ((start) & (BITS_PER_BYTE - 1))) & BYTE_MASK)56065606+#define BITMAP_LAST_BYTE_MASK(nbits) \56075607+ (BYTE_MASK >> (-(nbits) & (BITS_PER_BYTE - 1)))56085608+56095609+/*56105610+ * eb_bitmap_offset() - calculate the page and offset of the byte containing the56115611+ * given bit number56125612+ * @eb: the extent buffer56135613+ * @start: offset of the bitmap item in the extent buffer56145614+ * @nr: bit number56155615+ * @page_index: return index of the page in the extent buffer that contains the56165616+ * given bit number56175617+ * @page_offset: return offset into the page given by page_index56185618+ *56195619+ * This helper hides the ugliness of finding the byte in an extent buffer which56205620+ * contains a given bit.56215621+ */56225622+static inline void eb_bitmap_offset(struct extent_buffer *eb,56235623+ unsigned long start, unsigned long nr,56245624+ unsigned long *page_index,56255625+ size_t *page_offset)56265626+{56275627+ size_t start_offset = eb->start & ((u64)PAGE_CACHE_SIZE - 1);56285628+ size_t byte_offset = BIT_BYTE(nr);56295629+ size_t offset;56305630+56315631+ /*56325632+ * The byte we want is the offset of the extent buffer + the offset of56335633+ * the bitmap item in the extent buffer + the offset of the byte in the56345634+ * bitmap item.56355635+ */56365636+ offset = start_offset + start + byte_offset;56375637+56385638+ *page_index = offset >> PAGE_CACHE_SHIFT;56395639+ *page_offset = offset & (PAGE_CACHE_SIZE - 1);56405640+}56415641+56425642+/**56435643+ * extent_buffer_test_bit - determine whether a bit in a bitmap item is set56445644+ * @eb: the extent buffer56455645+ * @start: offset of the bitmap item in the extent buffer56465646+ * @nr: bit number to test56475647+ */56485648+int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,56495649+ unsigned long nr)56505650+{56515651+ char *kaddr;56525652+ struct page *page;56535653+ unsigned long i;56545654+ size_t offset;56555655+56565656+ eb_bitmap_offset(eb, start, nr, &i, &offset);56575657+ page = eb->pages[i];56585658+ WARN_ON(!PageUptodate(page));56595659+ kaddr = page_address(page);56605660+ return 1U & (kaddr[offset] >> (nr & (BITS_PER_BYTE - 1)));56615661+}56625662+56635663+/**56645664+ * extent_buffer_bitmap_set - set an area of a bitmap56655665+ * @eb: the extent buffer56665666+ * @start: offset of the bitmap item in the extent buffer56675667+ * @pos: bit number of the first bit56685668+ * @len: number of bits to set56695669+ */56705670+void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,56715671+ unsigned long pos, unsigned long len)56725672+{56735673+ char *kaddr;56745674+ struct page *page;56755675+ unsigned long i;56765676+ size_t offset;56775677+ const unsigned int size = pos + len;56785678+ int bits_to_set = BITS_PER_BYTE - (pos % BITS_PER_BYTE);56795679+ unsigned int mask_to_set = BITMAP_FIRST_BYTE_MASK(pos);56805680+56815681+ eb_bitmap_offset(eb, start, pos, &i, &offset);56825682+ page = eb->pages[i];56835683+ WARN_ON(!PageUptodate(page));56845684+ kaddr = page_address(page);56855685+56865686+ while (len >= bits_to_set) {56875687+ kaddr[offset] |= mask_to_set;56885688+ len -= bits_to_set;56895689+ bits_to_set = BITS_PER_BYTE;56905690+ mask_to_set = ~0U;56915691+ if (++offset >= PAGE_CACHE_SIZE && len > 0) {56925692+ offset = 0;56935693+ page = eb->pages[++i];56945694+ WARN_ON(!PageUptodate(page));56955695+ kaddr = page_address(page);56965696+ }56975697+ }56985698+ if (len) {56995699+ mask_to_set &= BITMAP_LAST_BYTE_MASK(size);57005700+ kaddr[offset] |= mask_to_set;57015701+ }57025702+}57035703+57045704+57055705+/**57065706+ * extent_buffer_bitmap_clear - clear an area of a bitmap57075707+ * @eb: the extent buffer57085708+ * @start: offset of the bitmap item in the extent buffer57095709+ * @pos: bit number of the first bit57105710+ * @len: number of bits to clear57115711+ */57125712+void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,57135713+ unsigned long pos, unsigned long len)57145714+{57155715+ char *kaddr;57165716+ struct page *page;57175717+ unsigned long i;57185718+ size_t offset;57195719+ const unsigned int size = pos + len;57205720+ int bits_to_clear = BITS_PER_BYTE - (pos % BITS_PER_BYTE);57215721+ unsigned int mask_to_clear = BITMAP_FIRST_BYTE_MASK(pos);57225722+57235723+ eb_bitmap_offset(eb, start, pos, &i, &offset);57245724+ page = eb->pages[i];57255725+ WARN_ON(!PageUptodate(page));57265726+ kaddr = page_address(page);57275727+57285728+ while (len >= bits_to_clear) {57295729+ kaddr[offset] &= ~mask_to_clear;57305730+ len -= bits_to_clear;57315731+ bits_to_clear = BITS_PER_BYTE;57325732+ mask_to_clear = ~0U;57335733+ if (++offset >= PAGE_CACHE_SIZE && len > 0) {57345734+ offset = 0;57355735+ page = eb->pages[++i];57365736+ WARN_ON(!PageUptodate(page));57375737+ kaddr = page_address(page);57385738+ }57395739+ }57405740+ if (len) {57415741+ mask_to_clear &= BITMAP_LAST_BYTE_MASK(size);57425742+ kaddr[offset] &= ~mask_to_clear;56025743 }56035744}56045745
+9-1
fs/btrfs/extent_io.h
···282282283283struct extent_buffer *alloc_extent_buffer(struct btrfs_fs_info *fs_info,284284 u64 start);285285+struct extent_buffer *__alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,286286+ u64 start, unsigned long len);285287struct extent_buffer *alloc_dummy_extent_buffer(struct btrfs_fs_info *fs_info,286286- u64 start);288288+ u64 start);287289struct extent_buffer *btrfs_clone_extent_buffer(struct extent_buffer *src);288290struct extent_buffer *find_extent_buffer(struct btrfs_fs_info *fs_info,289291 u64 start);···330328 unsigned long src_offset, unsigned long len);331329void memset_extent_buffer(struct extent_buffer *eb, char c,332330 unsigned long start, unsigned long len);331331+int extent_buffer_test_bit(struct extent_buffer *eb, unsigned long start,332332+ unsigned long pos);333333+void extent_buffer_bitmap_set(struct extent_buffer *eb, unsigned long start,334334+ unsigned long pos, unsigned long len);335335+void extent_buffer_bitmap_clear(struct extent_buffer *eb, unsigned long start,336336+ unsigned long pos, unsigned long len);333337void clear_extent_buffer_dirty(struct extent_buffer *eb);334338int set_extent_buffer_dirty(struct extent_buffer *eb);335339int set_extent_buffer_uptodate(struct extent_buffer *eb);
+1584
fs/btrfs/free-space-tree.c
···11+/*22+ * Copyright (C) 2015 Facebook. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or55+ * modify it under the terms of the GNU General Public66+ * License v2 as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope that it will be useful,99+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1010+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1111+ * General Public License for more details.1212+ *1313+ * You should have received a copy of the GNU General Public1414+ * License along with this program; if not, write to the1515+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,1616+ * Boston, MA 021110-1307, USA.1717+ */1818+1919+#include <linux/kernel.h>2020+#include <linux/vmalloc.h>2121+#include "ctree.h"2222+#include "disk-io.h"2323+#include "locking.h"2424+#include "free-space-tree.h"2525+#include "transaction.h"2626+2727+static int __add_block_group_free_space(struct btrfs_trans_handle *trans,2828+ struct btrfs_fs_info *fs_info,2929+ struct btrfs_block_group_cache *block_group,3030+ struct btrfs_path *path);3131+3232+void set_free_space_tree_thresholds(struct btrfs_block_group_cache *cache)3333+{3434+ u32 bitmap_range;3535+ size_t bitmap_size;3636+ u64 num_bitmaps, total_bitmap_size;3737+3838+ /*3939+ * We convert to bitmaps when the disk space required for using extents4040+ * exceeds that required for using bitmaps.4141+ */4242+ bitmap_range = cache->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;4343+ num_bitmaps = div_u64(cache->key.offset + bitmap_range - 1,4444+ bitmap_range);4545+ bitmap_size = sizeof(struct btrfs_item) + BTRFS_FREE_SPACE_BITMAP_SIZE;4646+ total_bitmap_size = num_bitmaps * bitmap_size;4747+ cache->bitmap_high_thresh = div_u64(total_bitmap_size,4848+ sizeof(struct btrfs_item));4949+5050+ /*5151+ * We allow for a small buffer between the high threshold and low5252+ * threshold to avoid thrashing back and forth between the two formats.5353+ */5454+ if (cache->bitmap_high_thresh > 100)5555+ cache->bitmap_low_thresh = cache->bitmap_high_thresh - 100;5656+ else5757+ cache->bitmap_low_thresh = 0;5858+}5959+6060+static int add_new_free_space_info(struct btrfs_trans_handle *trans,6161+ struct btrfs_fs_info *fs_info,6262+ struct btrfs_block_group_cache *block_group,6363+ struct btrfs_path *path)6464+{6565+ struct btrfs_root *root = fs_info->free_space_root;6666+ struct btrfs_free_space_info *info;6767+ struct btrfs_key key;6868+ struct extent_buffer *leaf;6969+ int ret;7070+7171+ key.objectid = block_group->key.objectid;7272+ key.type = BTRFS_FREE_SPACE_INFO_KEY;7373+ key.offset = block_group->key.offset;7474+7575+ ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*info));7676+ if (ret)7777+ goto out;7878+7979+ leaf = path->nodes[0];8080+ info = btrfs_item_ptr(leaf, path->slots[0],8181+ struct btrfs_free_space_info);8282+ btrfs_set_free_space_extent_count(leaf, info, 0);8383+ btrfs_set_free_space_flags(leaf, info, 0);8484+ btrfs_mark_buffer_dirty(leaf);8585+8686+ ret = 0;8787+out:8888+ btrfs_release_path(path);8989+ return ret;9090+}9191+9292+struct btrfs_free_space_info *9393+search_free_space_info(struct btrfs_trans_handle *trans,9494+ struct btrfs_fs_info *fs_info,9595+ struct btrfs_block_group_cache *block_group,9696+ struct btrfs_path *path, int cow)9797+{9898+ struct btrfs_root *root = fs_info->free_space_root;9999+ struct btrfs_key key;100100+ int ret;101101+102102+ key.objectid = block_group->key.objectid;103103+ key.type = BTRFS_FREE_SPACE_INFO_KEY;104104+ key.offset = block_group->key.offset;105105+106106+ ret = btrfs_search_slot(trans, root, &key, path, 0, cow);107107+ if (ret < 0)108108+ return ERR_PTR(ret);109109+ if (ret != 0) {110110+ btrfs_warn(fs_info, "missing free space info for %llu\n",111111+ block_group->key.objectid);112112+ ASSERT(0);113113+ return ERR_PTR(-ENOENT);114114+ }115115+116116+ return btrfs_item_ptr(path->nodes[0], path->slots[0],117117+ struct btrfs_free_space_info);118118+}119119+120120+/*121121+ * btrfs_search_slot() but we're looking for the greatest key less than the122122+ * passed key.123123+ */124124+static int btrfs_search_prev_slot(struct btrfs_trans_handle *trans,125125+ struct btrfs_root *root,126126+ struct btrfs_key *key, struct btrfs_path *p,127127+ int ins_len, int cow)128128+{129129+ int ret;130130+131131+ ret = btrfs_search_slot(trans, root, key, p, ins_len, cow);132132+ if (ret < 0)133133+ return ret;134134+135135+ if (ret == 0) {136136+ ASSERT(0);137137+ return -EIO;138138+ }139139+140140+ if (p->slots[0] == 0) {141141+ ASSERT(0);142142+ return -EIO;143143+ }144144+ p->slots[0]--;145145+146146+ return 0;147147+}148148+149149+static inline u32 free_space_bitmap_size(u64 size, u32 sectorsize)150150+{151151+ return DIV_ROUND_UP((u32)div_u64(size, sectorsize), BITS_PER_BYTE);152152+}153153+154154+static unsigned long *alloc_bitmap(u32 bitmap_size)155155+{156156+ return __vmalloc(bitmap_size, GFP_NOFS | __GFP_HIGHMEM | __GFP_ZERO,157157+ PAGE_KERNEL);158158+}159159+160160+int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,161161+ struct btrfs_fs_info *fs_info,162162+ struct btrfs_block_group_cache *block_group,163163+ struct btrfs_path *path)164164+{165165+ struct btrfs_root *root = fs_info->free_space_root;166166+ struct btrfs_free_space_info *info;167167+ struct btrfs_key key, found_key;168168+ struct extent_buffer *leaf;169169+ unsigned long *bitmap;170170+ char *bitmap_cursor;171171+ u64 start, end;172172+ u64 bitmap_range, i;173173+ u32 bitmap_size, flags, expected_extent_count;174174+ u32 extent_count = 0;175175+ int done = 0, nr;176176+ int ret;177177+178178+ bitmap_size = free_space_bitmap_size(block_group->key.offset,179179+ block_group->sectorsize);180180+ bitmap = alloc_bitmap(bitmap_size);181181+ if (!bitmap) {182182+ ret = -ENOMEM;183183+ goto out;184184+ }185185+186186+ start = block_group->key.objectid;187187+ end = block_group->key.objectid + block_group->key.offset;188188+189189+ key.objectid = end - 1;190190+ key.type = (u8)-1;191191+ key.offset = (u64)-1;192192+193193+ while (!done) {194194+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);195195+ if (ret)196196+ goto out;197197+198198+ leaf = path->nodes[0];199199+ nr = 0;200200+ path->slots[0]++;201201+ while (path->slots[0] > 0) {202202+ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);203203+204204+ if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {205205+ ASSERT(found_key.objectid == block_group->key.objectid);206206+ ASSERT(found_key.offset == block_group->key.offset);207207+ done = 1;208208+ break;209209+ } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) {210210+ u64 first, last;211211+212212+ ASSERT(found_key.objectid >= start);213213+ ASSERT(found_key.objectid < end);214214+ ASSERT(found_key.objectid + found_key.offset <= end);215215+216216+ first = div_u64(found_key.objectid - start,217217+ block_group->sectorsize);218218+ last = div_u64(found_key.objectid + found_key.offset - start,219219+ block_group->sectorsize);220220+ bitmap_set(bitmap, first, last - first);221221+222222+ extent_count++;223223+ nr++;224224+ path->slots[0]--;225225+ } else {226226+ ASSERT(0);227227+ }228228+ }229229+230230+ ret = btrfs_del_items(trans, root, path, path->slots[0], nr);231231+ if (ret)232232+ goto out;233233+ btrfs_release_path(path);234234+ }235235+236236+ info = search_free_space_info(trans, fs_info, block_group, path, 1);237237+ if (IS_ERR(info)) {238238+ ret = PTR_ERR(info);239239+ goto out;240240+ }241241+ leaf = path->nodes[0];242242+ flags = btrfs_free_space_flags(leaf, info);243243+ flags |= BTRFS_FREE_SPACE_USING_BITMAPS;244244+ btrfs_set_free_space_flags(leaf, info, flags);245245+ expected_extent_count = btrfs_free_space_extent_count(leaf, info);246246+ btrfs_mark_buffer_dirty(leaf);247247+ btrfs_release_path(path);248248+249249+ if (extent_count != expected_extent_count) {250250+ btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",251251+ block_group->key.objectid, extent_count,252252+ expected_extent_count);253253+ ASSERT(0);254254+ ret = -EIO;255255+ goto out;256256+ }257257+258258+ bitmap_cursor = (char *)bitmap;259259+ bitmap_range = block_group->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;260260+ i = start;261261+ while (i < end) {262262+ unsigned long ptr;263263+ u64 extent_size;264264+ u32 data_size;265265+266266+ extent_size = min(end - i, bitmap_range);267267+ data_size = free_space_bitmap_size(extent_size,268268+ block_group->sectorsize);269269+270270+ key.objectid = i;271271+ key.type = BTRFS_FREE_SPACE_BITMAP_KEY;272272+ key.offset = extent_size;273273+274274+ ret = btrfs_insert_empty_item(trans, root, path, &key,275275+ data_size);276276+ if (ret)277277+ goto out;278278+279279+ leaf = path->nodes[0];280280+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);281281+ write_extent_buffer(leaf, bitmap_cursor, ptr,282282+ data_size);283283+ btrfs_mark_buffer_dirty(leaf);284284+ btrfs_release_path(path);285285+286286+ i += extent_size;287287+ bitmap_cursor += data_size;288288+ }289289+290290+ ret = 0;291291+out:292292+ vfree(bitmap);293293+ if (ret)294294+ btrfs_abort_transaction(trans, root, ret);295295+ return ret;296296+}297297+298298+int convert_free_space_to_extents(struct btrfs_trans_handle *trans,299299+ struct btrfs_fs_info *fs_info,300300+ struct btrfs_block_group_cache *block_group,301301+ struct btrfs_path *path)302302+{303303+ struct btrfs_root *root = fs_info->free_space_root;304304+ struct btrfs_free_space_info *info;305305+ struct btrfs_key key, found_key;306306+ struct extent_buffer *leaf;307307+ unsigned long *bitmap;308308+ u64 start, end;309309+ /* Initialize to silence GCC. */310310+ u64 extent_start = 0;311311+ u64 offset;312312+ u32 bitmap_size, flags, expected_extent_count;313313+ int prev_bit = 0, bit, bitnr;314314+ u32 extent_count = 0;315315+ int done = 0, nr;316316+ int ret;317317+318318+ bitmap_size = free_space_bitmap_size(block_group->key.offset,319319+ block_group->sectorsize);320320+ bitmap = alloc_bitmap(bitmap_size);321321+ if (!bitmap) {322322+ ret = -ENOMEM;323323+ goto out;324324+ }325325+326326+ start = block_group->key.objectid;327327+ end = block_group->key.objectid + block_group->key.offset;328328+329329+ key.objectid = end - 1;330330+ key.type = (u8)-1;331331+ key.offset = (u64)-1;332332+333333+ while (!done) {334334+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);335335+ if (ret)336336+ goto out;337337+338338+ leaf = path->nodes[0];339339+ nr = 0;340340+ path->slots[0]++;341341+ while (path->slots[0] > 0) {342342+ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);343343+344344+ if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {345345+ ASSERT(found_key.objectid == block_group->key.objectid);346346+ ASSERT(found_key.offset == block_group->key.offset);347347+ done = 1;348348+ break;349349+ } else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {350350+ unsigned long ptr;351351+ char *bitmap_cursor;352352+ u32 bitmap_pos, data_size;353353+354354+ ASSERT(found_key.objectid >= start);355355+ ASSERT(found_key.objectid < end);356356+ ASSERT(found_key.objectid + found_key.offset <= end);357357+358358+ bitmap_pos = div_u64(found_key.objectid - start,359359+ block_group->sectorsize *360360+ BITS_PER_BYTE);361361+ bitmap_cursor = ((char *)bitmap) + bitmap_pos;362362+ data_size = free_space_bitmap_size(found_key.offset,363363+ block_group->sectorsize);364364+365365+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0] - 1);366366+ read_extent_buffer(leaf, bitmap_cursor, ptr,367367+ data_size);368368+369369+ nr++;370370+ path->slots[0]--;371371+ } else {372372+ ASSERT(0);373373+ }374374+ }375375+376376+ ret = btrfs_del_items(trans, root, path, path->slots[0], nr);377377+ if (ret)378378+ goto out;379379+ btrfs_release_path(path);380380+ }381381+382382+ info = search_free_space_info(trans, fs_info, block_group, path, 1);383383+ if (IS_ERR(info)) {384384+ ret = PTR_ERR(info);385385+ goto out;386386+ }387387+ leaf = path->nodes[0];388388+ flags = btrfs_free_space_flags(leaf, info);389389+ flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS;390390+ btrfs_set_free_space_flags(leaf, info, flags);391391+ expected_extent_count = btrfs_free_space_extent_count(leaf, info);392392+ btrfs_mark_buffer_dirty(leaf);393393+ btrfs_release_path(path);394394+395395+ offset = start;396396+ bitnr = 0;397397+ while (offset < end) {398398+ bit = !!test_bit(bitnr, bitmap);399399+ if (prev_bit == 0 && bit == 1) {400400+ extent_start = offset;401401+ } else if (prev_bit == 1 && bit == 0) {402402+ key.objectid = extent_start;403403+ key.type = BTRFS_FREE_SPACE_EXTENT_KEY;404404+ key.offset = offset - extent_start;405405+406406+ ret = btrfs_insert_empty_item(trans, root, path, &key, 0);407407+ if (ret)408408+ goto out;409409+ btrfs_release_path(path);410410+411411+ extent_count++;412412+ }413413+ prev_bit = bit;414414+ offset += block_group->sectorsize;415415+ bitnr++;416416+ }417417+ if (prev_bit == 1) {418418+ key.objectid = extent_start;419419+ key.type = BTRFS_FREE_SPACE_EXTENT_KEY;420420+ key.offset = end - extent_start;421421+422422+ ret = btrfs_insert_empty_item(trans, root, path, &key, 0);423423+ if (ret)424424+ goto out;425425+ btrfs_release_path(path);426426+427427+ extent_count++;428428+ }429429+430430+ if (extent_count != expected_extent_count) {431431+ btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",432432+ block_group->key.objectid, extent_count,433433+ expected_extent_count);434434+ ASSERT(0);435435+ ret = -EIO;436436+ goto out;437437+ }438438+439439+ ret = 0;440440+out:441441+ vfree(bitmap);442442+ if (ret)443443+ btrfs_abort_transaction(trans, root, ret);444444+ return ret;445445+}446446+447447+static int update_free_space_extent_count(struct btrfs_trans_handle *trans,448448+ struct btrfs_fs_info *fs_info,449449+ struct btrfs_block_group_cache *block_group,450450+ struct btrfs_path *path,451451+ int new_extents)452452+{453453+ struct btrfs_free_space_info *info;454454+ u32 flags;455455+ u32 extent_count;456456+ int ret = 0;457457+458458+ if (new_extents == 0)459459+ return 0;460460+461461+ info = search_free_space_info(trans, fs_info, block_group, path, 1);462462+ if (IS_ERR(info)) {463463+ ret = PTR_ERR(info);464464+ goto out;465465+ }466466+ flags = btrfs_free_space_flags(path->nodes[0], info);467467+ extent_count = btrfs_free_space_extent_count(path->nodes[0], info);468468+469469+ extent_count += new_extents;470470+ btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count);471471+ btrfs_mark_buffer_dirty(path->nodes[0]);472472+ btrfs_release_path(path);473473+474474+ if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&475475+ extent_count > block_group->bitmap_high_thresh) {476476+ ret = convert_free_space_to_bitmaps(trans, fs_info, block_group,477477+ path);478478+ } else if ((flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&479479+ extent_count < block_group->bitmap_low_thresh) {480480+ ret = convert_free_space_to_extents(trans, fs_info, block_group,481481+ path);482482+ }483483+484484+out:485485+ return ret;486486+}487487+488488+int free_space_test_bit(struct btrfs_block_group_cache *block_group,489489+ struct btrfs_path *path, u64 offset)490490+{491491+ struct extent_buffer *leaf;492492+ struct btrfs_key key;493493+ u64 found_start, found_end;494494+ unsigned long ptr, i;495495+496496+ leaf = path->nodes[0];497497+ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);498498+ ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);499499+500500+ found_start = key.objectid;501501+ found_end = key.objectid + key.offset;502502+ ASSERT(offset >= found_start && offset < found_end);503503+504504+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);505505+ i = div_u64(offset - found_start, block_group->sectorsize);506506+ return !!extent_buffer_test_bit(leaf, ptr, i);507507+}508508+509509+static void free_space_set_bits(struct btrfs_block_group_cache *block_group,510510+ struct btrfs_path *path, u64 *start, u64 *size,511511+ int bit)512512+{513513+ struct extent_buffer *leaf;514514+ struct btrfs_key key;515515+ u64 end = *start + *size;516516+ u64 found_start, found_end;517517+ unsigned long ptr, first, last;518518+519519+ leaf = path->nodes[0];520520+ btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);521521+ ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);522522+523523+ found_start = key.objectid;524524+ found_end = key.objectid + key.offset;525525+ ASSERT(*start >= found_start && *start < found_end);526526+ ASSERT(end > found_start);527527+528528+ if (end > found_end)529529+ end = found_end;530530+531531+ ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);532532+ first = div_u64(*start - found_start, block_group->sectorsize);533533+ last = div_u64(end - found_start, block_group->sectorsize);534534+ if (bit)535535+ extent_buffer_bitmap_set(leaf, ptr, first, last - first);536536+ else537537+ extent_buffer_bitmap_clear(leaf, ptr, first, last - first);538538+ btrfs_mark_buffer_dirty(leaf);539539+540540+ *size -= end - *start;541541+ *start = end;542542+}543543+544544+/*545545+ * We can't use btrfs_next_item() in modify_free_space_bitmap() because546546+ * btrfs_next_leaf() doesn't get the path for writing. We can forgo the fancy547547+ * tree walking in btrfs_next_leaf() anyways because we know exactly what we're548548+ * looking for.549549+ */550550+static int free_space_next_bitmap(struct btrfs_trans_handle *trans,551551+ struct btrfs_root *root, struct btrfs_path *p)552552+{553553+ struct btrfs_key key;554554+555555+ if (p->slots[0] + 1 < btrfs_header_nritems(p->nodes[0])) {556556+ p->slots[0]++;557557+ return 0;558558+ }559559+560560+ btrfs_item_key_to_cpu(p->nodes[0], &key, p->slots[0]);561561+ btrfs_release_path(p);562562+563563+ key.objectid += key.offset;564564+ key.type = (u8)-1;565565+ key.offset = (u64)-1;566566+567567+ return btrfs_search_prev_slot(trans, root, &key, p, 0, 1);568568+}569569+570570+/*571571+ * If remove is 1, then we are removing free space, thus clearing bits in the572572+ * bitmap. If remove is 0, then we are adding free space, thus setting bits in573573+ * the bitmap.574574+ */575575+static int modify_free_space_bitmap(struct btrfs_trans_handle *trans,576576+ struct btrfs_fs_info *fs_info,577577+ struct btrfs_block_group_cache *block_group,578578+ struct btrfs_path *path,579579+ u64 start, u64 size, int remove)580580+{581581+ struct btrfs_root *root = fs_info->free_space_root;582582+ struct btrfs_key key;583583+ u64 end = start + size;584584+ u64 cur_start, cur_size;585585+ int prev_bit, next_bit;586586+ int new_extents;587587+ int ret;588588+589589+ /*590590+ * Read the bit for the block immediately before the extent of space if591591+ * that block is within the block group.592592+ */593593+ if (start > block_group->key.objectid) {594594+ u64 prev_block = start - block_group->sectorsize;595595+596596+ key.objectid = prev_block;597597+ key.type = (u8)-1;598598+ key.offset = (u64)-1;599599+600600+ ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);601601+ if (ret)602602+ goto out;603603+604604+ prev_bit = free_space_test_bit(block_group, path, prev_block);605605+606606+ /* The previous block may have been in the previous bitmap. */607607+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);608608+ if (start >= key.objectid + key.offset) {609609+ ret = free_space_next_bitmap(trans, root, path);610610+ if (ret)611611+ goto out;612612+ }613613+ } else {614614+ key.objectid = start;615615+ key.type = (u8)-1;616616+ key.offset = (u64)-1;617617+618618+ ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);619619+ if (ret)620620+ goto out;621621+622622+ prev_bit = -1;623623+ }624624+625625+ /*626626+ * Iterate over all of the bitmaps overlapped by the extent of space,627627+ * clearing/setting bits as required.628628+ */629629+ cur_start = start;630630+ cur_size = size;631631+ while (1) {632632+ free_space_set_bits(block_group, path, &cur_start, &cur_size,633633+ !remove);634634+ if (cur_size == 0)635635+ break;636636+ ret = free_space_next_bitmap(trans, root, path);637637+ if (ret)638638+ goto out;639639+ }640640+641641+ /*642642+ * Read the bit for the block immediately after the extent of space if643643+ * that block is within the block group.644644+ */645645+ if (end < block_group->key.objectid + block_group->key.offset) {646646+ /* The next block may be in the next bitmap. */647647+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);648648+ if (end >= key.objectid + key.offset) {649649+ ret = free_space_next_bitmap(trans, root, path);650650+ if (ret)651651+ goto out;652652+ }653653+654654+ next_bit = free_space_test_bit(block_group, path, end);655655+ } else {656656+ next_bit = -1;657657+ }658658+659659+ if (remove) {660660+ new_extents = -1;661661+ if (prev_bit == 1) {662662+ /* Leftover on the left. */663663+ new_extents++;664664+ }665665+ if (next_bit == 1) {666666+ /* Leftover on the right. */667667+ new_extents++;668668+ }669669+ } else {670670+ new_extents = 1;671671+ if (prev_bit == 1) {672672+ /* Merging with neighbor on the left. */673673+ new_extents--;674674+ }675675+ if (next_bit == 1) {676676+ /* Merging with neighbor on the right. */677677+ new_extents--;678678+ }679679+ }680680+681681+ btrfs_release_path(path);682682+ ret = update_free_space_extent_count(trans, fs_info, block_group, path,683683+ new_extents);684684+685685+out:686686+ return ret;687687+}688688+689689+static int remove_free_space_extent(struct btrfs_trans_handle *trans,690690+ struct btrfs_fs_info *fs_info,691691+ struct btrfs_block_group_cache *block_group,692692+ struct btrfs_path *path,693693+ u64 start, u64 size)694694+{695695+ struct btrfs_root *root = fs_info->free_space_root;696696+ struct btrfs_key key;697697+ u64 found_start, found_end;698698+ u64 end = start + size;699699+ int new_extents = -1;700700+ int ret;701701+702702+ key.objectid = start;703703+ key.type = (u8)-1;704704+ key.offset = (u64)-1;705705+706706+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);707707+ if (ret)708708+ goto out;709709+710710+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);711711+712712+ ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);713713+714714+ found_start = key.objectid;715715+ found_end = key.objectid + key.offset;716716+ ASSERT(start >= found_start && end <= found_end);717717+718718+ /*719719+ * Okay, now that we've found the free space extent which contains the720720+ * free space that we are removing, there are four cases:721721+ *722722+ * 1. We're using the whole extent: delete the key we found and723723+ * decrement the free space extent count.724724+ * 2. We are using part of the extent starting at the beginning: delete725725+ * the key we found and insert a new key representing the leftover at726726+ * the end. There is no net change in the number of extents.727727+ * 3. We are using part of the extent ending at the end: delete the key728728+ * we found and insert a new key representing the leftover at the729729+ * beginning. There is no net change in the number of extents.730730+ * 4. We are using part of the extent in the middle: delete the key we731731+ * found and insert two new keys representing the leftovers on each732732+ * side. Where we used to have one extent, we now have two, so increment733733+ * the extent count. We may need to convert the block group to bitmaps734734+ * as a result.735735+ */736736+737737+ /* Delete the existing key (cases 1-4). */738738+ ret = btrfs_del_item(trans, root, path);739739+ if (ret)740740+ goto out;741741+742742+ /* Add a key for leftovers at the beginning (cases 3 and 4). */743743+ if (start > found_start) {744744+ key.objectid = found_start;745745+ key.type = BTRFS_FREE_SPACE_EXTENT_KEY;746746+ key.offset = start - found_start;747747+748748+ btrfs_release_path(path);749749+ ret = btrfs_insert_empty_item(trans, root, path, &key, 0);750750+ if (ret)751751+ goto out;752752+ new_extents++;753753+ }754754+755755+ /* Add a key for leftovers at the end (cases 2 and 4). */756756+ if (end < found_end) {757757+ key.objectid = end;758758+ key.type = BTRFS_FREE_SPACE_EXTENT_KEY;759759+ key.offset = found_end - end;760760+761761+ btrfs_release_path(path);762762+ ret = btrfs_insert_empty_item(trans, root, path, &key, 0);763763+ if (ret)764764+ goto out;765765+ new_extents++;766766+ }767767+768768+ btrfs_release_path(path);769769+ ret = update_free_space_extent_count(trans, fs_info, block_group, path,770770+ new_extents);771771+772772+out:773773+ return ret;774774+}775775+776776+int __remove_from_free_space_tree(struct btrfs_trans_handle *trans,777777+ struct btrfs_fs_info *fs_info,778778+ struct btrfs_block_group_cache *block_group,779779+ struct btrfs_path *path, u64 start, u64 size)780780+{781781+ struct btrfs_free_space_info *info;782782+ u32 flags;783783+ int ret;784784+785785+ if (block_group->needs_free_space) {786786+ ret = __add_block_group_free_space(trans, fs_info, block_group,787787+ path);788788+ if (ret)789789+ return ret;790790+ }791791+792792+ info = search_free_space_info(NULL, fs_info, block_group, path, 0);793793+ if (IS_ERR(info))794794+ return PTR_ERR(info);795795+ flags = btrfs_free_space_flags(path->nodes[0], info);796796+ btrfs_release_path(path);797797+798798+ if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {799799+ return modify_free_space_bitmap(trans, fs_info, block_group,800800+ path, start, size, 1);801801+ } else {802802+ return remove_free_space_extent(trans, fs_info, block_group,803803+ path, start, size);804804+ }805805+}806806+807807+int remove_from_free_space_tree(struct btrfs_trans_handle *trans,808808+ struct btrfs_fs_info *fs_info,809809+ u64 start, u64 size)810810+{811811+ struct btrfs_block_group_cache *block_group;812812+ struct btrfs_path *path;813813+ int ret;814814+815815+ if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))816816+ return 0;817817+818818+ path = btrfs_alloc_path();819819+ if (!path) {820820+ ret = -ENOMEM;821821+ goto out;822822+ }823823+824824+ block_group = btrfs_lookup_block_group(fs_info, start);825825+ if (!block_group) {826826+ ASSERT(0);827827+ ret = -ENOENT;828828+ goto out;829829+ }830830+831831+ mutex_lock(&block_group->free_space_lock);832832+ ret = __remove_from_free_space_tree(trans, fs_info, block_group, path,833833+ start, size);834834+ mutex_unlock(&block_group->free_space_lock);835835+836836+ btrfs_put_block_group(block_group);837837+out:838838+ btrfs_free_path(path);839839+ if (ret)840840+ btrfs_abort_transaction(trans, fs_info->free_space_root, ret);841841+ return ret;842842+}843843+844844+static int add_free_space_extent(struct btrfs_trans_handle *trans,845845+ struct btrfs_fs_info *fs_info,846846+ struct btrfs_block_group_cache *block_group,847847+ struct btrfs_path *path,848848+ u64 start, u64 size)849849+{850850+ struct btrfs_root *root = fs_info->free_space_root;851851+ struct btrfs_key key, new_key;852852+ u64 found_start, found_end;853853+ u64 end = start + size;854854+ int new_extents = 1;855855+ int ret;856856+857857+ /*858858+ * We are adding a new extent of free space, but we need to merge859859+ * extents. There are four cases here:860860+ *861861+ * 1. The new extent does not have any immediate neighbors to merge862862+ * with: add the new key and increment the free space extent count. We863863+ * may need to convert the block group to bitmaps as a result.864864+ * 2. The new extent has an immediate neighbor before it: remove the865865+ * previous key and insert a new key combining both of them. There is no866866+ * net change in the number of extents.867867+ * 3. The new extent has an immediate neighbor after it: remove the next868868+ * key and insert a new key combining both of them. There is no net869869+ * change in the number of extents.870870+ * 4. The new extent has immediate neighbors on both sides: remove both871871+ * of the keys and insert a new key combining all of them. Where we used872872+ * to have two extents, we now have one, so decrement the extent count.873873+ */874874+875875+ new_key.objectid = start;876876+ new_key.type = BTRFS_FREE_SPACE_EXTENT_KEY;877877+ new_key.offset = size;878878+879879+ /* Search for a neighbor on the left. */880880+ if (start == block_group->key.objectid)881881+ goto right;882882+ key.objectid = start - 1;883883+ key.type = (u8)-1;884884+ key.offset = (u64)-1;885885+886886+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);887887+ if (ret)888888+ goto out;889889+890890+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);891891+892892+ if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {893893+ ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);894894+ btrfs_release_path(path);895895+ goto right;896896+ }897897+898898+ found_start = key.objectid;899899+ found_end = key.objectid + key.offset;900900+ ASSERT(found_start >= block_group->key.objectid &&901901+ found_end > block_group->key.objectid);902902+ ASSERT(found_start < start && found_end <= start);903903+904904+ /*905905+ * Delete the neighbor on the left and absorb it into the new key (cases906906+ * 2 and 4).907907+ */908908+ if (found_end == start) {909909+ ret = btrfs_del_item(trans, root, path);910910+ if (ret)911911+ goto out;912912+ new_key.objectid = found_start;913913+ new_key.offset += key.offset;914914+ new_extents--;915915+ }916916+ btrfs_release_path(path);917917+918918+right:919919+ /* Search for a neighbor on the right. */920920+ if (end == block_group->key.objectid + block_group->key.offset)921921+ goto insert;922922+ key.objectid = end;923923+ key.type = (u8)-1;924924+ key.offset = (u64)-1;925925+926926+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);927927+ if (ret)928928+ goto out;929929+930930+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);931931+932932+ if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {933933+ ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);934934+ btrfs_release_path(path);935935+ goto insert;936936+ }937937+938938+ found_start = key.objectid;939939+ found_end = key.objectid + key.offset;940940+ ASSERT(found_start >= block_group->key.objectid &&941941+ found_end > block_group->key.objectid);942942+ ASSERT((found_start < start && found_end <= start) ||943943+ (found_start >= end && found_end > end));944944+945945+ /*946946+ * Delete the neighbor on the right and absorb it into the new key947947+ * (cases 3 and 4).948948+ */949949+ if (found_start == end) {950950+ ret = btrfs_del_item(trans, root, path);951951+ if (ret)952952+ goto out;953953+ new_key.offset += key.offset;954954+ new_extents--;955955+ }956956+ btrfs_release_path(path);957957+958958+insert:959959+ /* Insert the new key (cases 1-4). */960960+ ret = btrfs_insert_empty_item(trans, root, path, &new_key, 0);961961+ if (ret)962962+ goto out;963963+964964+ btrfs_release_path(path);965965+ ret = update_free_space_extent_count(trans, fs_info, block_group, path,966966+ new_extents);967967+968968+out:969969+ return ret;970970+}971971+972972+int __add_to_free_space_tree(struct btrfs_trans_handle *trans,973973+ struct btrfs_fs_info *fs_info,974974+ struct btrfs_block_group_cache *block_group,975975+ struct btrfs_path *path, u64 start, u64 size)976976+{977977+ struct btrfs_free_space_info *info;978978+ u32 flags;979979+ int ret;980980+981981+ if (block_group->needs_free_space) {982982+ ret = __add_block_group_free_space(trans, fs_info, block_group,983983+ path);984984+ if (ret)985985+ return ret;986986+ }987987+988988+ info = search_free_space_info(NULL, fs_info, block_group, path, 0);989989+ if (IS_ERR(info))990990+ return PTR_ERR(info);991991+ flags = btrfs_free_space_flags(path->nodes[0], info);992992+ btrfs_release_path(path);993993+994994+ if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {995995+ return modify_free_space_bitmap(trans, fs_info, block_group,996996+ path, start, size, 0);997997+ } else {998998+ return add_free_space_extent(trans, fs_info, block_group, path,999999+ start, size);10001000+ }10011001+}10021002+10031003+int add_to_free_space_tree(struct btrfs_trans_handle *trans,10041004+ struct btrfs_fs_info *fs_info,10051005+ u64 start, u64 size)10061006+{10071007+ struct btrfs_block_group_cache *block_group;10081008+ struct btrfs_path *path;10091009+ int ret;10101010+10111011+ if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))10121012+ return 0;10131013+10141014+ path = btrfs_alloc_path();10151015+ if (!path) {10161016+ ret = -ENOMEM;10171017+ goto out;10181018+ }10191019+10201020+ block_group = btrfs_lookup_block_group(fs_info, start);10211021+ if (!block_group) {10221022+ ASSERT(0);10231023+ ret = -ENOENT;10241024+ goto out;10251025+ }10261026+10271027+ mutex_lock(&block_group->free_space_lock);10281028+ ret = __add_to_free_space_tree(trans, fs_info, block_group, path, start,10291029+ size);10301030+ mutex_unlock(&block_group->free_space_lock);10311031+10321032+ btrfs_put_block_group(block_group);10331033+out:10341034+ btrfs_free_path(path);10351035+ if (ret)10361036+ btrfs_abort_transaction(trans, fs_info->free_space_root, ret);10371037+ return ret;10381038+}10391039+10401040+/*10411041+ * Populate the free space tree by walking the extent tree. Operations on the10421042+ * extent tree that happen as a result of writes to the free space tree will go10431043+ * through the normal add/remove hooks.10441044+ */10451045+static int populate_free_space_tree(struct btrfs_trans_handle *trans,10461046+ struct btrfs_fs_info *fs_info,10471047+ struct btrfs_block_group_cache *block_group)10481048+{10491049+ struct btrfs_root *extent_root = fs_info->extent_root;10501050+ struct btrfs_path *path, *path2;10511051+ struct btrfs_key key;10521052+ u64 start, end;10531053+ int ret;10541054+10551055+ path = btrfs_alloc_path();10561056+ if (!path)10571057+ return -ENOMEM;10581058+ path->reada = 1;10591059+10601060+ path2 = btrfs_alloc_path();10611061+ if (!path2) {10621062+ btrfs_free_path(path);10631063+ return -ENOMEM;10641064+ }10651065+10661066+ ret = add_new_free_space_info(trans, fs_info, block_group, path2);10671067+ if (ret)10681068+ goto out;10691069+10701070+ /*10711071+ * Iterate through all of the extent and metadata items in this block10721072+ * group, adding the free space between them and the free space at the10731073+ * end. Note that EXTENT_ITEM and METADATA_ITEM are less than10741074+ * BLOCK_GROUP_ITEM, so an extent may precede the block group that it's10751075+ * contained in.10761076+ */10771077+ key.objectid = block_group->key.objectid;10781078+ key.type = BTRFS_EXTENT_ITEM_KEY;10791079+ key.offset = 0;10801080+10811081+ ret = btrfs_search_slot_for_read(extent_root, &key, path, 1, 0);10821082+ if (ret < 0)10831083+ goto out;10841084+ ASSERT(ret == 0);10851085+10861086+ start = block_group->key.objectid;10871087+ end = block_group->key.objectid + block_group->key.offset;10881088+ while (1) {10891089+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);10901090+10911091+ if (key.type == BTRFS_EXTENT_ITEM_KEY ||10921092+ key.type == BTRFS_METADATA_ITEM_KEY) {10931093+ if (key.objectid >= end)10941094+ break;10951095+10961096+ if (start < key.objectid) {10971097+ ret = __add_to_free_space_tree(trans, fs_info,10981098+ block_group,10991099+ path2, start,11001100+ key.objectid -11011101+ start);11021102+ if (ret)11031103+ goto out;11041104+ }11051105+ start = key.objectid;11061106+ if (key.type == BTRFS_METADATA_ITEM_KEY)11071107+ start += fs_info->tree_root->nodesize;11081108+ else11091109+ start += key.offset;11101110+ } else if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {11111111+ if (key.objectid != block_group->key.objectid)11121112+ break;11131113+ }11141114+11151115+ ret = btrfs_next_item(extent_root, path);11161116+ if (ret < 0)11171117+ goto out;11181118+ if (ret)11191119+ break;11201120+ }11211121+ if (start < end) {11221122+ ret = __add_to_free_space_tree(trans, fs_info, block_group,11231123+ path2, start, end - start);11241124+ if (ret)11251125+ goto out;11261126+ }11271127+11281128+ ret = 0;11291129+out:11301130+ btrfs_free_path(path2);11311131+ btrfs_free_path(path);11321132+ return ret;11331133+}11341134+11351135+int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)11361136+{11371137+ struct btrfs_trans_handle *trans;11381138+ struct btrfs_root *tree_root = fs_info->tree_root;11391139+ struct btrfs_root *free_space_root;11401140+ struct btrfs_block_group_cache *block_group;11411141+ struct rb_node *node;11421142+ int ret;11431143+11441144+ trans = btrfs_start_transaction(tree_root, 0);11451145+ if (IS_ERR(trans))11461146+ return PTR_ERR(trans);11471147+11481148+ free_space_root = btrfs_create_tree(trans, fs_info,11491149+ BTRFS_FREE_SPACE_TREE_OBJECTID);11501150+ if (IS_ERR(free_space_root)) {11511151+ ret = PTR_ERR(free_space_root);11521152+ goto abort;11531153+ }11541154+ fs_info->free_space_root = free_space_root;11551155+11561156+ node = rb_first(&fs_info->block_group_cache_tree);11571157+ while (node) {11581158+ block_group = rb_entry(node, struct btrfs_block_group_cache,11591159+ cache_node);11601160+ ret = populate_free_space_tree(trans, fs_info, block_group);11611161+ if (ret)11621162+ goto abort;11631163+ node = rb_next(node);11641164+ }11651165+11661166+ btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);11671167+11681168+ ret = btrfs_commit_transaction(trans, tree_root);11691169+ if (ret)11701170+ return ret;11711171+11721172+ return 0;11731173+11741174+abort:11751175+ btrfs_abort_transaction(trans, tree_root, ret);11761176+ btrfs_end_transaction(trans, tree_root);11771177+ return ret;11781178+}11791179+11801180+static int clear_free_space_tree(struct btrfs_trans_handle *trans,11811181+ struct btrfs_root *root)11821182+{11831183+ struct btrfs_path *path;11841184+ struct btrfs_key key;11851185+ int nr;11861186+ int ret;11871187+11881188+ path = btrfs_alloc_path();11891189+ if (!path)11901190+ return -ENOMEM;11911191+11921192+ path->leave_spinning = 1;11931193+11941194+ key.objectid = 0;11951195+ key.type = 0;11961196+ key.offset = 0;11971197+11981198+ while (1) {11991199+ ret = btrfs_search_slot(trans, root, &key, path, -1, 1);12001200+ if (ret < 0)12011201+ goto out;12021202+12031203+ nr = btrfs_header_nritems(path->nodes[0]);12041204+ if (!nr)12051205+ break;12061206+12071207+ path->slots[0] = 0;12081208+ ret = btrfs_del_items(trans, root, path, 0, nr);12091209+ if (ret)12101210+ goto out;12111211+12121212+ btrfs_release_path(path);12131213+ }12141214+12151215+ ret = 0;12161216+out:12171217+ btrfs_free_path(path);12181218+ return ret;12191219+}12201220+12211221+int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info)12221222+{12231223+ struct btrfs_trans_handle *trans;12241224+ struct btrfs_root *tree_root = fs_info->tree_root;12251225+ struct btrfs_root *free_space_root = fs_info->free_space_root;12261226+ int ret;12271227+12281228+ trans = btrfs_start_transaction(tree_root, 0);12291229+ if (IS_ERR(trans))12301230+ return PTR_ERR(trans);12311231+12321232+ btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);12331233+ fs_info->free_space_root = NULL;12341234+12351235+ ret = clear_free_space_tree(trans, free_space_root);12361236+ if (ret)12371237+ goto abort;12381238+12391239+ ret = btrfs_del_root(trans, tree_root, &free_space_root->root_key);12401240+ if (ret)12411241+ goto abort;12421242+12431243+ list_del(&free_space_root->dirty_list);12441244+12451245+ btrfs_tree_lock(free_space_root->node);12461246+ clean_tree_block(trans, tree_root->fs_info, free_space_root->node);12471247+ btrfs_tree_unlock(free_space_root->node);12481248+ btrfs_free_tree_block(trans, free_space_root, free_space_root->node,12491249+ 0, 1);12501250+12511251+ free_extent_buffer(free_space_root->node);12521252+ free_extent_buffer(free_space_root->commit_root);12531253+ kfree(free_space_root);12541254+12551255+ ret = btrfs_commit_transaction(trans, tree_root);12561256+ if (ret)12571257+ return ret;12581258+12591259+ return 0;12601260+12611261+abort:12621262+ btrfs_abort_transaction(trans, tree_root, ret);12631263+ btrfs_end_transaction(trans, tree_root);12641264+ return ret;12651265+}12661266+12671267+static int __add_block_group_free_space(struct btrfs_trans_handle *trans,12681268+ struct btrfs_fs_info *fs_info,12691269+ struct btrfs_block_group_cache *block_group,12701270+ struct btrfs_path *path)12711271+{12721272+ u64 start, end;12731273+ int ret;12741274+12751275+ start = block_group->key.objectid;12761276+ end = block_group->key.objectid + block_group->key.offset;12771277+12781278+ block_group->needs_free_space = 0;12791279+12801280+ ret = add_new_free_space_info(trans, fs_info, block_group, path);12811281+ if (ret)12821282+ return ret;12831283+12841284+ return __add_to_free_space_tree(trans, fs_info, block_group, path,12851285+ block_group->key.objectid,12861286+ block_group->key.offset);12871287+}12881288+12891289+int add_block_group_free_space(struct btrfs_trans_handle *trans,12901290+ struct btrfs_fs_info *fs_info,12911291+ struct btrfs_block_group_cache *block_group)12921292+{12931293+ struct btrfs_path *path = NULL;12941294+ int ret = 0;12951295+12961296+ if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))12971297+ return 0;12981298+12991299+ mutex_lock(&block_group->free_space_lock);13001300+ if (!block_group->needs_free_space)13011301+ goto out;13021302+13031303+ path = btrfs_alloc_path();13041304+ if (!path) {13051305+ ret = -ENOMEM;13061306+ goto out;13071307+ }13081308+13091309+ ret = __add_block_group_free_space(trans, fs_info, block_group, path);13101310+13111311+out:13121312+ btrfs_free_path(path);13131313+ mutex_unlock(&block_group->free_space_lock);13141314+ if (ret)13151315+ btrfs_abort_transaction(trans, fs_info->free_space_root, ret);13161316+ return ret;13171317+}13181318+13191319+int remove_block_group_free_space(struct btrfs_trans_handle *trans,13201320+ struct btrfs_fs_info *fs_info,13211321+ struct btrfs_block_group_cache *block_group)13221322+{13231323+ struct btrfs_root *root = fs_info->free_space_root;13241324+ struct btrfs_path *path;13251325+ struct btrfs_key key, found_key;13261326+ struct extent_buffer *leaf;13271327+ u64 start, end;13281328+ int done = 0, nr;13291329+ int ret;13301330+13311331+ if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))13321332+ return 0;13331333+13341334+ if (block_group->needs_free_space) {13351335+ /* We never added this block group to the free space tree. */13361336+ return 0;13371337+ }13381338+13391339+ path = btrfs_alloc_path();13401340+ if (!path) {13411341+ ret = -ENOMEM;13421342+ goto out;13431343+ }13441344+13451345+ start = block_group->key.objectid;13461346+ end = block_group->key.objectid + block_group->key.offset;13471347+13481348+ key.objectid = end - 1;13491349+ key.type = (u8)-1;13501350+ key.offset = (u64)-1;13511351+13521352+ while (!done) {13531353+ ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);13541354+ if (ret)13551355+ goto out;13561356+13571357+ leaf = path->nodes[0];13581358+ nr = 0;13591359+ path->slots[0]++;13601360+ while (path->slots[0] > 0) {13611361+ btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);13621362+13631363+ if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {13641364+ ASSERT(found_key.objectid == block_group->key.objectid);13651365+ ASSERT(found_key.offset == block_group->key.offset);13661366+ done = 1;13671367+ nr++;13681368+ path->slots[0]--;13691369+ break;13701370+ } else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY ||13711371+ found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {13721372+ ASSERT(found_key.objectid >= start);13731373+ ASSERT(found_key.objectid < end);13741374+ ASSERT(found_key.objectid + found_key.offset <= end);13751375+ nr++;13761376+ path->slots[0]--;13771377+ } else {13781378+ ASSERT(0);13791379+ }13801380+ }13811381+13821382+ ret = btrfs_del_items(trans, root, path, path->slots[0], nr);13831383+ if (ret)13841384+ goto out;13851385+ btrfs_release_path(path);13861386+ }13871387+13881388+ ret = 0;13891389+out:13901390+ btrfs_free_path(path);13911391+ if (ret)13921392+ btrfs_abort_transaction(trans, root, ret);13931393+ return ret;13941394+}13951395+13961396+static int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,13971397+ struct btrfs_path *path,13981398+ u32 expected_extent_count)13991399+{14001400+ struct btrfs_block_group_cache *block_group;14011401+ struct btrfs_fs_info *fs_info;14021402+ struct btrfs_root *root;14031403+ struct btrfs_key key;14041404+ int prev_bit = 0, bit;14051405+ /* Initialize to silence GCC. */14061406+ u64 extent_start = 0;14071407+ u64 end, offset;14081408+ u64 total_found = 0;14091409+ u32 extent_count = 0;14101410+ int ret;14111411+14121412+ block_group = caching_ctl->block_group;14131413+ fs_info = block_group->fs_info;14141414+ root = fs_info->free_space_root;14151415+14161416+ end = block_group->key.objectid + block_group->key.offset;14171417+14181418+ while (1) {14191419+ ret = btrfs_next_item(root, path);14201420+ if (ret < 0)14211421+ goto out;14221422+ if (ret)14231423+ break;14241424+14251425+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);14261426+14271427+ if (key.type == BTRFS_FREE_SPACE_INFO_KEY)14281428+ break;14291429+14301430+ ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);14311431+ ASSERT(key.objectid < end && key.objectid + key.offset <= end);14321432+14331433+ caching_ctl->progress = key.objectid;14341434+14351435+ offset = key.objectid;14361436+ while (offset < key.objectid + key.offset) {14371437+ bit = free_space_test_bit(block_group, path, offset);14381438+ if (prev_bit == 0 && bit == 1) {14391439+ extent_start = offset;14401440+ } else if (prev_bit == 1 && bit == 0) {14411441+ total_found += add_new_free_space(block_group,14421442+ fs_info,14431443+ extent_start,14441444+ offset);14451445+ if (total_found > CACHING_CTL_WAKE_UP) {14461446+ total_found = 0;14471447+ wake_up(&caching_ctl->wait);14481448+ }14491449+ extent_count++;14501450+ }14511451+ prev_bit = bit;14521452+ offset += block_group->sectorsize;14531453+ }14541454+ }14551455+ if (prev_bit == 1) {14561456+ total_found += add_new_free_space(block_group, fs_info,14571457+ extent_start, end);14581458+ extent_count++;14591459+ }14601460+14611461+ if (extent_count != expected_extent_count) {14621462+ btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",14631463+ block_group->key.objectid, extent_count,14641464+ expected_extent_count);14651465+ ASSERT(0);14661466+ ret = -EIO;14671467+ goto out;14681468+ }14691469+14701470+ caching_ctl->progress = (u64)-1;14711471+14721472+ ret = 0;14731473+out:14741474+ return ret;14751475+}14761476+14771477+static int load_free_space_extents(struct btrfs_caching_control *caching_ctl,14781478+ struct btrfs_path *path,14791479+ u32 expected_extent_count)14801480+{14811481+ struct btrfs_block_group_cache *block_group;14821482+ struct btrfs_fs_info *fs_info;14831483+ struct btrfs_root *root;14841484+ struct btrfs_key key;14851485+ u64 end;14861486+ u64 total_found = 0;14871487+ u32 extent_count = 0;14881488+ int ret;14891489+14901490+ block_group = caching_ctl->block_group;14911491+ fs_info = block_group->fs_info;14921492+ root = fs_info->free_space_root;14931493+14941494+ end = block_group->key.objectid + block_group->key.offset;14951495+14961496+ while (1) {14971497+ ret = btrfs_next_item(root, path);14981498+ if (ret < 0)14991499+ goto out;15001500+ if (ret)15011501+ break;15021502+15031503+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);15041504+15051505+ if (key.type == BTRFS_FREE_SPACE_INFO_KEY)15061506+ break;15071507+15081508+ ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);15091509+ ASSERT(key.objectid < end && key.objectid + key.offset <= end);15101510+15111511+ caching_ctl->progress = key.objectid;15121512+15131513+ total_found += add_new_free_space(block_group, fs_info,15141514+ key.objectid,15151515+ key.objectid + key.offset);15161516+ if (total_found > CACHING_CTL_WAKE_UP) {15171517+ total_found = 0;15181518+ wake_up(&caching_ctl->wait);15191519+ }15201520+ extent_count++;15211521+ }15221522+15231523+ if (extent_count != expected_extent_count) {15241524+ btrfs_err(fs_info, "incorrect extent count for %llu; counted %u, expected %u",15251525+ block_group->key.objectid, extent_count,15261526+ expected_extent_count);15271527+ ASSERT(0);15281528+ ret = -EIO;15291529+ goto out;15301530+ }15311531+15321532+ caching_ctl->progress = (u64)-1;15331533+15341534+ ret = 0;15351535+out:15361536+ return ret;15371537+}15381538+15391539+int load_free_space_tree(struct btrfs_caching_control *caching_ctl)15401540+{15411541+ struct btrfs_block_group_cache *block_group;15421542+ struct btrfs_fs_info *fs_info;15431543+ struct btrfs_free_space_info *info;15441544+ struct btrfs_path *path;15451545+ u32 extent_count, flags;15461546+ int ret;15471547+15481548+ block_group = caching_ctl->block_group;15491549+ fs_info = block_group->fs_info;15501550+15511551+ path = btrfs_alloc_path();15521552+ if (!path)15531553+ return -ENOMEM;15541554+15551555+ /*15561556+ * Just like caching_thread() doesn't want to deadlock on the extent15571557+ * tree, we don't want to deadlock on the free space tree.15581558+ */15591559+ path->skip_locking = 1;15601560+ path->search_commit_root = 1;15611561+ path->reada = 1;15621562+15631563+ info = search_free_space_info(NULL, fs_info, block_group, path, 0);15641564+ if (IS_ERR(info)) {15651565+ ret = PTR_ERR(info);15661566+ goto out;15671567+ }15681568+ extent_count = btrfs_free_space_extent_count(path->nodes[0], info);15691569+ flags = btrfs_free_space_flags(path->nodes[0], info);15701570+15711571+ /*15721572+ * We left path pointing to the free space info item, so now15731573+ * load_free_space_foo can just iterate through the free space tree from15741574+ * there.15751575+ */15761576+ if (flags & BTRFS_FREE_SPACE_USING_BITMAPS)15771577+ ret = load_free_space_bitmaps(caching_ctl, path, extent_count);15781578+ else15791579+ ret = load_free_space_extents(caching_ctl, path, extent_count);15801580+15811581+out:15821582+ btrfs_free_path(path);15831583+ return ret;15841584+}
+72
fs/btrfs/free-space-tree.h
···11+/*22+ * Copyright (C) 2015 Facebook. All rights reserved.33+ *44+ * This program is free software; you can redistribute it and/or55+ * modify it under the terms of the GNU General Public66+ * License v2 as published by the Free Software Foundation.77+ *88+ * This program is distributed in the hope that it will be useful,99+ * but WITHOUT ANY WARRANTY; without even the implied warranty of1010+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU1111+ * General Public License for more details.1212+ *1313+ * You should have received a copy of the GNU General Public1414+ * License along with this program; if not, write to the1515+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,1616+ * Boston, MA 021110-1307, USA.1717+ */1818+1919+#ifndef __BTRFS_FREE_SPACE_TREE2020+#define __BTRFS_FREE_SPACE_TREE2121+2222+/*2323+ * The default size for new free space bitmap items. The last bitmap in a block2424+ * group may be truncated, and none of the free space tree code assumes that2525+ * existing bitmaps are this size.2626+ */2727+#define BTRFS_FREE_SPACE_BITMAP_SIZE 2562828+#define BTRFS_FREE_SPACE_BITMAP_BITS (BTRFS_FREE_SPACE_BITMAP_SIZE * BITS_PER_BYTE)2929+3030+void set_free_space_tree_thresholds(struct btrfs_block_group_cache *block_group);3131+int btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info);3232+int btrfs_clear_free_space_tree(struct btrfs_fs_info *fs_info);3333+int load_free_space_tree(struct btrfs_caching_control *caching_ctl);3434+int add_block_group_free_space(struct btrfs_trans_handle *trans,3535+ struct btrfs_fs_info *fs_info,3636+ struct btrfs_block_group_cache *block_group);3737+int remove_block_group_free_space(struct btrfs_trans_handle *trans,3838+ struct btrfs_fs_info *fs_info,3939+ struct btrfs_block_group_cache *block_group);4040+int add_to_free_space_tree(struct btrfs_trans_handle *trans,4141+ struct btrfs_fs_info *fs_info,4242+ u64 start, u64 size);4343+int remove_from_free_space_tree(struct btrfs_trans_handle *trans,4444+ struct btrfs_fs_info *fs_info,4545+ u64 start, u64 size);4646+4747+/* Exposed for testing. */4848+struct btrfs_free_space_info *4949+search_free_space_info(struct btrfs_trans_handle *trans,5050+ struct btrfs_fs_info *fs_info,5151+ struct btrfs_block_group_cache *block_group,5252+ struct btrfs_path *path, int cow);5353+int __add_to_free_space_tree(struct btrfs_trans_handle *trans,5454+ struct btrfs_fs_info *fs_info,5555+ struct btrfs_block_group_cache *block_group,5656+ struct btrfs_path *path, u64 start, u64 size);5757+int __remove_from_free_space_tree(struct btrfs_trans_handle *trans,5858+ struct btrfs_fs_info *fs_info,5959+ struct btrfs_block_group_cache *block_group,6060+ struct btrfs_path *path, u64 start, u64 size);6161+int convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,6262+ struct btrfs_fs_info *fs_info,6363+ struct btrfs_block_group_cache *block_group,6464+ struct btrfs_path *path);6565+int convert_free_space_to_extents(struct btrfs_trans_handle *trans,6666+ struct btrfs_fs_info *fs_info,6767+ struct btrfs_block_group_cache *block_group,6868+ struct btrfs_path *path);6969+int free_space_test_bit(struct btrfs_block_group_cache *block_group,7070+ struct btrfs_path *path, u64 offset);7171+7272+#endif
+47-9
fs/btrfs/super.c
···295295 Opt_nossd, Opt_ssd_spread, Opt_thread_pool, Opt_noacl, Opt_compress,296296 Opt_compress_type, Opt_compress_force, Opt_compress_force_type,297297 Opt_notreelog, Opt_ratio, Opt_flushoncommit, Opt_discard,298298- Opt_space_cache, Opt_clear_cache, Opt_user_subvol_rm_allowed,299299- Opt_enospc_debug, Opt_subvolrootid, Opt_defrag, Opt_inode_cache,300300- Opt_no_space_cache, Opt_recovery, Opt_skip_balance,301301- Opt_check_integrity, Opt_check_integrity_including_extent_data,298298+ Opt_space_cache, Opt_space_cache_version, Opt_clear_cache,299299+ Opt_user_subvol_rm_allowed, Opt_enospc_debug, Opt_subvolrootid,300300+ Opt_defrag, Opt_inode_cache, Opt_no_space_cache, Opt_recovery,301301+ Opt_skip_balance, Opt_check_integrity,302302+ Opt_check_integrity_including_extent_data,302303 Opt_check_integrity_print_mask, Opt_fatal_errors, Opt_rescan_uuid_tree,303304 Opt_commit_interval, Opt_barrier, Opt_nodefrag, Opt_nodiscard,304305 Opt_noenospc_debug, Opt_noflushoncommit, Opt_acl, Opt_datacow,···341340 {Opt_discard, "discard"},342341 {Opt_nodiscard, "nodiscard"},343342 {Opt_space_cache, "space_cache"},343343+ {Opt_space_cache_version, "space_cache=%s"},344344 {Opt_clear_cache, "clear_cache"},345345 {Opt_user_subvol_rm_allowed, "user_subvol_rm_allowed"},346346 {Opt_enospc_debug, "enospc_debug"},···385383 bool compress_force = false;386384387385 cache_gen = btrfs_super_cache_generation(root->fs_info->super_copy);388388- if (cache_gen)386386+ if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE))387387+ btrfs_set_opt(info->mount_opt, FREE_SPACE_TREE);388388+ else if (cache_gen)389389 btrfs_set_opt(info->mount_opt, SPACE_CACHE);390390391391 if (!options)···621617 "turning off discard");622618 break;623619 case Opt_space_cache:624624- btrfs_set_and_info(root, SPACE_CACHE,625625- "enabling disk space caching");620620+ case Opt_space_cache_version:621621+ if (token == Opt_space_cache ||622622+ strcmp(args[0].from, "v1") == 0) {623623+ btrfs_clear_opt(root->fs_info->mount_opt,624624+ FREE_SPACE_TREE);625625+ btrfs_set_and_info(root, SPACE_CACHE,626626+ "enabling disk space caching");627627+ } else if (strcmp(args[0].from, "v2") == 0) {628628+ btrfs_clear_opt(root->fs_info->mount_opt,629629+ SPACE_CACHE);630630+ btrfs_set_and_info(root, FREE_SPACE_TREE,631631+ "enabling free space tree");632632+ } else {633633+ ret = -EINVAL;634634+ goto out;635635+ }626636 break;627637 case Opt_rescan_uuid_tree:628638 btrfs_set_opt(info->mount_opt, RESCAN_UUID_TREE);629639 break;630640 case Opt_no_space_cache:631631- btrfs_clear_and_info(root, SPACE_CACHE,632632- "disabling disk space caching");641641+ if (btrfs_test_opt(root, SPACE_CACHE)) {642642+ btrfs_clear_and_info(root, SPACE_CACHE,643643+ "disabling disk space caching");644644+ }645645+ if (btrfs_test_opt(root, FREE_SPACE_TREE)) {646646+ btrfs_clear_and_info(root, FREE_SPACE_TREE,647647+ "disabling free space tree");648648+ }633649 break;634650 case Opt_inode_cache:635651 btrfs_set_pending_and_info(info, INODE_MAP_CACHE,···778754 }779755 }780756out:757757+ if (btrfs_fs_compat_ro(root->fs_info, FREE_SPACE_TREE) &&758758+ !btrfs_test_opt(root, FREE_SPACE_TREE) &&759759+ !btrfs_test_opt(root, CLEAR_CACHE)) {760760+ btrfs_err(root->fs_info, "cannot disable free space tree");761761+ ret = -EINVAL;762762+763763+ }781764 if (!ret && btrfs_test_opt(root, SPACE_CACHE))782765 btrfs_info(root->fs_info, "disk space caching is enabled");766766+ if (!ret && btrfs_test_opt(root, FREE_SPACE_TREE))767767+ btrfs_info(root->fs_info, "using free space tree");783768 kfree(orig);784769 return ret;785770}···11951162 seq_puts(seq, ",noacl");11961163 if (btrfs_test_opt(root, SPACE_CACHE))11971164 seq_puts(seq, ",space_cache");11651165+ else if (btrfs_test_opt(root, FREE_SPACE_TREE))11661166+ seq_puts(seq, ",space_cache=v2");11981167 else11991168 seq_puts(seq, ",nospace_cache");12001169 if (btrfs_test_opt(root, RESCAN_UUID_TREE))···22602225 if (ret)22612226 goto out;22622227 ret = btrfs_test_qgroups();22282228+ if (ret)22292229+ goto out;22302230+ ret = btrfs_test_free_space_tree();22632231out:22642232 btrfs_destroy_test_fs();22652233 return ret;