cache = (struct btrfs_block_group_cache *)(unsigned long)ptr;
ret = write_one_cache_group(trans, root, path, cache);
- BUG_ON(ret);
}
btrfs_free_path(path);
return 0;
u64 extra_flags = flags & (BTRFS_BLOCK_GROUP_RAID0 |
BTRFS_BLOCK_GROUP_RAID1 |
BTRFS_BLOCK_GROUP_RAID10 |
+ BTRFS_BLOCK_GROUP_RAID5 |
+ BTRFS_BLOCK_GROUP_RAID6 |
BTRFS_BLOCK_GROUP_DUP);
if (extra_flags) {
if (flags & BTRFS_BLOCK_GROUP_DATA)
u64 end;
/* block accounting for super block */
- old_val = btrfs_super_bytes_used(&info->super_copy);
+ old_val = btrfs_super_bytes_used(info->super_copy);
if (alloc)
old_val += num_bytes;
else
old_val -= num_bytes;
- btrfs_set_super_bytes_used(&info->super_copy, old_val);
+ btrfs_set_super_bytes_used(info->super_copy, old_val);
/* block accounting for root item */
old_val = btrfs_root_used(&root->root_item);
}
while (num > 0) {
cache = btrfs_lookup_block_group(fs_info, bytenr);
+ if (!cache) {
+ len = min((u64)root->sectorsize, num);
+ goto next;
+ }
WARN_ON(!cache);
len = min(num, cache->key.offset -
(bytenr - cache->key.objectid));
cache->space_info->bytes_pinned -= len;
fs_info->total_pinned -= len;
}
+next:
bytenr += len;
num -= len;
}
return 0;
}
+static int extent_root_pending_ops(struct btrfs_fs_info *info)
+{
+ u64 start;
+ u64 end;
+ int ret;
+
+ ret = find_first_extent_bit(&info->extent_ins, 0, &start,
+ &end, EXTENT_LOCKED);
+ if (!ret) {
+ ret = find_first_extent_bit(&info->pending_del, 0, &start, &end,
+ EXTENT_LOCKED);
+ }
+ return ret == 0;
+
+}
static int finish_current_insert(struct btrfs_trans_handle *trans,
struct btrfs_root *extent_root)
{
u32 item_size;
u64 refs;
+ if (root->fs_info->free_extent_hook) {
+ root->fs_info->free_extent_hook(trans, root, bytenr, num_bytes,
+ parent, root_objectid, owner_objectid,
+ owner_offset, refs_to_drop);
+
+ }
path = btrfs_alloc_path();
if (!path)
return -ENOMEM;
BUG_ON(ret);
}
- ret = update_block_group(trans, root, bytenr, num_bytes, 0,
- mark_free);
- BUG_ON(ret);
+ update_block_group(trans, root, bytenr, num_bytes, 0, mark_free);
}
fail:
btrfs_free_path(path);
WARN_ON(num_bytes < root->sectorsize);
btrfs_set_key_type(ins, BTRFS_EXTENT_ITEM_KEY);
+ search_start = stripe_align(root, search_start);
+
if (hint_byte) {
block_group = btrfs_lookup_first_block_group(info, hint_byte);
if (!block_group)
total_needed += empty_size;
check_failed:
+ search_start = stripe_align(root, search_start);
if (!block_group) {
block_group = btrfs_lookup_first_block_group(info,
search_start);
if (ret)
goto error;
- search_start = stripe_align(root, search_start);
ins->objectid = search_start;
ins->offset = num_bytes;
ret = update_block_group(trans, root, ins->objectid, ins->offset,
1, 0);
- if (ret) {
- printk(KERN_ERR "btrfs update block group failed for %llu "
- "%llu\n", (unsigned long long)ins->objectid,
- (unsigned long long)ins->offset);
- BUG();
- }
- return ret;
+ return 0;
}
static int alloc_tree_block(struct btrfs_trans_handle *trans,
int btrfs_free_block_groups(struct btrfs_fs_info *info)
{
+ struct btrfs_space_info *sinfo;
u64 start;
u64 end;
u64 ptr;
int ret;
+
while(1) {
ret = find_first_extent_bit(&info->block_group_cache, 0,
&start, &end, (unsigned int)-1);
clear_extent_dirty(&info->free_space_cache, start,
end, GFP_NOFS);
}
+
+ while (!list_empty(&info->space_info)) {
+ sinfo = list_entry(info->space_info.next,
+ struct btrfs_space_info, list);
+ list_del_init(&sinfo->list);
+ kfree(sinfo);
+ }
return 0;
}
finish_current_insert(trans, extent_root);
ret = del_pending_extents(trans, extent_root);
- BUG_ON(ret);
set_avail_alloc_bits(extent_root->fs_info, type);
return 0;
}
extent_root = root->fs_info->extent_root;
block_group_cache = &root->fs_info->block_group_cache;
chunk_objectid = BTRFS_FIRST_CHUNK_TREE_OBJECTID;
- total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
+ total_bytes = btrfs_super_total_bytes(root->fs_info->super_copy);
group_align = 64 * root->sectorsize;
cur_start = 0;
struct btrfs_block_group_cache *cache;
struct btrfs_fs_info *fs_info = root->fs_info;
+ root = root->fs_info->extent_root;
+
+ while(extent_root_pending_ops(fs_info)) {
+ ret = finish_current_insert(trans, root);
+ if (ret)
+ return ret;
+ ret = del_pending_extents(trans, root);
+ if (ret)
+ return ret;
+ }
+
while(1) {
- cache = btrfs_lookup_block_group(fs_info, start);
+ cache = btrfs_lookup_first_block_group(fs_info, start);
if (!cache)
break;
start = cache->key.objectid + cache->key.offset;
btrfs_set_block_group_used(&cache->item, 0);
cache->space_info->bytes_used = 0;
+ set_extent_bits(&root->fs_info->block_group_cache,
+ cache->key.objectid,
+ cache->key.objectid + cache->key.offset -1,
+ BLOCK_GROUP_DIRTY, GFP_NOFS);
}
btrfs_init_path(&path);
}
path.slots[0]++;
}
- btrfs_set_super_bytes_used(&root->fs_info->super_copy, bytes_used);
+ btrfs_set_super_bytes_used(root->fs_info->super_copy, bytes_used);
btrfs_release_path(root, &path);
return 0;
}