aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/transaction.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/transaction.c')
-rw-r--r--fs/btrfs/transaction.c116
1 files changed, 39 insertions, 77 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 51dcec86757..e24b7964a15 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -216,17 +216,11 @@ static void wait_current_trans(struct btrfs_root *root)
216 spin_lock(&root->fs_info->trans_lock); 216 spin_lock(&root->fs_info->trans_lock);
217 cur_trans = root->fs_info->running_transaction; 217 cur_trans = root->fs_info->running_transaction;
218 if (cur_trans && cur_trans->blocked) { 218 if (cur_trans && cur_trans->blocked) {
219 DEFINE_WAIT(wait);
220 atomic_inc(&cur_trans->use_count); 219 atomic_inc(&cur_trans->use_count);
221 spin_unlock(&root->fs_info->trans_lock); 220 spin_unlock(&root->fs_info->trans_lock);
222 while (1) { 221
223 prepare_to_wait(&root->fs_info->transaction_wait, &wait, 222 wait_event(root->fs_info->transaction_wait,
224 TASK_UNINTERRUPTIBLE); 223 !cur_trans->blocked);
225 if (!cur_trans->blocked)
226 break;
227 schedule();
228 }
229 finish_wait(&root->fs_info->transaction_wait, &wait);
230 put_transaction(cur_trans); 224 put_transaction(cur_trans);
231 } else { 225 } else {
232 spin_unlock(&root->fs_info->trans_lock); 226 spin_unlock(&root->fs_info->trans_lock);
@@ -260,7 +254,7 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
260{ 254{
261 struct btrfs_trans_handle *h; 255 struct btrfs_trans_handle *h;
262 struct btrfs_transaction *cur_trans; 256 struct btrfs_transaction *cur_trans;
263 int retries = 0; 257 u64 num_bytes = 0;
264 int ret; 258 int ret;
265 259
266 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) 260 if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR)
@@ -274,6 +268,19 @@ static struct btrfs_trans_handle *start_transaction(struct btrfs_root *root,
274 h->block_rsv = NULL; 268 h->block_rsv = NULL;
275 goto got_it; 269 goto got_it;
276 } 270 }
271
272 /*
273 * Do the reservation before we join the transaction so we can do all
274 * the appropriate flushing if need be.
275 */
276 if (num_items > 0 && root != root->fs_info->chunk_root) {
277 num_bytes = btrfs_calc_trans_metadata_size(root, num_items);
278 ret = btrfs_block_rsv_add(NULL, root,
279 &root->fs_info->trans_block_rsv,
280 num_bytes);
281 if (ret)
282 return ERR_PTR(ret);
283 }
277again: 284again:
278 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS); 285 h = kmem_cache_alloc(btrfs_trans_handle_cachep, GFP_NOFS);
279 if (!h) 286 if (!h)
@@ -310,24 +317,9 @@ again:
310 goto again; 317 goto again;
311 } 318 }
312 319
313 if (num_items > 0) { 320 if (num_bytes) {
314 ret = btrfs_trans_reserve_metadata(h, root, num_items); 321 h->block_rsv = &root->fs_info->trans_block_rsv;
315 if (ret == -EAGAIN && !retries) { 322 h->bytes_reserved = num_bytes;
316 retries++;
317 btrfs_commit_transaction(h, root);
318 goto again;
319 } else if (ret == -EAGAIN) {
320 /*
321 * We have already retried and got EAGAIN, so really we
322 * don't have space, so set ret to -ENOSPC.
323 */
324 ret = -ENOSPC;
325 }
326
327 if (ret < 0) {
328 btrfs_end_transaction(h, root);
329 return ERR_PTR(ret);
330 }
331 } 323 }
332 324
333got_it: 325got_it:
@@ -359,19 +351,10 @@ struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root
359} 351}
360 352
361/* wait for a transaction commit to be fully complete */ 353/* wait for a transaction commit to be fully complete */
362static noinline int wait_for_commit(struct btrfs_root *root, 354static noinline void wait_for_commit(struct btrfs_root *root,
363 struct btrfs_transaction *commit) 355 struct btrfs_transaction *commit)
364{ 356{
365 DEFINE_WAIT(wait); 357 wait_event(commit->commit_wait, commit->commit_done);
366 while (!commit->commit_done) {
367 prepare_to_wait(&commit->commit_wait, &wait,
368 TASK_UNINTERRUPTIBLE);
369 if (commit->commit_done)
370 break;
371 schedule();
372 }
373 finish_wait(&commit->commit_wait, &wait);
374 return 0;
375} 358}
376 359
377int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid) 360int btrfs_wait_for_commit(struct btrfs_root *root, u64 transid)
@@ -499,10 +482,17 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans,
499 } 482 }
500 483
501 if (lock && cur_trans->blocked && !cur_trans->in_commit) { 484 if (lock && cur_trans->blocked && !cur_trans->in_commit) {
502 if (throttle) 485 if (throttle) {
486 /*
487 * We may race with somebody else here so end up having
488 * to call end_transaction on ourselves again, so inc
489 * our use_count.
490 */
491 trans->use_count++;
503 return btrfs_commit_transaction(trans, root); 492 return btrfs_commit_transaction(trans, root);
504 else 493 } else {
505 wake_up_process(info->transaction_kthread); 494 wake_up_process(info->transaction_kthread);
495 }
506 } 496 }
507 497
508 WARN_ON(cur_trans != info->running_transaction); 498 WARN_ON(cur_trans != info->running_transaction);
@@ -894,6 +884,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
894 struct btrfs_root *tree_root = fs_info->tree_root; 884 struct btrfs_root *tree_root = fs_info->tree_root;
895 struct btrfs_root *root = pending->root; 885 struct btrfs_root *root = pending->root;
896 struct btrfs_root *parent_root; 886 struct btrfs_root *parent_root;
887 struct btrfs_block_rsv *rsv;
897 struct inode *parent_inode; 888 struct inode *parent_inode;
898 struct dentry *parent; 889 struct dentry *parent;
899 struct dentry *dentry; 890 struct dentry *dentry;
@@ -905,6 +896,8 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
905 u64 objectid; 896 u64 objectid;
906 u64 root_flags; 897 u64 root_flags;
907 898
899 rsv = trans->block_rsv;
900
908 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); 901 new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS);
909 if (!new_root_item) { 902 if (!new_root_item) {
910 pending->error = -ENOMEM; 903 pending->error = -ENOMEM;
@@ -1012,6 +1005,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans,
1012 btrfs_orphan_post_snapshot(trans, pending); 1005 btrfs_orphan_post_snapshot(trans, pending);
1013fail: 1006fail:
1014 kfree(new_root_item); 1007 kfree(new_root_item);
1008 trans->block_rsv = rsv;
1015 btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); 1009 btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1);
1016 return 0; 1010 return 0;
1017} 1011}
@@ -1080,22 +1074,7 @@ int btrfs_transaction_blocked(struct btrfs_fs_info *info)
1080static void wait_current_trans_commit_start(struct btrfs_root *root, 1074static void wait_current_trans_commit_start(struct btrfs_root *root,
1081 struct btrfs_transaction *trans) 1075 struct btrfs_transaction *trans)
1082{ 1076{
1083 DEFINE_WAIT(wait); 1077 wait_event(root->fs_info->transaction_blocked_wait, trans->in_commit);
1084
1085 if (trans->in_commit)
1086 return;
1087
1088 while (1) {
1089 prepare_to_wait(&root->fs_info->transaction_blocked_wait, &wait,
1090 TASK_UNINTERRUPTIBLE);
1091 if (trans->in_commit) {
1092 finish_wait(&root->fs_info->transaction_blocked_wait,
1093 &wait);
1094 break;
1095 }
1096 schedule();
1097 finish_wait(&root->fs_info->transaction_blocked_wait, &wait);
1098 }
1099} 1078}
1100 1079
1101/* 1080/*
@@ -1105,24 +1084,8 @@ static void wait_current_trans_commit_start(struct btrfs_root *root,
1105static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root, 1084static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root,
1106 struct btrfs_transaction *trans) 1085 struct btrfs_transaction *trans)
1107{ 1086{
1108 DEFINE_WAIT(wait); 1087 wait_event(root->fs_info->transaction_wait,
1109 1088 trans->commit_done || (trans->in_commit && !trans->blocked));
1110 if (trans->commit_done || (trans->in_commit && !trans->blocked))
1111 return;
1112
1113 while (1) {
1114 prepare_to_wait(&root->fs_info->transaction_wait, &wait,
1115 TASK_UNINTERRUPTIBLE);
1116 if (trans->commit_done ||
1117 (trans->in_commit && !trans->blocked)) {
1118 finish_wait(&root->fs_info->transaction_wait,
1119 &wait);
1120 break;
1121 }
1122 schedule();
1123 finish_wait(&root->fs_info->transaction_wait,
1124 &wait);
1125 }
1126} 1089}
1127 1090
1128/* 1091/*
@@ -1229,8 +1192,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
1229 atomic_inc(&cur_trans->use_count); 1192 atomic_inc(&cur_trans->use_count);
1230 btrfs_end_transaction(trans, root); 1193 btrfs_end_transaction(trans, root);
1231 1194
1232 ret = wait_for_commit(root, cur_trans); 1195 wait_for_commit(root, cur_trans);
1233 BUG_ON(ret);
1234 1196
1235 put_transaction(cur_trans); 1197 put_transaction(cur_trans);
1236 1198