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 c207e8c32c9b..b2acc79f1b34 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 | ||