Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 332563
b: refs/heads/master
c: ea658ba
h: refs/heads/master
i:
  332561: 3b01546
  332559: cd630e9
v: v3
  • Loading branch information
Josef Bacik authored and Chris Mason committed Oct 1, 2012
1 parent 186ec0a commit b141493
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 68 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: be3940c0a90265654d778394cafe2e2cec674df8
refs/heads/master: ea658badc47e614e38ab4d98510488474c7e6d4b
5 changes: 5 additions & 0 deletions trunk/fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1137,6 +1137,9 @@ struct btrfs_block_group_cache {
* Today it will only have one thing on it, but that may change
*/
struct list_head cluster_list;

/* For delayed block group creation */
struct list_head new_bg_list;
};

/* delayed seq elem */
Expand Down Expand Up @@ -2865,6 +2868,8 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
u64 size);
int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 group_start);
void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
u64 btrfs_reduce_alloc_profile(struct btrfs_root *root, u64 flags);
u64 btrfs_get_alloc_profile(struct btrfs_root *root, int data);
void btrfs_clear_space_info_full(struct btrfs_fs_info *info);
Expand Down
130 changes: 63 additions & 67 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -2361,10 +2361,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans,
}

next:
do_chunk_alloc(trans, fs_info->extent_root,
2 * 1024 * 1024,
btrfs_get_alloc_profile(root, 0),
CHUNK_ALLOC_NO_FORCE);
cond_resched();
spin_lock(&delayed_refs->lock);
}
Expand Down Expand Up @@ -2478,10 +2474,6 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
if (root == root->fs_info->extent_root)
root = root->fs_info->tree_root;

do_chunk_alloc(trans, root->fs_info->extent_root,
2 * 1024 * 1024, btrfs_get_alloc_profile(root, 0),
CHUNK_ALLOC_NO_FORCE);

btrfs_delayed_refs_qgroup_accounting(trans, root->fs_info);

delayed_refs = &trans->transaction->delayed_refs;
Expand Down Expand Up @@ -2551,6 +2543,12 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
}

if (run_all) {
if (!list_empty(&trans->new_bgs)) {
spin_unlock(&delayed_refs->lock);
btrfs_create_pending_block_groups(trans, root);
spin_lock(&delayed_refs->lock);
}

node = rb_first(&delayed_refs->root);
if (!node)
goto out;
Expand Down Expand Up @@ -3826,7 +3824,8 @@ enum flush_state {
FLUSH_DELALLOC_WAIT = 2,
FLUSH_DELAYED_ITEMS_NR = 3,
FLUSH_DELAYED_ITEMS = 4,
COMMIT_TRANS = 5,
ALLOC_CHUNK = 5,
COMMIT_TRANS = 6,
};

static int flush_space(struct btrfs_root *root,
Expand Down Expand Up @@ -3863,6 +3862,20 @@ static int flush_space(struct btrfs_root *root,
ret = btrfs_run_delayed_items_nr(trans, root, nr);
btrfs_end_transaction(trans, root);
break;
case ALLOC_CHUNK:
trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
break;
}
ret = do_chunk_alloc(trans, root->fs_info->extent_root,
num_bytes,
btrfs_get_alloc_profile(root, 0),
CHUNK_ALLOC_NO_FORCE);
btrfs_end_transaction(trans, root);
if (ret == -ENOSPC)
ret = 0;
break;
case COMMIT_TRANS:
ret = may_commit_transaction(root, space_info, orig_bytes, 0);
break;
Expand Down Expand Up @@ -5515,8 +5528,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *used_block_group;
u64 search_start = 0;
int empty_cluster = 2 * 1024 * 1024;
int allowed_chunk_alloc = 0;
int done_chunk_alloc = 0;
struct btrfs_space_info *space_info;
int loop = 0;
int index = 0;
Expand Down Expand Up @@ -5548,9 +5559,6 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
if (btrfs_mixed_space_info(space_info))
use_cluster = false;

if (orig_root->ref_cows || empty_size)
allowed_chunk_alloc = 1;

if (data & BTRFS_BLOCK_GROUP_METADATA && use_cluster) {
last_ptr = &root->fs_info->meta_alloc_cluster;
if (!btrfs_test_opt(root, SSD))
Expand Down Expand Up @@ -5860,34 +5868,18 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
index = 0;
loop++;
if (loop == LOOP_ALLOC_CHUNK) {
if (allowed_chunk_alloc) {
ret = do_chunk_alloc(trans, root, num_bytes +
2 * 1024 * 1024, data,
CHUNK_ALLOC_LIMITED);
/*
* Do not bail out on ENOSPC since we
* can do more things.
*/
if (ret < 0 && ret != -ENOSPC) {
btrfs_abort_transaction(trans,
root, ret);
goto out;
}
allowed_chunk_alloc = 0;
if (ret == 1)
done_chunk_alloc = 1;
} else if (!done_chunk_alloc &&
space_info->force_alloc ==
CHUNK_ALLOC_NO_FORCE) {
space_info->force_alloc = CHUNK_ALLOC_LIMITED;
ret = do_chunk_alloc(trans, root, num_bytes +
2 * 1024 * 1024, data,
CHUNK_ALLOC_FORCE);
/*
* Do not bail out on ENOSPC since we
* can do more things.
*/
if (ret < 0 && ret != -ENOSPC) {
btrfs_abort_transaction(trans,
root, ret);
goto out;
}

/*
* We didn't allocate a chunk, go ahead and drop the
* empty size and loop again.
*/
if (!done_chunk_alloc)
loop = LOOP_NO_EMPTY_SIZE;
}

if (loop == LOOP_NO_EMPTY_SIZE) {
Expand Down Expand Up @@ -5962,20 +5954,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,

data = btrfs_get_alloc_profile(root, data);
again:
/*
* the only place that sets empty_size is btrfs_realloc_node, which
* is not called recursively on allocations
*/
if (empty_size || root->ref_cows) {
ret = do_chunk_alloc(trans, root->fs_info->extent_root,
num_bytes + 2 * 1024 * 1024, data,
CHUNK_ALLOC_NO_FORCE);
if (ret < 0 && ret != -ENOSPC) {
btrfs_abort_transaction(trans, root, ret);
return ret;
}
}

WARN_ON(num_bytes < root->sectorsize);
ret = find_free_extent(trans, root, num_bytes, empty_size,
hint_byte, ins, data);
Expand All @@ -5985,12 +5963,6 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans,
num_bytes = num_bytes >> 1;
num_bytes = num_bytes & ~(root->sectorsize - 1);
num_bytes = max(num_bytes, min_alloc_size);
ret = do_chunk_alloc(trans, root->fs_info->extent_root,
num_bytes, data, CHUNK_ALLOC_FORCE);
if (ret < 0 && ret != -ENOSPC) {
btrfs_abort_transaction(trans, root, ret);
return ret;
}
if (num_bytes == min_alloc_size)
final_tried = true;
goto again;
Expand Down Expand Up @@ -7828,6 +7800,34 @@ int btrfs_read_block_groups(struct btrfs_root *root)
return ret;
}

void btrfs_create_pending_block_groups(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
struct btrfs_block_group_cache *block_group, *tmp;
struct btrfs_root *extent_root = root->fs_info->extent_root;
struct btrfs_block_group_item item;
struct btrfs_key key;
int ret = 0;

list_for_each_entry_safe(block_group, tmp, &trans->new_bgs,
new_bg_list) {
list_del_init(&block_group->new_bg_list);

if (ret)
continue;

spin_lock(&block_group->lock);
memcpy(&item, &block_group->item, sizeof(item));
memcpy(&key, &block_group->key, sizeof(key));
spin_unlock(&block_group->lock);

ret = btrfs_insert_item(trans, extent_root, &key, &item,
sizeof(item));
if (ret)
btrfs_abort_transaction(trans, extent_root, ret);
}
}

int btrfs_make_block_group(struct btrfs_trans_handle *trans,
struct btrfs_root *root, u64 bytes_used,
u64 type, u64 chunk_objectid, u64 chunk_offset,
Expand Down Expand Up @@ -7861,6 +7861,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
spin_lock_init(&cache->lock);
INIT_LIST_HEAD(&cache->list);
INIT_LIST_HEAD(&cache->cluster_list);
INIT_LIST_HEAD(&cache->new_bg_list);

btrfs_init_free_space_ctl(cache);

Expand Down Expand Up @@ -7892,12 +7893,7 @@ int btrfs_make_block_group(struct btrfs_trans_handle *trans,
ret = btrfs_add_block_group_cache(root->fs_info, cache);
BUG_ON(ret); /* Logic error */

ret = btrfs_insert_item(trans, extent_root, &cache->key, &cache->item,
sizeof(cache->item));
if (ret) {
btrfs_abort_transaction(trans, extent_root, ret);
return ret;
}
list_add_tail(&cache->new_bg_list, &trans->new_bgs);

set_avail_alloc_bits(extent_root->fs_info, type);

Expand Down
10 changes: 10 additions & 0 deletions trunk/fs/btrfs/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
h->qgroup_reserved = qgroup_reserved;
h->delayed_ref_elem.seq = 0;
INIT_LIST_HEAD(&h->qgroup_ref_list);
INIT_LIST_HEAD(&h->new_bgs);

smp_mb();
if (cur_trans->blocked && may_wait_transaction(root, type)) {
Expand Down Expand Up @@ -549,6 +550,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
trans->qgroup_reserved = 0;
}

if (!list_empty(&trans->new_bgs))
btrfs_create_pending_block_groups(trans, root);

while (count < 2) {
unsigned long cur = trans->delayed_ref_updates;
trans->delayed_ref_updates = 0;
Expand All @@ -564,6 +568,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
btrfs_trans_release_metadata(trans, root);
trans->block_rsv = NULL;

if (!list_empty(&trans->new_bgs))
btrfs_create_pending_block_groups(trans, root);

if (lock && !atomic_read(&root->fs_info->open_ioctl_trans) &&
should_end_transaction(trans, root)) {
trans->transaction->blocked = 1;
Expand Down Expand Up @@ -1400,6 +1407,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
*/
cur_trans->delayed_refs.flushing = 1;

if (!list_empty(&trans->new_bgs))
btrfs_create_pending_block_groups(trans, root);

ret = btrfs_run_delayed_refs(trans, root, 0);
if (ret)
goto cleanup_transaction;
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/btrfs/transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct btrfs_trans_handle {
struct btrfs_root *root;
struct seq_list delayed_ref_elem;
struct list_head qgroup_ref_list;
struct list_head new_bgs;
};

struct btrfs_pending_snapshot {
Expand Down

0 comments on commit b141493

Please sign in to comment.