提交 06d5a589 编写于 作者: J Josef Bacik

Btrfs: only retry transaction reservation once

I saw a lockup where we kept getting into this start transaction->commit
transaction loop because of enospce.  The fact is if we fail to make our
reservation, we've tried _everything_ several times, so we only need to try and
commit the transaction once, and if that doesn't work then we really are out of
space and need to just exit.  Thanks,
Signed-off-by: NJosef Bacik <josef@redhat.com>
上级 be1a12a0
...@@ -181,6 +181,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, ...@@ -181,6 +181,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
{ {
struct btrfs_trans_handle *h; struct btrfs_trans_handle *h;
struct btrfs_transaction *cur_trans; struct btrfs_transaction *cur_trans;
int retries = 0;
int ret; int ret;
if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
...@@ -224,10 +225,18 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root, ...@@ -224,10 +225,18 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
if (num_items > 0) { if (num_items > 0) {
ret = btrfs_trans_reserve_metadata(h, root, num_items); ret = btrfs_trans_reserve_metadata(h, root, num_items);
if (ret == -EAGAIN) { if (ret == -EAGAIN && !retries) {
retries++;
btrfs_commit_transaction(h, root); btrfs_commit_transaction(h, root);
goto again; goto again;
} else if (ret == -EAGAIN) {
/*
* We have already retried and got EAGAIN, so really we
* don't have space, so set ret to -ENOSPC.
*/
ret = -ENOSPC;
} }
if (ret < 0) { if (ret < 0) {
btrfs_end_transaction(h, root); btrfs_end_transaction(h, root);
return ERR_PTR(ret); return ERR_PTR(ret);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册