diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
| -rw-r--r-- | fs/btrfs/transaction.c | 151 |
1 files changed, 115 insertions, 36 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 4c0067c4f76d..e52da6fb1165 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -40,7 +40,6 @@ void put_transaction(struct btrfs_transaction *transaction) | |||
| 40 | if (atomic_dec_and_test(&transaction->use_count)) { | 40 | if (atomic_dec_and_test(&transaction->use_count)) { |
| 41 | BUG_ON(!list_empty(&transaction->list)); | 41 | BUG_ON(!list_empty(&transaction->list)); |
| 42 | WARN_ON(transaction->delayed_refs.root.rb_node); | 42 | WARN_ON(transaction->delayed_refs.root.rb_node); |
| 43 | memset(transaction, 0, sizeof(*transaction)); | ||
| 44 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 43 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
| 45 | } | 44 | } |
| 46 | } | 45 | } |
| @@ -51,6 +50,14 @@ static noinline void switch_commit_root(struct btrfs_root *root) | |||
| 51 | root->commit_root = btrfs_root_node(root); | 50 | root->commit_root = btrfs_root_node(root); |
| 52 | } | 51 | } |
| 53 | 52 | ||
| 53 | static inline int can_join_transaction(struct btrfs_transaction *trans, | ||
| 54 | int type) | ||
| 55 | { | ||
| 56 | return !(trans->in_commit && | ||
| 57 | type != TRANS_JOIN && | ||
| 58 | type != TRANS_JOIN_NOLOCK); | ||
| 59 | } | ||
| 60 | |||
| 54 | /* | 61 | /* |
| 55 | * either allocate a new transaction or hop into the existing one | 62 | * either allocate a new transaction or hop into the existing one |
| 56 | */ | 63 | */ |
| @@ -62,7 +69,7 @@ static noinline int join_transaction(struct btrfs_root *root, int type) | |||
| 62 | spin_lock(&fs_info->trans_lock); | 69 | spin_lock(&fs_info->trans_lock); |
| 63 | loop: | 70 | loop: |
| 64 | /* The file system has been taken offline. No new transactions. */ | 71 | /* The file system has been taken offline. No new transactions. */ |
| 65 | if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 72 | if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
| 66 | spin_unlock(&fs_info->trans_lock); | 73 | spin_unlock(&fs_info->trans_lock); |
| 67 | return -EROFS; | 74 | return -EROFS; |
| 68 | } | 75 | } |
| @@ -86,6 +93,10 @@ loop: | |||
| 86 | spin_unlock(&fs_info->trans_lock); | 93 | spin_unlock(&fs_info->trans_lock); |
| 87 | return cur_trans->aborted; | 94 | return cur_trans->aborted; |
| 88 | } | 95 | } |
| 96 | if (!can_join_transaction(cur_trans, type)) { | ||
| 97 | spin_unlock(&fs_info->trans_lock); | ||
| 98 | return -EBUSY; | ||
| 99 | } | ||
| 89 | atomic_inc(&cur_trans->use_count); | 100 | atomic_inc(&cur_trans->use_count); |
| 90 | atomic_inc(&cur_trans->num_writers); | 101 | atomic_inc(&cur_trans->num_writers); |
| 91 | cur_trans->num_joined++; | 102 | cur_trans->num_joined++; |
| @@ -113,7 +124,7 @@ loop: | |||
| 113 | */ | 124 | */ |
| 114 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); | 125 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); |
| 115 | goto loop; | 126 | goto loop; |
| 116 | } else if (fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 127 | } else if (test_bit(BTRFS_FS_STATE_ERROR, &fs_info->fs_state)) { |
| 117 | spin_unlock(&fs_info->trans_lock); | 128 | spin_unlock(&fs_info->trans_lock); |
| 118 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); | 129 | kmem_cache_free(btrfs_transaction_cachep, cur_trans); |
| 119 | return -EROFS; | 130 | return -EROFS; |
| @@ -155,8 +166,12 @@ loop: | |||
| 155 | 166 | ||
| 156 | spin_lock_init(&cur_trans->commit_lock); | 167 | spin_lock_init(&cur_trans->commit_lock); |
| 157 | spin_lock_init(&cur_trans->delayed_refs.lock); | 168 | spin_lock_init(&cur_trans->delayed_refs.lock); |
| 169 | atomic_set(&cur_trans->delayed_refs.procs_running_refs, 0); | ||
| 170 | atomic_set(&cur_trans->delayed_refs.ref_seq, 0); | ||
| 171 | init_waitqueue_head(&cur_trans->delayed_refs.wait); | ||
| 158 | 172 | ||
| 159 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 173 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
| 174 | INIT_LIST_HEAD(&cur_trans->ordered_operations); | ||
| 160 | list_add_tail(&cur_trans->list, &fs_info->trans_list); | 175 | list_add_tail(&cur_trans->list, &fs_info->trans_list); |
| 161 | extent_io_tree_init(&cur_trans->dirty_pages, | 176 | extent_io_tree_init(&cur_trans->dirty_pages, |
| 162 | fs_info->btree_inode->i_mapping); | 177 | fs_info->btree_inode->i_mapping); |
| @@ -301,7 +316,7 @@ start_transaction(struct btrfs_root *root, u64 num_items, int type, | |||
| 301 | int ret; | 316 | int ret; |
| 302 | u64 qgroup_reserved = 0; | 317 | u64 qgroup_reserved = 0; |
| 303 | 318 | ||
| 304 | if (root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) | 319 | if (test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) |
| 305 | return ERR_PTR(-EROFS); | 320 | return ERR_PTR(-EROFS); |
| 306 | 321 | ||
| 307 | if (current->journal_info) { | 322 | if (current->journal_info) { |
| @@ -359,8 +374,11 @@ again: | |||
| 359 | 374 | ||
| 360 | do { | 375 | do { |
| 361 | ret = join_transaction(root, type); | 376 | ret = join_transaction(root, type); |
| 362 | if (ret == -EBUSY) | 377 | if (ret == -EBUSY) { |
| 363 | wait_current_trans(root); | 378 | wait_current_trans(root); |
| 379 | if (unlikely(type == TRANS_ATTACH)) | ||
| 380 | ret = -ENOENT; | ||
| 381 | } | ||
| 364 | } while (ret == -EBUSY); | 382 | } while (ret == -EBUSY); |
| 365 | 383 | ||
| 366 | if (ret < 0) { | 384 | if (ret < 0) { |
| @@ -382,9 +400,10 @@ again: | |||
| 382 | h->block_rsv = NULL; | 400 | h->block_rsv = NULL; |
| 383 | h->orig_rsv = NULL; | 401 | h->orig_rsv = NULL; |
| 384 | h->aborted = 0; | 402 | h->aborted = 0; |
| 385 | h->qgroup_reserved = qgroup_reserved; | 403 | h->qgroup_reserved = 0; |
| 386 | h->delayed_ref_elem.seq = 0; | 404 | h->delayed_ref_elem.seq = 0; |
| 387 | h->type = type; | 405 | h->type = type; |
| 406 | h->allocating_chunk = false; | ||
| 388 | INIT_LIST_HEAD(&h->qgroup_ref_list); | 407 | INIT_LIST_HEAD(&h->qgroup_ref_list); |
| 389 | INIT_LIST_HEAD(&h->new_bgs); | 408 | INIT_LIST_HEAD(&h->new_bgs); |
| 390 | 409 | ||
| @@ -400,6 +419,7 @@ again: | |||
| 400 | h->block_rsv = &root->fs_info->trans_block_rsv; | 419 | h->block_rsv = &root->fs_info->trans_block_rsv; |
| 401 | h->bytes_reserved = num_bytes; | 420 | h->bytes_reserved = num_bytes; |
| 402 | } | 421 | } |
| 422 | h->qgroup_reserved = qgroup_reserved; | ||
| 403 | 423 | ||
| 404 | got_it: | 424 | got_it: |
| 405 | btrfs_record_root_in_trans(h, root); | 425 | btrfs_record_root_in_trans(h, root); |
| @@ -451,11 +471,43 @@ struct btrfs_trans_handle *btrfs_start_ioctl_transaction(struct btrfs_root *root | |||
| 451 | return start_transaction(root, 0, TRANS_USERSPACE, 0); | 471 | return start_transaction(root, 0, TRANS_USERSPACE, 0); |
| 452 | } | 472 | } |
| 453 | 473 | ||
| 474 | /* | ||
| 475 | * btrfs_attach_transaction() - catch the running transaction | ||
| 476 | * | ||
| 477 | * It is used when we want to commit the current the transaction, but | ||
| 478 | * don't want to start a new one. | ||
| 479 | * | ||
| 480 | * Note: If this function return -ENOENT, it just means there is no | ||
| 481 | * running transaction. But it is possible that the inactive transaction | ||
| 482 | * is still in the memory, not fully on disk. If you hope there is no | ||
| 483 | * inactive transaction in the fs when -ENOENT is returned, you should | ||
| 484 | * invoke | ||
| 485 | * btrfs_attach_transaction_barrier() | ||
| 486 | */ | ||
| 454 | struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root) | 487 | struct btrfs_trans_handle *btrfs_attach_transaction(struct btrfs_root *root) |
| 455 | { | 488 | { |
| 456 | return start_transaction(root, 0, TRANS_ATTACH, 0); | 489 | return start_transaction(root, 0, TRANS_ATTACH, 0); |
| 457 | } | 490 | } |
| 458 | 491 | ||
| 492 | /* | ||
| 493 | * btrfs_attach_transaction() - catch the running transaction | ||
| 494 | * | ||
| 495 | * It is similar to the above function, the differentia is this one | ||
| 496 | * will wait for all the inactive transactions until they fully | ||
| 497 | * complete. | ||
| 498 | */ | ||
| 499 | struct btrfs_trans_handle * | ||
| 500 | btrfs_attach_transaction_barrier(struct btrfs_root *root) | ||
| 501 | { | ||
| 502 | struct btrfs_trans_handle *trans; | ||
| 503 | |||
| 504 | trans = start_transaction(root, 0, TRANS_ATTACH, 0); | ||
| 505 | if (IS_ERR(trans) && PTR_ERR(trans) == -ENOENT) | ||
| 506 | btrfs_wait_for_commit(root, 0); | ||
| 507 | |||
| 508 | return trans; | ||
| 509 | } | ||
| 510 | |||
| 459 | /* wait for a transaction commit to be fully complete */ | 511 | /* wait for a transaction commit to be fully complete */ |
| 460 | static noinline void wait_for_commit(struct btrfs_root *root, | 512 | static noinline void wait_for_commit(struct btrfs_root *root, |
| 461 | struct btrfs_transaction *commit) | 513 | struct btrfs_transaction *commit) |
| @@ -587,7 +639,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 587 | if (!list_empty(&trans->new_bgs)) | 639 | if (!list_empty(&trans->new_bgs)) |
| 588 | btrfs_create_pending_block_groups(trans, root); | 640 | btrfs_create_pending_block_groups(trans, root); |
| 589 | 641 | ||
| 590 | while (count < 2) { | 642 | while (count < 1) { |
| 591 | unsigned long cur = trans->delayed_ref_updates; | 643 | unsigned long cur = trans->delayed_ref_updates; |
| 592 | trans->delayed_ref_updates = 0; | 644 | trans->delayed_ref_updates = 0; |
| 593 | if (cur && | 645 | if (cur && |
| @@ -599,6 +651,7 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 599 | } | 651 | } |
| 600 | count++; | 652 | count++; |
| 601 | } | 653 | } |
| 654 | |||
| 602 | btrfs_trans_release_metadata(trans, root); | 655 | btrfs_trans_release_metadata(trans, root); |
| 603 | trans->block_rsv = NULL; | 656 | trans->block_rsv = NULL; |
| 604 | 657 | ||
| @@ -644,12 +697,10 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 644 | btrfs_run_delayed_iputs(root); | 697 | btrfs_run_delayed_iputs(root); |
| 645 | 698 | ||
| 646 | if (trans->aborted || | 699 | if (trans->aborted || |
| 647 | root->fs_info->fs_state & BTRFS_SUPER_FLAG_ERROR) { | 700 | test_bit(BTRFS_FS_STATE_ERROR, &root->fs_info->fs_state)) |
| 648 | err = -EIO; | 701 | err = -EIO; |
| 649 | } | ||
| 650 | assert_qgroups_uptodate(trans); | 702 | assert_qgroups_uptodate(trans); |
| 651 | 703 | ||
| 652 | memset(trans, 0, sizeof(*trans)); | ||
| 653 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 704 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
| 654 | return err; | 705 | return err; |
| 655 | } | 706 | } |
| @@ -696,7 +747,9 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
| 696 | struct extent_state *cached_state = NULL; | 747 | struct extent_state *cached_state = NULL; |
| 697 | u64 start = 0; | 748 | u64 start = 0; |
| 698 | u64 end; | 749 | u64 end; |
| 750 | struct blk_plug plug; | ||
| 699 | 751 | ||
| 752 | blk_start_plug(&plug); | ||
| 700 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, | 753 | while (!find_first_extent_bit(dirty_pages, start, &start, &end, |
| 701 | mark, &cached_state)) { | 754 | mark, &cached_state)) { |
| 702 | convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, | 755 | convert_extent_bit(dirty_pages, start, end, EXTENT_NEED_WAIT, |
| @@ -710,6 +763,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
| 710 | } | 763 | } |
| 711 | if (err) | 764 | if (err) |
| 712 | werr = err; | 765 | werr = err; |
| 766 | blk_finish_plug(&plug); | ||
| 713 | return werr; | 767 | return werr; |
| 714 | } | 768 | } |
| 715 | 769 | ||
| @@ -960,10 +1014,10 @@ static noinline int commit_fs_roots(struct btrfs_trans_handle *trans, | |||
| 960 | } | 1014 | } |
| 961 | 1015 | ||
| 962 | /* | 1016 | /* |
| 963 | * defrag a given btree. If cacheonly == 1, this won't read from the disk, | 1017 | * defrag a given btree. |
| 964 | * otherwise every leaf in the btree is read and defragged. | 1018 | * Every leaf in the btree is read and defragged. |
| 965 | */ | 1019 | */ |
| 966 | int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | 1020 | int btrfs_defrag_root(struct btrfs_root *root) |
| 967 | { | 1021 | { |
| 968 | struct btrfs_fs_info *info = root->fs_info; | 1022 | struct btrfs_fs_info *info = root->fs_info; |
| 969 | struct btrfs_trans_handle *trans; | 1023 | struct btrfs_trans_handle *trans; |
| @@ -977,7 +1031,7 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
| 977 | if (IS_ERR(trans)) | 1031 | if (IS_ERR(trans)) |
| 978 | return PTR_ERR(trans); | 1032 | return PTR_ERR(trans); |
| 979 | 1033 | ||
| 980 | ret = btrfs_defrag_leaves(trans, root, cacheonly); | 1034 | ret = btrfs_defrag_leaves(trans, root); |
| 981 | 1035 | ||
| 982 | btrfs_end_transaction(trans, root); | 1036 | btrfs_end_transaction(trans, root); |
| 983 | btrfs_btree_balance_dirty(info->tree_root); | 1037 | btrfs_btree_balance_dirty(info->tree_root); |
| @@ -985,6 +1039,12 @@ int btrfs_defrag_root(struct btrfs_root *root, int cacheonly) | |||
| 985 | 1039 | ||
| 986 | if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN) | 1040 | if (btrfs_fs_closing(root->fs_info) || ret != -EAGAIN) |
| 987 | break; | 1041 | break; |
| 1042 | |||
| 1043 | if (btrfs_defrag_cancelled(root->fs_info)) { | ||
| 1044 | printk(KERN_DEBUG "btrfs: defrag_root cancelled\n"); | ||
| 1045 | ret = -EAGAIN; | ||
| 1046 | break; | ||
| 1047 | } | ||
| 988 | } | 1048 | } |
| 989 | root->defrag_running = 0; | 1049 | root->defrag_running = 0; |
| 990 | return ret; | 1050 | return ret; |
| @@ -1007,7 +1067,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1007 | struct inode *parent_inode; | 1067 | struct inode *parent_inode; |
| 1008 | struct btrfs_path *path; | 1068 | struct btrfs_path *path; |
| 1009 | struct btrfs_dir_item *dir_item; | 1069 | struct btrfs_dir_item *dir_item; |
| 1010 | struct dentry *parent; | ||
| 1011 | struct dentry *dentry; | 1070 | struct dentry *dentry; |
| 1012 | struct extent_buffer *tmp; | 1071 | struct extent_buffer *tmp; |
| 1013 | struct extent_buffer *old; | 1072 | struct extent_buffer *old; |
| @@ -1022,7 +1081,7 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1022 | path = btrfs_alloc_path(); | 1081 | path = btrfs_alloc_path(); |
| 1023 | if (!path) { | 1082 | if (!path) { |
| 1024 | ret = pending->error = -ENOMEM; | 1083 | ret = pending->error = -ENOMEM; |
| 1025 | goto path_alloc_fail; | 1084 | return ret; |
| 1026 | } | 1085 | } |
| 1027 | 1086 | ||
| 1028 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); | 1087 | new_root_item = kmalloc(sizeof(*new_root_item), GFP_NOFS); |
| @@ -1062,10 +1121,10 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1062 | 1121 | ||
| 1063 | rsv = trans->block_rsv; | 1122 | rsv = trans->block_rsv; |
| 1064 | trans->block_rsv = &pending->block_rsv; | 1123 | trans->block_rsv = &pending->block_rsv; |
| 1124 | trans->bytes_reserved = trans->block_rsv->reserved; | ||
| 1065 | 1125 | ||
| 1066 | dentry = pending->dentry; | 1126 | dentry = pending->dentry; |
| 1067 | parent = dget_parent(dentry); | 1127 | parent_inode = pending->dir; |
| 1068 | parent_inode = parent->d_inode; | ||
| 1069 | parent_root = BTRFS_I(parent_inode)->root; | 1128 | parent_root = BTRFS_I(parent_inode)->root; |
| 1070 | record_root_in_trans(trans, parent_root); | 1129 | record_root_in_trans(trans, parent_root); |
| 1071 | 1130 | ||
| @@ -1213,14 +1272,12 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 1213 | if (ret) | 1272 | if (ret) |
| 1214 | btrfs_abort_transaction(trans, root, ret); | 1273 | btrfs_abort_transaction(trans, root, ret); |
| 1215 | fail: | 1274 | fail: |
| 1216 | dput(parent); | ||
| 1217 | trans->block_rsv = rsv; | 1275 | trans->block_rsv = rsv; |
| 1276 | trans->bytes_reserved = 0; | ||
| 1218 | no_free_objectid: | 1277 | no_free_objectid: |
| 1219 | kfree(new_root_item); | 1278 | kfree(new_root_item); |
| 1220 | root_item_alloc_fail: | 1279 | root_item_alloc_fail: |
| 1221 | btrfs_free_path(path); | 1280 | btrfs_free_path(path); |
| 1222 | path_alloc_fail: | ||
| 1223 | btrfs_block_rsv_release(root, &pending->block_rsv, (u64)-1); | ||
| 1224 | return ret; | 1281 | return ret; |
| 1225 | } | 1282 | } |
| 1226 | 1283 | ||
| @@ -1306,13 +1363,13 @@ static void wait_current_trans_commit_start_and_unblock(struct btrfs_root *root, | |||
| 1306 | struct btrfs_async_commit { | 1363 | struct btrfs_async_commit { |
| 1307 | struct btrfs_trans_handle *newtrans; | 1364 | struct btrfs_trans_handle *newtrans; |
| 1308 | struct btrfs_root *root; | 1365 | struct btrfs_root *root; |
| 1309 | struct delayed_work work; | 1366 | struct work_struct work; |
| 1310 | }; | 1367 | }; |
| 1311 | 1368 | ||
| 1312 | static void do_async_commit(struct work_struct *work) | 1369 | static void do_async_commit(struct work_struct *work) |
| 1313 | { | 1370 | { |
| 1314 | struct btrfs_async_commit *ac = | 1371 | struct btrfs_async_commit *ac = |
| 1315 | container_of(work, struct btrfs_async_commit, work.work); | 1372 | container_of(work, struct btrfs_async_commit, work); |
| 1316 | 1373 | ||
| 1317 | /* | 1374 | /* |
| 1318 | * We've got freeze protection passed with the transaction. | 1375 | * We've got freeze protection passed with the transaction. |
| @@ -1340,7 +1397,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
| 1340 | if (!ac) | 1397 | if (!ac) |
| 1341 | return -ENOMEM; | 1398 | return -ENOMEM; |
| 1342 | 1399 | ||
| 1343 | INIT_DELAYED_WORK(&ac->work, do_async_commit); | 1400 | INIT_WORK(&ac->work, do_async_commit); |
| 1344 | ac->root = root; | 1401 | ac->root = root; |
| 1345 | ac->newtrans = btrfs_join_transaction(root); | 1402 | ac->newtrans = btrfs_join_transaction(root); |
| 1346 | if (IS_ERR(ac->newtrans)) { | 1403 | if (IS_ERR(ac->newtrans)) { |
| @@ -1364,7 +1421,7 @@ int btrfs_commit_transaction_async(struct btrfs_trans_handle *trans, | |||
| 1364 | &root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], | 1421 | &root->fs_info->sb->s_writers.lock_map[SB_FREEZE_FS-1], |
| 1365 | 1, _THIS_IP_); | 1422 | 1, _THIS_IP_); |
| 1366 | 1423 | ||
| 1367 | schedule_delayed_work(&ac->work, 0); | 1424 | schedule_work(&ac->work); |
| 1368 | 1425 | ||
| 1369 | /* wait for transaction to start and unblock */ | 1426 | /* wait for transaction to start and unblock */ |
| 1370 | if (wait_for_unblock) | 1427 | if (wait_for_unblock) |
| @@ -1384,6 +1441,7 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
| 1384 | struct btrfs_root *root, int err) | 1441 | struct btrfs_root *root, int err) |
| 1385 | { | 1442 | { |
| 1386 | struct btrfs_transaction *cur_trans = trans->transaction; | 1443 | struct btrfs_transaction *cur_trans = trans->transaction; |
| 1444 | DEFINE_WAIT(wait); | ||
| 1387 | 1445 | ||
| 1388 | WARN_ON(trans->use_count > 1); | 1446 | WARN_ON(trans->use_count > 1); |
| 1389 | 1447 | ||
| @@ -1392,8 +1450,13 @@ static void cleanup_transaction(struct btrfs_trans_handle *trans, | |||
| 1392 | spin_lock(&root->fs_info->trans_lock); | 1450 | spin_lock(&root->fs_info->trans_lock); |
| 1393 | list_del_init(&cur_trans->list); | 1451 | list_del_init(&cur_trans->list); |
| 1394 | if (cur_trans == root->fs_info->running_transaction) { | 1452 | if (cur_trans == root->fs_info->running_transaction) { |
| 1453 | root->fs_info->trans_no_join = 1; | ||
| 1454 | spin_unlock(&root->fs_info->trans_lock); | ||
| 1455 | wait_event(cur_trans->writer_wait, | ||
| 1456 | atomic_read(&cur_trans->num_writers) == 1); | ||
| 1457 | |||
| 1458 | spin_lock(&root->fs_info->trans_lock); | ||
| 1395 | root->fs_info->running_transaction = NULL; | 1459 | root->fs_info->running_transaction = NULL; |
| 1396 | root->fs_info->trans_no_join = 0; | ||
| 1397 | } | 1460 | } |
| 1398 | spin_unlock(&root->fs_info->trans_lock); | 1461 | spin_unlock(&root->fs_info->trans_lock); |
| 1399 | 1462 | ||
| @@ -1427,7 +1490,9 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
| 1427 | } | 1490 | } |
| 1428 | 1491 | ||
| 1429 | if (flush_on_commit || snap_pending) { | 1492 | if (flush_on_commit || snap_pending) { |
| 1430 | btrfs_start_delalloc_inodes(root, 1); | 1493 | ret = btrfs_start_delalloc_inodes(root, 1); |
| 1494 | if (ret) | ||
| 1495 | return ret; | ||
| 1431 | btrfs_wait_ordered_extents(root, 1); | 1496 | btrfs_wait_ordered_extents(root, 1); |
| 1432 | } | 1497 | } |
| 1433 | 1498 | ||
| @@ -1449,9 +1514,9 @@ static int btrfs_flush_all_pending_stuffs(struct btrfs_trans_handle *trans, | |||
| 1449 | * it here and no for sure that nothing new will be added | 1514 | * it here and no for sure that nothing new will be added |
| 1450 | * to the list | 1515 | * to the list |
| 1451 | */ | 1516 | */ |
| 1452 | btrfs_run_ordered_operations(root, 1); | 1517 | ret = btrfs_run_ordered_operations(trans, root, 1); |
| 1453 | 1518 | ||
| 1454 | return 0; | 1519 | return ret; |
| 1455 | } | 1520 | } |
| 1456 | 1521 | ||
| 1457 | /* | 1522 | /* |
| @@ -1472,27 +1537,35 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1472 | int should_grow = 0; | 1537 | int should_grow = 0; |
| 1473 | unsigned long now = get_seconds(); | 1538 | unsigned long now = get_seconds(); |
| 1474 | 1539 | ||
| 1475 | ret = btrfs_run_ordered_operations(root, 0); | 1540 | ret = btrfs_run_ordered_operations(trans, root, 0); |
| 1476 | if (ret) { | 1541 | if (ret) { |
| 1477 | btrfs_abort_transaction(trans, root, ret); | 1542 | btrfs_abort_transaction(trans, root, ret); |
| 1478 | goto cleanup_transaction; | 1543 | btrfs_end_transaction(trans, root); |
| 1544 | return ret; | ||
| 1479 | } | 1545 | } |
| 1480 | 1546 | ||
| 1481 | /* Stop the commit early if ->aborted is set */ | 1547 | /* Stop the commit early if ->aborted is set */ |
| 1482 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { | 1548 | if (unlikely(ACCESS_ONCE(cur_trans->aborted))) { |
| 1483 | ret = cur_trans->aborted; | 1549 | ret = cur_trans->aborted; |
| 1484 | goto cleanup_transaction; | 1550 | btrfs_end_transaction(trans, root); |
| 1551 | return ret; | ||
| 1485 | } | 1552 | } |
| 1486 | 1553 | ||
| 1487 | /* make a pass through all the delayed refs we have so far | 1554 | /* make a pass through all the delayed refs we have so far |
| 1488 | * any runnings procs may add more while we are here | 1555 | * any runnings procs may add more while we are here |
| 1489 | */ | 1556 | */ |
| 1490 | ret = btrfs_run_delayed_refs(trans, root, 0); | 1557 | ret = btrfs_run_delayed_refs(trans, root, 0); |
| 1491 | if (ret) | 1558 | if (ret) { |
| 1492 | goto cleanup_transaction; | 1559 | btrfs_end_transaction(trans, root); |
| 1560 | return ret; | ||
| 1561 | } | ||
| 1493 | 1562 | ||
| 1494 | btrfs_trans_release_metadata(trans, root); | 1563 | btrfs_trans_release_metadata(trans, root); |
| 1495 | trans->block_rsv = NULL; | 1564 | trans->block_rsv = NULL; |
| 1565 | if (trans->qgroup_reserved) { | ||
| 1566 | btrfs_qgroup_free(root, trans->qgroup_reserved); | ||
| 1567 | trans->qgroup_reserved = 0; | ||
| 1568 | } | ||
| 1496 | 1569 | ||
| 1497 | cur_trans = trans->transaction; | 1570 | cur_trans = trans->transaction; |
| 1498 | 1571 | ||
| @@ -1506,8 +1579,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1506 | btrfs_create_pending_block_groups(trans, root); | 1579 | btrfs_create_pending_block_groups(trans, root); |
| 1507 | 1580 | ||
| 1508 | ret = btrfs_run_delayed_refs(trans, root, 0); | 1581 | ret = btrfs_run_delayed_refs(trans, root, 0); |
| 1509 | if (ret) | 1582 | if (ret) { |
| 1510 | goto cleanup_transaction; | 1583 | btrfs_end_transaction(trans, root); |
| 1584 | return ret; | ||
| 1585 | } | ||
| 1511 | 1586 | ||
| 1512 | spin_lock(&cur_trans->commit_lock); | 1587 | spin_lock(&cur_trans->commit_lock); |
| 1513 | if (cur_trans->in_commit) { | 1588 | if (cur_trans->in_commit) { |
| @@ -1771,6 +1846,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1771 | cleanup_transaction: | 1846 | cleanup_transaction: |
| 1772 | btrfs_trans_release_metadata(trans, root); | 1847 | btrfs_trans_release_metadata(trans, root); |
| 1773 | trans->block_rsv = NULL; | 1848 | trans->block_rsv = NULL; |
| 1849 | if (trans->qgroup_reserved) { | ||
| 1850 | btrfs_qgroup_free(root, trans->qgroup_reserved); | ||
| 1851 | trans->qgroup_reserved = 0; | ||
| 1852 | } | ||
| 1774 | btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n"); | 1853 | btrfs_printk(root->fs_info, "Skipping commit of aborted transaction.\n"); |
| 1775 | // WARN_ON(1); | 1854 | // WARN_ON(1); |
| 1776 | if (current->journal_info == trans) | 1855 | if (current->journal_info == trans) |
