aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorJosef Bacik <josef@redhat.com>2011-04-05 11:57:27 -0400
committerJosef Bacik <josef@redhat.com>2011-04-08 13:00:32 -0400
commit06d5a5899d6d3ac401d2359b5eac6d2a3a0fe331 (patch)
treeff26c40dec6e649dca7316ce10412cc6c0ace985 /fs/btrfs
parentbe1a12a0dfed06cf1e62e35bf91620dc610a451a (diff)
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: Josef Bacik <josef@redhat.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/transaction.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 5b158da7e0bb..4583008217e6 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -181,6 +181,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
181{ 181{
182 struct btrfs_trans_handle *h; 182 struct btrfs_trans_handle *h;
183 struct btrfs_transaction *cur_trans; 183 struct btrfs_transaction *cur_trans;
184 int retries = 0;
184 int ret; 185 int ret;
185 186
186 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) 187 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
@@ -224,10 +225,18 @@ again:
224 225
225 if (num_items > 0) { 226 if (num_items > 0) {
226 ret = btrfs_trans_reserve_metadata(h, root, num_items); 227 ret = btrfs_trans_reserve_metadata(h, root, num_items);
227 if (ret == -EAGAIN) { 228 if (ret == -EAGAIN && !retries) {
229 retries++;
228 btrfs_commit_transaction(h, root); 230 btrfs_commit_transaction(h, root);
229 goto again; 231 goto again;
232 } else if (ret == -EAGAIN) {
233 /*
234 * We have already retried and got EAGAIN, so really we
235 * don't have space, so set ret to -ENOSPC.
236 */
237 ret = -ENOSPC;
230 } 238 }
239
231 if (ret < 0) { 240 if (ret < 0) {
232 btrfs_end_transaction(h, root); 241 btrfs_end_transaction(h, root);
233 return ERR_PTR(ret); 242 return ERR_PTR(ret);