Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318837
b: refs/heads/master
c: 96c3f43
h: refs/heads/master
i:
  318835: 8655a8c
v: v3
  • Loading branch information
Josef Bacik authored and Chris Mason committed Jul 23, 2012
1 parent 68b9a2c commit 32b9418
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 39 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: b27f7c0c150f74564b5d4c6c24a03c5226bf6327
refs/heads/master: 96c3f4331a8c1cd0a58307e4ac7e73e09d7dab23
22 changes: 19 additions & 3 deletions trunk/fs/btrfs/delayed-inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1113,15 +1113,16 @@ static int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
* Returns < 0 on error and returns with an aborted transaction with any
* outstanding delayed items cleaned up.
*/
int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int nr)
{
struct btrfs_root *curr_root = root;
struct btrfs_delayed_root *delayed_root;
struct btrfs_delayed_node *curr_node, *prev_node;
struct btrfs_path *path;
struct btrfs_block_rsv *block_rsv;
int ret = 0;
bool count = (nr > 0);

if (trans->aborted)
return -EIO;
Expand All @@ -1137,7 +1138,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
delayed_root = btrfs_get_delayed_root(root);

curr_node = btrfs_first_delayed_node(delayed_root);
while (curr_node) {
while (curr_node && (!count || (count && nr--))) {
curr_root = curr_node->root;
ret = btrfs_insert_delayed_items(trans, path, curr_root,
curr_node);
Expand All @@ -1149,6 +1150,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
path, curr_node);
if (ret) {
btrfs_release_delayed_node(curr_node);
curr_node = NULL;
btrfs_abort_transaction(trans, root, ret);
break;
}
Expand All @@ -1158,12 +1160,26 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
btrfs_release_delayed_node(prev_node);
}

if (curr_node)
btrfs_release_delayed_node(curr_node);
btrfs_free_path(path);
trans->block_rsv = block_rsv;

return ret;
}

int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root)
{
return __btrfs_run_delayed_items(trans, root, -1);
}

int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int nr)
{
return __btrfs_run_delayed_items(trans, root, nr);
}

static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_delayed_node *node)
{
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/btrfs/delayed-inode.h
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode);

int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans,
struct btrfs_root *root, int nr);

void btrfs_balance_delayed_items(struct btrfs_root *root);

Expand Down
97 changes: 62 additions & 35 deletions trunk/fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -3728,6 +3728,60 @@ static int may_commit_transaction(struct btrfs_root *root,
return btrfs_commit_transaction(trans, root);
}

enum flush_state {
FLUSH_DELALLOC = 1,
FLUSH_DELALLOC_WAIT = 2,
FLUSH_DELAYED_ITEMS_NR = 3,
FLUSH_DELAYED_ITEMS = 4,
COMMIT_TRANS = 5,
};

static int flush_space(struct btrfs_root *root,
struct btrfs_space_info *space_info, u64 num_bytes,
u64 orig_bytes, int state)
{
struct btrfs_trans_handle *trans;
int nr;
int ret;

switch (state) {
case FLUSH_DELALLOC:
case FLUSH_DELALLOC_WAIT:
ret = shrink_delalloc(root, num_bytes,
state == FLUSH_DELALLOC_WAIT);
if (ret > 0)
ret = 0;
break;
case FLUSH_DELAYED_ITEMS_NR:
case FLUSH_DELAYED_ITEMS:
if (state == FLUSH_DELAYED_ITEMS_NR) {
u64 bytes = btrfs_calc_trans_metadata_size(root, 1);

nr = (int)div64_u64(num_bytes, bytes);
if (!nr)
nr = 1;
nr *= 2;
} else {
nr = -1;
}
trans = btrfs_join_transaction(root);
if (IS_ERR(trans)) {
ret = PTR_ERR(trans);
break;
}
ret = btrfs_run_delayed_items_nr(trans, root, nr);
btrfs_end_transaction(trans, root);
break;
case COMMIT_TRANS:
ret = may_commit_transaction(root, space_info, orig_bytes, 0);
break;
default:
ret = -ENOSPC;
break;
}

return ret;
}
/**
* reserve_metadata_bytes - try to reserve bytes from the block_rsv's space
* @root - the root we're allocating for
Expand All @@ -3749,11 +3803,10 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
struct btrfs_space_info *space_info = block_rsv->space_info;
u64 used;
u64 num_bytes = orig_bytes;
int retries = 0;
int flush_state = FLUSH_DELALLOC;
int ret = 0;
bool committed = false;
bool flushing = false;
bool wait_ordered = false;
bool committed = false;

again:
ret = 0;
Expand Down Expand Up @@ -3812,9 +3865,8 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
* amount plus the amount of bytes that we need for this
* reservation.
*/
wait_ordered = true;
num_bytes = used - space_info->total_bytes +
(orig_bytes * (retries + 1));
(orig_bytes * 2);
}

if (ret) {
Expand Down Expand Up @@ -3867,8 +3919,6 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
trace_btrfs_space_reservation(root->fs_info,
"space_info", space_info->flags, orig_bytes, 1);
ret = 0;
} else {
wait_ordered = true;
}
}

Expand All @@ -3887,36 +3937,13 @@ static int reserve_metadata_bytes(struct btrfs_root *root,
if (!ret || !flush)
goto out;

/*
* We do synchronous shrinking since we don't actually unreserve
* metadata until after the IO is completed.
*/
ret = shrink_delalloc(root, num_bytes, wait_ordered);
if (ret < 0)
goto out;

ret = 0;

/*
* So if we were overcommitted it's possible that somebody else flushed
* out enough space and we simply didn't have enough space to reclaim,
* so go back around and try again.
*/
if (retries < 2) {
wait_ordered = true;
retries++;
ret = flush_space(root, space_info, num_bytes, orig_bytes,
flush_state);
flush_state++;
if (!ret)
goto again;
}

ret = -ENOSPC;
if (committed)
goto out;

ret = may_commit_transaction(root, space_info, orig_bytes, 0);
if (!ret) {
committed = true;
else if (flush_state <= COMMIT_TRANS)
goto again;
}

out:
if (flushing) {
Expand Down

0 comments on commit 32b9418

Please sign in to comment.