diff options
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r-- | fs/btrfs/tree-log.c | 41 |
1 files changed, 15 insertions, 26 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 39d83da03e03..7c449c699bed 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -3479,7 +3479,8 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b) | |||
3479 | 3479 | ||
3480 | static int log_one_extent(struct btrfs_trans_handle *trans, | 3480 | static int log_one_extent(struct btrfs_trans_handle *trans, |
3481 | struct inode *inode, struct btrfs_root *root, | 3481 | struct inode *inode, struct btrfs_root *root, |
3482 | struct extent_map *em, struct btrfs_path *path) | 3482 | struct extent_map *em, struct btrfs_path *path, |
3483 | struct list_head *logged_list) | ||
3483 | { | 3484 | { |
3484 | struct btrfs_root *log = root->log_root; | 3485 | struct btrfs_root *log = root->log_root; |
3485 | struct btrfs_file_extent_item *fi; | 3486 | struct btrfs_file_extent_item *fi; |
@@ -3495,7 +3496,6 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
3495 | u64 extent_offset = em->start - em->orig_start; | 3496 | u64 extent_offset = em->start - em->orig_start; |
3496 | u64 block_len; | 3497 | u64 block_len; |
3497 | int ret; | 3498 | int ret; |
3498 | int index = log->log_transid % 2; | ||
3499 | bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; | 3499 | bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; |
3500 | int extent_inserted = 0; | 3500 | int extent_inserted = 0; |
3501 | 3501 | ||
@@ -3579,17 +3579,12 @@ static int log_one_extent(struct btrfs_trans_handle *trans, | |||
3579 | * First check and see if our csums are on our outstanding ordered | 3579 | * First check and see if our csums are on our outstanding ordered |
3580 | * extents. | 3580 | * extents. |
3581 | */ | 3581 | */ |
3582 | again: | 3582 | list_for_each_entry(ordered, logged_list, log_list) { |
3583 | spin_lock_irq(&log->log_extents_lock[index]); | ||
3584 | list_for_each_entry(ordered, &log->logged_list[index], log_list) { | ||
3585 | struct btrfs_ordered_sum *sum; | 3583 | struct btrfs_ordered_sum *sum; |
3586 | 3584 | ||
3587 | if (!mod_len) | 3585 | if (!mod_len) |
3588 | break; | 3586 | break; |
3589 | 3587 | ||
3590 | if (ordered->inode != inode) | ||
3591 | continue; | ||
3592 | |||
3593 | if (ordered->file_offset + ordered->len <= mod_start || | 3588 | if (ordered->file_offset + ordered->len <= mod_start || |
3594 | mod_start + mod_len <= ordered->file_offset) | 3589 | mod_start + mod_len <= ordered->file_offset) |
3595 | continue; | 3590 | continue; |
@@ -3632,12 +3627,6 @@ again: | |||
3632 | if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM, | 3627 | if (test_and_set_bit(BTRFS_ORDERED_LOGGED_CSUM, |
3633 | &ordered->flags)) | 3628 | &ordered->flags)) |
3634 | continue; | 3629 | continue; |
3635 | atomic_inc(&ordered->refs); | ||
3636 | spin_unlock_irq(&log->log_extents_lock[index]); | ||
3637 | /* | ||
3638 | * we've dropped the lock, we must either break or | ||
3639 | * start over after this. | ||
3640 | */ | ||
3641 | 3630 | ||
3642 | if (ordered->csum_bytes_left) { | 3631 | if (ordered->csum_bytes_left) { |
3643 | btrfs_start_ordered_extent(inode, ordered, 0); | 3632 | btrfs_start_ordered_extent(inode, ordered, 0); |
@@ -3647,16 +3636,11 @@ again: | |||
3647 | 3636 | ||
3648 | list_for_each_entry(sum, &ordered->list, list) { | 3637 | list_for_each_entry(sum, &ordered->list, list) { |
3649 | ret = btrfs_csum_file_blocks(trans, log, sum); | 3638 | ret = btrfs_csum_file_blocks(trans, log, sum); |
3650 | if (ret) { | 3639 | if (ret) |
3651 | btrfs_put_ordered_extent(ordered); | ||
3652 | goto unlocked; | 3640 | goto unlocked; |
3653 | } | ||
3654 | } | 3641 | } |
3655 | btrfs_put_ordered_extent(ordered); | ||
3656 | goto again; | ||
3657 | 3642 | ||
3658 | } | 3643 | } |
3659 | spin_unlock_irq(&log->log_extents_lock[index]); | ||
3660 | unlocked: | 3644 | unlocked: |
3661 | 3645 | ||
3662 | if (!mod_len || ret) | 3646 | if (!mod_len || ret) |
@@ -3694,7 +3678,8 @@ unlocked: | |||
3694 | static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | 3678 | static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, |
3695 | struct btrfs_root *root, | 3679 | struct btrfs_root *root, |
3696 | struct inode *inode, | 3680 | struct inode *inode, |
3697 | struct btrfs_path *path) | 3681 | struct btrfs_path *path, |
3682 | struct list_head *logged_list) | ||
3698 | { | 3683 | { |
3699 | struct extent_map *em, *n; | 3684 | struct extent_map *em, *n; |
3700 | struct list_head extents; | 3685 | struct list_head extents; |
@@ -3752,7 +3737,7 @@ process: | |||
3752 | 3737 | ||
3753 | write_unlock(&tree->lock); | 3738 | write_unlock(&tree->lock); |
3754 | 3739 | ||
3755 | ret = log_one_extent(trans, inode, root, em, path); | 3740 | ret = log_one_extent(trans, inode, root, em, path, logged_list); |
3756 | write_lock(&tree->lock); | 3741 | write_lock(&tree->lock); |
3757 | clear_em_logging(tree, em); | 3742 | clear_em_logging(tree, em); |
3758 | free_extent_map(em); | 3743 | free_extent_map(em); |
@@ -3788,6 +3773,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
3788 | struct btrfs_key max_key; | 3773 | struct btrfs_key max_key; |
3789 | struct btrfs_root *log = root->log_root; | 3774 | struct btrfs_root *log = root->log_root; |
3790 | struct extent_buffer *src = NULL; | 3775 | struct extent_buffer *src = NULL; |
3776 | LIST_HEAD(logged_list); | ||
3791 | u64 last_extent = 0; | 3777 | u64 last_extent = 0; |
3792 | int err = 0; | 3778 | int err = 0; |
3793 | int ret; | 3779 | int ret; |
@@ -3836,7 +3822,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans, | |||
3836 | 3822 | ||
3837 | mutex_lock(&BTRFS_I(inode)->log_mutex); | 3823 | mutex_lock(&BTRFS_I(inode)->log_mutex); |
3838 | 3824 | ||
3839 | btrfs_get_logged_extents(log, inode); | 3825 | btrfs_get_logged_extents(inode, &logged_list); |
3840 | 3826 | ||
3841 | /* | 3827 | /* |
3842 | * a brute force approach to making sure we get the most uptodate | 3828 | * a brute force approach to making sure we get the most uptodate |
@@ -3962,7 +3948,8 @@ log_extents: | |||
3962 | btrfs_release_path(path); | 3948 | btrfs_release_path(path); |
3963 | btrfs_release_path(dst_path); | 3949 | btrfs_release_path(dst_path); |
3964 | if (fast_search) { | 3950 | if (fast_search) { |
3965 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path); | 3951 | ret = btrfs_log_changed_extents(trans, root, inode, dst_path, |
3952 | &logged_list); | ||
3966 | if (ret) { | 3953 | if (ret) { |
3967 | err = ret; | 3954 | err = ret; |
3968 | goto out_unlock; | 3955 | goto out_unlock; |
@@ -3987,8 +3974,10 @@ log_extents: | |||
3987 | BTRFS_I(inode)->logged_trans = trans->transid; | 3974 | BTRFS_I(inode)->logged_trans = trans->transid; |
3988 | BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans; | 3975 | BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans; |
3989 | out_unlock: | 3976 | out_unlock: |
3990 | if (err) | 3977 | if (unlikely(err)) |
3991 | btrfs_free_logged_extents(log, log->log_transid); | 3978 | btrfs_put_logged_extents(&logged_list); |
3979 | else | ||
3980 | btrfs_submit_logged_extents(&logged_list, log); | ||
3992 | mutex_unlock(&BTRFS_I(inode)->log_mutex); | 3981 | mutex_unlock(&BTRFS_I(inode)->log_mutex); |
3993 | 3982 | ||
3994 | btrfs_free_path(path); | 3983 | btrfs_free_path(path); |