aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
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);