diff options
Diffstat (limited to 'fs/btrfs/transaction.c')
| -rw-r--r-- | fs/btrfs/transaction.c | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index c207e8c32c9..b2acc79f1b3 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
| @@ -333,6 +333,9 @@ static int __btrfs_end_transaction(struct btrfs_trans_handle *trans, | |||
| 333 | memset(trans, 0, sizeof(*trans)); | 333 | memset(trans, 0, sizeof(*trans)); |
| 334 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 334 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
| 335 | 335 | ||
| 336 | if (throttle) | ||
| 337 | btrfs_run_delayed_iputs(root); | ||
| 338 | |||
| 336 | return 0; | 339 | return 0; |
| 337 | } | 340 | } |
| 338 | 341 | ||
| @@ -354,7 +357,7 @@ int btrfs_end_transaction_throttle(struct btrfs_trans_handle *trans, | |||
| 354 | * those extents are sent to disk but does not wait on them | 357 | * those extents are sent to disk but does not wait on them |
| 355 | */ | 358 | */ |
| 356 | int btrfs_write_marked_extents(struct btrfs_root *root, | 359 | int btrfs_write_marked_extents(struct btrfs_root *root, |
| 357 | struct extent_io_tree *dirty_pages) | 360 | struct extent_io_tree *dirty_pages, int mark) |
| 358 | { | 361 | { |
| 359 | int ret; | 362 | int ret; |
| 360 | int err = 0; | 363 | int err = 0; |
| @@ -367,7 +370,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
| 367 | 370 | ||
| 368 | while (1) { | 371 | while (1) { |
| 369 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, | 372 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, |
| 370 | EXTENT_DIRTY); | 373 | mark); |
| 371 | if (ret) | 374 | if (ret) |
| 372 | break; | 375 | break; |
| 373 | while (start <= end) { | 376 | while (start <= end) { |
| @@ -413,7 +416,7 @@ int btrfs_write_marked_extents(struct btrfs_root *root, | |||
| 413 | * on all the pages and clear them from the dirty pages state tree | 416 | * on all the pages and clear them from the dirty pages state tree |
| 414 | */ | 417 | */ |
| 415 | int btrfs_wait_marked_extents(struct btrfs_root *root, | 418 | int btrfs_wait_marked_extents(struct btrfs_root *root, |
| 416 | struct extent_io_tree *dirty_pages) | 419 | struct extent_io_tree *dirty_pages, int mark) |
| 417 | { | 420 | { |
| 418 | int ret; | 421 | int ret; |
| 419 | int err = 0; | 422 | int err = 0; |
| @@ -425,12 +428,12 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, | |||
| 425 | unsigned long index; | 428 | unsigned long index; |
| 426 | 429 | ||
| 427 | while (1) { | 430 | while (1) { |
| 428 | ret = find_first_extent_bit(dirty_pages, 0, &start, &end, | 431 | ret = find_first_extent_bit(dirty_pages, start, &start, &end, |
| 429 | EXTENT_DIRTY); | 432 | mark); |
| 430 | if (ret) | 433 | if (ret) |
| 431 | break; | 434 | break; |
| 432 | 435 | ||
| 433 | clear_extent_dirty(dirty_pages, start, end, GFP_NOFS); | 436 | clear_extent_bits(dirty_pages, start, end, mark, GFP_NOFS); |
| 434 | while (start <= end) { | 437 | while (start <= end) { |
| 435 | index = start >> PAGE_CACHE_SHIFT; | 438 | index = start >> PAGE_CACHE_SHIFT; |
| 436 | start = (u64)(index + 1) << PAGE_CACHE_SHIFT; | 439 | start = (u64)(index + 1) << PAGE_CACHE_SHIFT; |
| @@ -460,13 +463,13 @@ int btrfs_wait_marked_extents(struct btrfs_root *root, | |||
| 460 | * those extents are on disk for transaction or log commit | 463 | * those extents are on disk for transaction or log commit |
| 461 | */ | 464 | */ |
| 462 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, | 465 | int btrfs_write_and_wait_marked_extents(struct btrfs_root *root, |
| 463 | struct extent_io_tree *dirty_pages) | 466 | struct extent_io_tree *dirty_pages, int mark) |
| 464 | { | 467 | { |
| 465 | int ret; | 468 | int ret; |
| 466 | int ret2; | 469 | int ret2; |
| 467 | 470 | ||
| 468 | ret = btrfs_write_marked_extents(root, dirty_pages); | 471 | ret = btrfs_write_marked_extents(root, dirty_pages, mark); |
| 469 | ret2 = btrfs_wait_marked_extents(root, dirty_pages); | 472 | ret2 = btrfs_wait_marked_extents(root, dirty_pages, mark); |
| 470 | return ret || ret2; | 473 | return ret || ret2; |
| 471 | } | 474 | } |
| 472 | 475 | ||
| @@ -479,7 +482,8 @@ int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, | |||
| 479 | return filemap_write_and_wait(btree_inode->i_mapping); | 482 | return filemap_write_and_wait(btree_inode->i_mapping); |
| 480 | } | 483 | } |
| 481 | return btrfs_write_and_wait_marked_extents(root, | 484 | return btrfs_write_and_wait_marked_extents(root, |
| 482 | &trans->transaction->dirty_pages); | 485 | &trans->transaction->dirty_pages, |
| 486 | EXTENT_DIRTY); | ||
| 483 | } | 487 | } |
| 484 | 488 | ||
| 485 | /* | 489 | /* |
| @@ -497,13 +501,16 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
| 497 | { | 501 | { |
| 498 | int ret; | 502 | int ret; |
| 499 | u64 old_root_bytenr; | 503 | u64 old_root_bytenr; |
| 504 | u64 old_root_used; | ||
| 500 | struct btrfs_root *tree_root = root->fs_info->tree_root; | 505 | struct btrfs_root *tree_root = root->fs_info->tree_root; |
| 501 | 506 | ||
| 507 | old_root_used = btrfs_root_used(&root->root_item); | ||
| 502 | btrfs_write_dirty_block_groups(trans, root); | 508 | btrfs_write_dirty_block_groups(trans, root); |
| 503 | 509 | ||
| 504 | while (1) { | 510 | while (1) { |
| 505 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); | 511 | old_root_bytenr = btrfs_root_bytenr(&root->root_item); |
| 506 | if (old_root_bytenr == root->node->start) | 512 | if (old_root_bytenr == root->node->start && |
| 513 | old_root_used == btrfs_root_used(&root->root_item)) | ||
| 507 | break; | 514 | break; |
| 508 | 515 | ||
| 509 | btrfs_set_root_node(&root->root_item, root->node); | 516 | btrfs_set_root_node(&root->root_item, root->node); |
| @@ -512,6 +519,7 @@ static int update_cowonly_root(struct btrfs_trans_handle *trans, | |||
| 512 | &root->root_item); | 519 | &root->root_item); |
| 513 | BUG_ON(ret); | 520 | BUG_ON(ret); |
| 514 | 521 | ||
| 522 | old_root_used = btrfs_root_used(&root->root_item); | ||
| 515 | ret = btrfs_write_dirty_block_groups(trans, root); | 523 | ret = btrfs_write_dirty_block_groups(trans, root); |
| 516 | BUG_ON(ret); | 524 | BUG_ON(ret); |
| 517 | } | 525 | } |
| @@ -795,7 +803,6 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
| 795 | memcpy(&pending->root_key, &key, sizeof(key)); | 803 | memcpy(&pending->root_key, &key, sizeof(key)); |
| 796 | fail: | 804 | fail: |
| 797 | kfree(new_root_item); | 805 | kfree(new_root_item); |
| 798 | btrfs_unreserve_metadata_space(root, 6); | ||
| 799 | return ret; | 806 | return ret; |
| 800 | } | 807 | } |
| 801 | 808 | ||
| @@ -807,7 +814,6 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, | |||
| 807 | u64 index = 0; | 814 | u64 index = 0; |
| 808 | struct btrfs_trans_handle *trans; | 815 | struct btrfs_trans_handle *trans; |
| 809 | struct inode *parent_inode; | 816 | struct inode *parent_inode; |
| 810 | struct inode *inode; | ||
| 811 | struct btrfs_root *parent_root; | 817 | struct btrfs_root *parent_root; |
| 812 | 818 | ||
| 813 | parent_inode = pending->dentry->d_parent->d_inode; | 819 | parent_inode = pending->dentry->d_parent->d_inode; |
| @@ -839,8 +845,6 @@ static noinline int finish_pending_snapshot(struct btrfs_fs_info *fs_info, | |||
| 839 | 845 | ||
| 840 | BUG_ON(ret); | 846 | BUG_ON(ret); |
| 841 | 847 | ||
| 842 | inode = btrfs_lookup_dentry(parent_inode, pending->dentry); | ||
| 843 | d_instantiate(pending->dentry, inode); | ||
| 844 | fail: | 848 | fail: |
| 845 | btrfs_end_transaction(trans, fs_info->fs_root); | 849 | btrfs_end_transaction(trans, fs_info->fs_root); |
| 846 | return ret; | 850 | return ret; |
| @@ -994,11 +998,11 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 994 | mutex_unlock(&root->fs_info->trans_mutex); | 998 | mutex_unlock(&root->fs_info->trans_mutex); |
| 995 | 999 | ||
| 996 | if (flush_on_commit) { | 1000 | if (flush_on_commit) { |
| 997 | btrfs_start_delalloc_inodes(root); | 1001 | btrfs_start_delalloc_inodes(root, 1); |
| 998 | ret = btrfs_wait_ordered_extents(root, 0); | 1002 | ret = btrfs_wait_ordered_extents(root, 0, 1); |
| 999 | BUG_ON(ret); | 1003 | BUG_ON(ret); |
| 1000 | } else if (snap_pending) { | 1004 | } else if (snap_pending) { |
| 1001 | ret = btrfs_wait_ordered_extents(root, 1); | 1005 | ret = btrfs_wait_ordered_extents(root, 0, 1); |
| 1002 | BUG_ON(ret); | 1006 | BUG_ON(ret); |
| 1003 | } | 1007 | } |
| 1004 | 1008 | ||
| @@ -1116,6 +1120,10 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, | |||
| 1116 | current->journal_info = NULL; | 1120 | current->journal_info = NULL; |
| 1117 | 1121 | ||
| 1118 | kmem_cache_free(btrfs_trans_handle_cachep, trans); | 1122 | kmem_cache_free(btrfs_trans_handle_cachep, trans); |
| 1123 | |||
| 1124 | if (current != root->fs_info->transaction_kthread) | ||
| 1125 | btrfs_run_delayed_iputs(root); | ||
| 1126 | |||
| 1119 | return ret; | 1127 | return ret; |
| 1120 | } | 1128 | } |
| 1121 | 1129 | ||
