Loading fs/btrfs/ctree.h +1 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ struct btrfs_block_group_item { struct btrfs_block_group_cache { struct btrfs_key key; struct btrfs_block_group_item item; struct radix_tree_root *radix; u64 first_free; u64 last_alloc; u64 pinned; Loading fs/btrfs/extent-tree.c +33 −42 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ static struct btrfs_block_group_cache *lookup_block_group(struct (void **)&block_group, blocknr, 1); if (ret) { if (block_group->key.objectid <= blocknr && blocknr < if (block_group->key.objectid <= blocknr && blocknr <= block_group->key.objectid + block_group->key.offset) return block_group; } Loading @@ -31,11 +31,16 @@ static struct btrfs_block_group_cache *lookup_block_group(struct (void **)&block_group, blocknr, 1); if (ret) { if (block_group->key.objectid <= blocknr && blocknr < if (block_group->key.objectid <= blocknr && blocknr <= block_group->key.objectid + block_group->key.offset) return block_group; } WARN_ON(1); printk("lookup_block_group fails for blocknr %Lu\n", blocknr); printk("last ret was %d\n", ret); if (ret) { printk("last block group was %Lu %Lu\n", block_group->key.objectid, block_group->key.offset); } return NULL; } Loading Loading @@ -356,45 +361,20 @@ static int update_block_group(struct btrfs_trans_handle *trans, { struct btrfs_block_group_cache *cache; struct btrfs_fs_info *info = root->fs_info; struct radix_tree_root *radix; u64 total = num; u64 old_val; u64 block_in_group; int ret; if (num != 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; while(total) { ret = radix_tree_gang_lookup(radix, (void **)&cache, blocknr, 1); if (!ret) { printk(KERN_CRIT "blocknr %Lu lookup failed\n", blocknr); return -1; } block_in_group = blocknr - cache->key.objectid; if (block_in_group > cache->key.offset || cache->key.objectid > blocknr) { if (radix == &info->block_group_data_radix) radix = &info->block_group_radix; else radix = &info->block_group_data_radix; ret = radix_tree_gang_lookup(radix, (void **)&cache, blocknr, 1); if (!ret) { cache = lookup_block_group(info, blocknr); if (!cache) { printk(KERN_CRIT "blocknr %Lu lookup failed\n", blocknr); return -1; } block_in_group = blocknr - cache->key.objectid; if (block_in_group > cache->key.offset || cache->key.objectid > blocknr) { BUG(); } } WARN_ON(block_in_group > cache->key.offset); radix_tree_tag_set(radix, cache->key.objectid + radix_tree_tag_set(cache->radix, cache->key.objectid + cache->key.offset - 1, BTRFS_BLOCK_GROUP_DIRTY); Loading Loading @@ -693,6 +673,8 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root num_blocks = 1; total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3; } if (search_end == (u64)-1) search_end = btrfs_super_total_blocks(info->disk_super); if (search_start) { block_group = lookup_block_group(info, search_start); block_group = btrfs_find_block_group(root, block_group, Loading @@ -704,7 +686,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root } check_failed: if (block_group->data != data) if (!full_scan && block_group->data != data) WARN_ON(1); if (block_group->last_alloc > search_start) search_start = block_group->last_alloc; Loading Loading @@ -734,13 +716,13 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root goto error; if (!start_found) { ins->objectid = search_start; ins->offset = (u64)-1 - search_start; ins->offset = search_end - search_start; start_found = 1; goto check_pending; } ins->objectid = last_block > search_start ? last_block : search_start; ins->offset = (u64)-1 - ins->objectid; ins->offset = search_end - ins->objectid; goto check_pending; } btrfs_disk_key_to_cpu(&key, &l->items[slot].key); Loading Loading @@ -777,7 +759,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root */ btrfs_release_path(root, path); BUG_ON(ins->objectid < search_start); if (ins->objectid >= btrfs_super_total_blocks(info->disk_super)) { if (ins->objectid + num_blocks >= search_end) { if (full_scan) return -ENOSPC; search_start = orig_search_start; Loading Loading @@ -840,7 +822,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root return 0; new_group: if (search_start >= btrfs_super_total_blocks(info->disk_super)) { if (search_start + num_blocks >= search_end) { search_start = orig_search_start; full_scan = 1; } Loading Loading @@ -900,7 +882,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, return ret; /* then do prealloc for the extent tree */ ret = find_free_extent(trans, root, 0, ins->objectid + ins->offset, if (ins->objectid + ins->offset >= search_end) search_end = ins->objectid - 1; else search_start = ins->objectid + ins->offset; ret = find_free_extent(trans, root, 0, search_start, search_end, &prealloc_key, 0); if (ret) return ret; Loading Loading @@ -1198,6 +1185,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) err = -1; break; } if (nr & 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; bi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_block_group_item); memcpy(&cache->item, bi, sizeof(*bi)); Loading @@ -1206,12 +1199,10 @@ int btrfs_read_block_groups(struct btrfs_root *root) cache->first_free = cache->key.objectid; cache->pinned = 0; cache->data = (nr & 1); cache->radix = radix; key.objectid = found_key.objectid + found_key.offset; btrfs_release_path(root, path); if (nr & 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; ret = radix_tree_insert(radix, found_key.objectid + found_key.offset - 1, (void *)cache); Loading Loading
fs/btrfs/ctree.h +1 −0 Original line number Diff line number Diff line Loading @@ -255,6 +255,7 @@ struct btrfs_block_group_item { struct btrfs_block_group_cache { struct btrfs_key key; struct btrfs_block_group_item item; struct radix_tree_root *radix; u64 first_free; u64 last_alloc; u64 pinned; Loading
fs/btrfs/extent-tree.c +33 −42 Original line number Diff line number Diff line Loading @@ -23,7 +23,7 @@ static struct btrfs_block_group_cache *lookup_block_group(struct (void **)&block_group, blocknr, 1); if (ret) { if (block_group->key.objectid <= blocknr && blocknr < if (block_group->key.objectid <= blocknr && blocknr <= block_group->key.objectid + block_group->key.offset) return block_group; } Loading @@ -31,11 +31,16 @@ static struct btrfs_block_group_cache *lookup_block_group(struct (void **)&block_group, blocknr, 1); if (ret) { if (block_group->key.objectid <= blocknr && blocknr < if (block_group->key.objectid <= blocknr && blocknr <= block_group->key.objectid + block_group->key.offset) return block_group; } WARN_ON(1); printk("lookup_block_group fails for blocknr %Lu\n", blocknr); printk("last ret was %d\n", ret); if (ret) { printk("last block group was %Lu %Lu\n", block_group->key.objectid, block_group->key.offset); } return NULL; } Loading Loading @@ -356,45 +361,20 @@ static int update_block_group(struct btrfs_trans_handle *trans, { struct btrfs_block_group_cache *cache; struct btrfs_fs_info *info = root->fs_info; struct radix_tree_root *radix; u64 total = num; u64 old_val; u64 block_in_group; int ret; if (num != 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; while(total) { ret = radix_tree_gang_lookup(radix, (void **)&cache, blocknr, 1); if (!ret) { printk(KERN_CRIT "blocknr %Lu lookup failed\n", blocknr); return -1; } block_in_group = blocknr - cache->key.objectid; if (block_in_group > cache->key.offset || cache->key.objectid > blocknr) { if (radix == &info->block_group_data_radix) radix = &info->block_group_radix; else radix = &info->block_group_data_radix; ret = radix_tree_gang_lookup(radix, (void **)&cache, blocknr, 1); if (!ret) { cache = lookup_block_group(info, blocknr); if (!cache) { printk(KERN_CRIT "blocknr %Lu lookup failed\n", blocknr); return -1; } block_in_group = blocknr - cache->key.objectid; if (block_in_group > cache->key.offset || cache->key.objectid > blocknr) { BUG(); } } WARN_ON(block_in_group > cache->key.offset); radix_tree_tag_set(radix, cache->key.objectid + radix_tree_tag_set(cache->radix, cache->key.objectid + cache->key.offset - 1, BTRFS_BLOCK_GROUP_DIRTY); Loading Loading @@ -693,6 +673,8 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root num_blocks = 1; total_needed = (min(level + 1, BTRFS_MAX_LEVEL) + 2) * 3; } if (search_end == (u64)-1) search_end = btrfs_super_total_blocks(info->disk_super); if (search_start) { block_group = lookup_block_group(info, search_start); block_group = btrfs_find_block_group(root, block_group, Loading @@ -704,7 +686,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root } check_failed: if (block_group->data != data) if (!full_scan && block_group->data != data) WARN_ON(1); if (block_group->last_alloc > search_start) search_start = block_group->last_alloc; Loading Loading @@ -734,13 +716,13 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root goto error; if (!start_found) { ins->objectid = search_start; ins->offset = (u64)-1 - search_start; ins->offset = search_end - search_start; start_found = 1; goto check_pending; } ins->objectid = last_block > search_start ? last_block : search_start; ins->offset = (u64)-1 - ins->objectid; ins->offset = search_end - ins->objectid; goto check_pending; } btrfs_disk_key_to_cpu(&key, &l->items[slot].key); Loading Loading @@ -777,7 +759,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root */ btrfs_release_path(root, path); BUG_ON(ins->objectid < search_start); if (ins->objectid >= btrfs_super_total_blocks(info->disk_super)) { if (ins->objectid + num_blocks >= search_end) { if (full_scan) return -ENOSPC; search_start = orig_search_start; Loading Loading @@ -840,7 +822,7 @@ static int find_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root return 0; new_group: if (search_start >= btrfs_super_total_blocks(info->disk_super)) { if (search_start + num_blocks >= search_end) { search_start = orig_search_start; full_scan = 1; } Loading Loading @@ -900,7 +882,12 @@ int btrfs_alloc_extent(struct btrfs_trans_handle *trans, return ret; /* then do prealloc for the extent tree */ ret = find_free_extent(trans, root, 0, ins->objectid + ins->offset, if (ins->objectid + ins->offset >= search_end) search_end = ins->objectid - 1; else search_start = ins->objectid + ins->offset; ret = find_free_extent(trans, root, 0, search_start, search_end, &prealloc_key, 0); if (ret) return ret; Loading Loading @@ -1198,6 +1185,12 @@ int btrfs_read_block_groups(struct btrfs_root *root) err = -1; break; } if (nr & 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; bi = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_block_group_item); memcpy(&cache->item, bi, sizeof(*bi)); Loading @@ -1206,12 +1199,10 @@ int btrfs_read_block_groups(struct btrfs_root *root) cache->first_free = cache->key.objectid; cache->pinned = 0; cache->data = (nr & 1); cache->radix = radix; key.objectid = found_key.objectid + found_key.offset; btrfs_release_path(root, path); if (nr & 1) radix = &info->block_group_data_radix; else radix = &info->block_group_radix; ret = radix_tree_insert(radix, found_key.objectid + found_key.offset - 1, (void *)cache); Loading