aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/tree-log.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/btrfs/tree-log.c')
-rw-r--r--fs/btrfs/tree-log.c334
1 files changed, 210 insertions, 124 deletions
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 9e1f2cd5e67a..1475979e5718 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -94,8 +94,11 @@
94#define LOG_WALK_REPLAY_ALL 3 94#define LOG_WALK_REPLAY_ALL 3
95 95
96static int btrfs_log_inode(struct btrfs_trans_handle *trans, 96static int btrfs_log_inode(struct btrfs_trans_handle *trans,
97 struct btrfs_root *root, struct inode *inode, 97 struct btrfs_root *root, struct inode *inode,
98 int inode_only); 98 int inode_only,
99 const loff_t start,
100 const loff_t end,
101 struct btrfs_log_ctx *ctx);
99static int link_to_fixup_dir(struct btrfs_trans_handle *trans, 102static int link_to_fixup_dir(struct btrfs_trans_handle *trans,
100 struct btrfs_root *root, 103 struct btrfs_root *root,
101 struct btrfs_path *path, u64 objectid); 104 struct btrfs_path *path, u64 objectid);
@@ -1496,7 +1499,7 @@ static noinline int link_to_fixup_dir(struct btrfs_trans_handle *trans,
1496 return -EIO; 1499 return -EIO;
1497 1500
1498 key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID; 1501 key.objectid = BTRFS_TREE_LOG_FIXUP_OBJECTID;
1499 btrfs_set_key_type(&key, BTRFS_ORPHAN_ITEM_KEY); 1502 key.type = BTRFS_ORPHAN_ITEM_KEY;
1500 key.offset = objectid; 1503 key.offset = objectid;
1501 1504
1502 ret = btrfs_insert_empty_item(trans, root, path, &key, 0); 1505 ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
@@ -1635,6 +1638,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
1635 found_key.type == log_key.type && 1638 found_key.type == log_key.type &&
1636 found_key.offset == log_key.offset && 1639 found_key.offset == log_key.offset &&
1637 btrfs_dir_type(path->nodes[0], dst_di) == log_type) { 1640 btrfs_dir_type(path->nodes[0], dst_di) == log_type) {
1641 update_size = false;
1638 goto out; 1642 goto out;
1639 } 1643 }
1640 1644
@@ -2155,7 +2159,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
2155 2159
2156 bytenr = btrfs_node_blockptr(cur, path->slots[*level]); 2160 bytenr = btrfs_node_blockptr(cur, path->slots[*level]);
2157 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]); 2161 ptr_gen = btrfs_node_ptr_generation(cur, path->slots[*level]);
2158 blocksize = btrfs_level_size(root, *level - 1); 2162 blocksize = root->nodesize;
2159 2163
2160 parent = path->nodes[*level]; 2164 parent = path->nodes[*level];
2161 root_owner = btrfs_header_owner(parent); 2165 root_owner = btrfs_header_owner(parent);
@@ -2981,8 +2985,6 @@ static noinline int log_dir_items(struct btrfs_trans_handle *trans,
2981 min_key.type = key_type; 2985 min_key.type = key_type;
2982 min_key.offset = min_offset; 2986 min_key.offset = min_offset;
2983 2987
2984 path->keep_locks = 1;
2985
2986 ret = btrfs_search_forward(root, &min_key, path, trans->transid); 2988 ret = btrfs_search_forward(root, &min_key, path, trans->transid);
2987 2989
2988 /* 2990 /*
@@ -3298,7 +3300,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3298 struct list_head ordered_sums; 3300 struct list_head ordered_sums;
3299 int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM; 3301 int skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
3300 bool has_extents = false; 3302 bool has_extents = false;
3301 bool need_find_last_extent = (*last_extent == 0); 3303 bool need_find_last_extent = true;
3302 bool done = false; 3304 bool done = false;
3303 3305
3304 INIT_LIST_HEAD(&ordered_sums); 3306 INIT_LIST_HEAD(&ordered_sums);
@@ -3352,8 +3354,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3352 */ 3354 */
3353 if (ins_keys[i].type == BTRFS_EXTENT_DATA_KEY) { 3355 if (ins_keys[i].type == BTRFS_EXTENT_DATA_KEY) {
3354 has_extents = true; 3356 has_extents = true;
3355 if (need_find_last_extent && 3357 if (first_key.objectid == (u64)-1)
3356 first_key.objectid == (u64)-1)
3357 first_key = ins_keys[i]; 3358 first_key = ins_keys[i];
3358 } else { 3359 } else {
3359 need_find_last_extent = false; 3360 need_find_last_extent = false;
@@ -3363,7 +3364,7 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3363 * or deletes of this inode don't have to relog the inode 3364 * or deletes of this inode don't have to relog the inode
3364 * again 3365 * again
3365 */ 3366 */
3366 if (btrfs_key_type(ins_keys + i) == BTRFS_EXTENT_DATA_KEY && 3367 if (ins_keys[i].type == BTRFS_EXTENT_DATA_KEY &&
3367 !skip_csum) { 3368 !skip_csum) {
3368 int found_type; 3369 int found_type;
3369 extent = btrfs_item_ptr(src, start_slot + i, 3370 extent = btrfs_item_ptr(src, start_slot + i,
@@ -3427,6 +3428,16 @@ static noinline int copy_items(struct btrfs_trans_handle *trans,
3427 if (!has_extents) 3428 if (!has_extents)
3428 return ret; 3429 return ret;
3429 3430
3431 if (need_find_last_extent && *last_extent == first_key.offset) {
3432 /*
3433 * We don't have any leafs between our current one and the one
3434 * we processed before that can have file extent items for our
3435 * inode (and have a generation number smaller than our current
3436 * transaction id).
3437 */
3438 need_find_last_extent = false;
3439 }
3440
3430 /* 3441 /*
3431 * Because we use btrfs_search_forward we could skip leaves that were 3442 * Because we use btrfs_search_forward we could skip leaves that were
3432 * not modified and then assume *last_extent is valid when it really 3443 * not modified and then assume *last_extent is valid when it really
@@ -3537,7 +3548,7 @@ fill_holes:
3537 0, 0); 3548 0, 0);
3538 if (ret) 3549 if (ret)
3539 break; 3550 break;
3540 *last_extent = offset + len; 3551 *last_extent = extent_end;
3541 } 3552 }
3542 /* 3553 /*
3543 * Need to let the callers know we dropped the path so they should 3554 * Need to let the callers know we dropped the path so they should
@@ -3562,107 +3573,33 @@ static int extent_cmp(void *priv, struct list_head *a, struct list_head *b)
3562 return 0; 3573 return 0;
3563} 3574}
3564 3575
3565static int log_one_extent(struct btrfs_trans_handle *trans, 3576static int wait_ordered_extents(struct btrfs_trans_handle *trans,
3566 struct inode *inode, struct btrfs_root *root, 3577 struct inode *inode,
3567 struct extent_map *em, struct btrfs_path *path, 3578 struct btrfs_root *root,
3568 struct list_head *logged_list) 3579 const struct extent_map *em,
3580 const struct list_head *logged_list,
3581 bool *ordered_io_error)
3569{ 3582{
3570 struct btrfs_root *log = root->log_root;
3571 struct btrfs_file_extent_item *fi;
3572 struct extent_buffer *leaf;
3573 struct btrfs_ordered_extent *ordered; 3583 struct btrfs_ordered_extent *ordered;
3574 struct list_head ordered_sums; 3584 struct btrfs_root *log = root->log_root;
3575 struct btrfs_map_token token;
3576 struct btrfs_key key;
3577 u64 mod_start = em->mod_start; 3585 u64 mod_start = em->mod_start;
3578 u64 mod_len = em->mod_len; 3586 u64 mod_len = em->mod_len;
3587 const bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
3579 u64 csum_offset; 3588 u64 csum_offset;
3580 u64 csum_len; 3589 u64 csum_len;
3581 u64 extent_offset = em->start - em->orig_start; 3590 LIST_HEAD(ordered_sums);
3582 u64 block_len; 3591 int ret = 0;
3583 int ret;
3584 bool skip_csum = BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM;
3585 int extent_inserted = 0;
3586
3587 INIT_LIST_HEAD(&ordered_sums);
3588 btrfs_init_map_token(&token);
3589
3590 ret = __btrfs_drop_extents(trans, log, inode, path, em->start,
3591 em->start + em->len, NULL, 0, 1,
3592 sizeof(*fi), &extent_inserted);
3593 if (ret)
3594 return ret;
3595
3596 if (!extent_inserted) {
3597 key.objectid = btrfs_ino(inode);
3598 key.type = BTRFS_EXTENT_DATA_KEY;
3599 key.offset = em->start;
3600
3601 ret = btrfs_insert_empty_item(trans, log, path, &key,
3602 sizeof(*fi));
3603 if (ret)
3604 return ret;
3605 }
3606 leaf = path->nodes[0];
3607 fi = btrfs_item_ptr(leaf, path->slots[0],
3608 struct btrfs_file_extent_item);
3609
3610 btrfs_set_token_file_extent_generation(leaf, fi, em->generation,
3611 &token);
3612 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) {
3613 skip_csum = true;
3614 btrfs_set_token_file_extent_type(leaf, fi,
3615 BTRFS_FILE_EXTENT_PREALLOC,
3616 &token);
3617 } else {
3618 btrfs_set_token_file_extent_type(leaf, fi,
3619 BTRFS_FILE_EXTENT_REG,
3620 &token);
3621 if (em->block_start == EXTENT_MAP_HOLE)
3622 skip_csum = true;
3623 }
3624
3625 block_len = max(em->block_len, em->orig_block_len);
3626 if (em->compress_type != BTRFS_COMPRESS_NONE) {
3627 btrfs_set_token_file_extent_disk_bytenr(leaf, fi,
3628 em->block_start,
3629 &token);
3630 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, block_len,
3631 &token);
3632 } else if (em->block_start < EXTENT_MAP_LAST_BYTE) {
3633 btrfs_set_token_file_extent_disk_bytenr(leaf, fi,
3634 em->block_start -
3635 extent_offset, &token);
3636 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, block_len,
3637 &token);
3638 } else {
3639 btrfs_set_token_file_extent_disk_bytenr(leaf, fi, 0, &token);
3640 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, 0,
3641 &token);
3642 }
3643 3592
3644 btrfs_set_token_file_extent_offset(leaf, fi, 3593 *ordered_io_error = false;
3645 em->start - em->orig_start,
3646 &token);
3647 btrfs_set_token_file_extent_num_bytes(leaf, fi, em->len, &token);
3648 btrfs_set_token_file_extent_ram_bytes(leaf, fi, em->ram_bytes, &token);
3649 btrfs_set_token_file_extent_compression(leaf, fi, em->compress_type,
3650 &token);
3651 btrfs_set_token_file_extent_encryption(leaf, fi, 0, &token);
3652 btrfs_set_token_file_extent_other_encoding(leaf, fi, 0, &token);
3653 btrfs_mark_buffer_dirty(leaf);
3654 3594
3655 btrfs_release_path(path); 3595 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags) ||
3656 if (ret) { 3596 em->block_start == EXTENT_MAP_HOLE)
3657 return ret;
3658 }
3659
3660 if (skip_csum)
3661 return 0; 3597 return 0;
3662 3598
3663 /* 3599 /*
3664 * First check and see if our csums are on our outstanding ordered 3600 * Wait far any ordered extent that covers our extent map. If it
3665 * extents. 3601 * finishes without an error, first check and see if our csums are on
3602 * our outstanding ordered extents.
3666 */ 3603 */
3667 list_for_each_entry(ordered, logged_list, log_list) { 3604 list_for_each_entry(ordered, logged_list, log_list) {
3668 struct btrfs_ordered_sum *sum; 3605 struct btrfs_ordered_sum *sum;
@@ -3674,6 +3611,24 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3674 mod_start + mod_len <= ordered->file_offset) 3611 mod_start + mod_len <= ordered->file_offset)
3675 continue; 3612 continue;
3676 3613
3614 if (!test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) &&
3615 !test_bit(BTRFS_ORDERED_IOERR, &ordered->flags) &&
3616 !test_bit(BTRFS_ORDERED_DIRECT, &ordered->flags)) {
3617 const u64 start = ordered->file_offset;
3618 const u64 end = ordered->file_offset + ordered->len - 1;
3619
3620 WARN_ON(ordered->inode != inode);
3621 filemap_fdatawrite_range(inode->i_mapping, start, end);
3622 }
3623
3624 wait_event(ordered->wait,
3625 (test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) ||
3626 test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)));
3627
3628 if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags)) {
3629 *ordered_io_error = true;
3630 break;
3631 }
3677 /* 3632 /*
3678 * We are going to copy all the csums on this ordered extent, so 3633 * We are going to copy all the csums on this ordered extent, so
3679 * go ahead and adjust mod_start and mod_len in case this 3634 * go ahead and adjust mod_start and mod_len in case this
@@ -3705,6 +3660,9 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3705 } 3660 }
3706 } 3661 }
3707 3662
3663 if (skip_csum)
3664 continue;
3665
3708 /* 3666 /*
3709 * To keep us from looping for the above case of an ordered 3667 * To keep us from looping for the above case of an ordered
3710 * extent that falls inside of the logged extent. 3668 * extent that falls inside of the logged extent.
@@ -3722,18 +3680,16 @@ static int log_one_extent(struct btrfs_trans_handle *trans,
3722 list_for_each_entry(sum, &ordered->list, list) { 3680 list_for_each_entry(sum, &ordered->list, list) {
3723 ret = btrfs_csum_file_blocks(trans, log, sum); 3681 ret = btrfs_csum_file_blocks(trans, log, sum);
3724 if (ret) 3682 if (ret)
3725 goto unlocked; 3683 break;
3726 } 3684 }
3727
3728 } 3685 }
3729unlocked:
3730 3686
3731 if (!mod_len || ret) 3687 if (*ordered_io_error || !mod_len || ret || skip_csum)
3732 return ret; 3688 return ret;
3733 3689
3734 if (em->compress_type) { 3690 if (em->compress_type) {
3735 csum_offset = 0; 3691 csum_offset = 0;
3736 csum_len = block_len; 3692 csum_len = max(em->block_len, em->orig_block_len);
3737 } else { 3693 } else {
3738 csum_offset = mod_start - em->start; 3694 csum_offset = mod_start - em->start;
3739 csum_len = mod_len; 3695 csum_len = mod_len;
@@ -3760,11 +3716,106 @@ unlocked:
3760 return ret; 3716 return ret;
3761} 3717}
3762 3718
3719static int log_one_extent(struct btrfs_trans_handle *trans,
3720 struct inode *inode, struct btrfs_root *root,
3721 const struct extent_map *em,
3722 struct btrfs_path *path,
3723 const struct list_head *logged_list,
3724 struct btrfs_log_ctx *ctx)
3725{
3726 struct btrfs_root *log = root->log_root;
3727 struct btrfs_file_extent_item *fi;
3728 struct extent_buffer *leaf;
3729 struct btrfs_map_token token;
3730 struct btrfs_key key;
3731 u64 extent_offset = em->start - em->orig_start;
3732 u64 block_len;
3733 int ret;
3734 int extent_inserted = 0;
3735 bool ordered_io_err = false;
3736
3737 ret = wait_ordered_extents(trans, inode, root, em, logged_list,
3738 &ordered_io_err);
3739 if (ret)
3740 return ret;
3741
3742 if (ordered_io_err) {
3743 ctx->io_err = -EIO;
3744 return 0;
3745 }
3746
3747 btrfs_init_map_token(&token);
3748
3749 ret = __btrfs_drop_extents(trans, log, inode, path, em->start,
3750 em->start + em->len, NULL, 0, 1,
3751 sizeof(*fi), &extent_inserted);
3752 if (ret)
3753 return ret;
3754
3755 if (!extent_inserted) {
3756 key.objectid = btrfs_ino(inode);
3757 key.type = BTRFS_EXTENT_DATA_KEY;
3758 key.offset = em->start;
3759
3760 ret = btrfs_insert_empty_item(trans, log, path, &key,
3761 sizeof(*fi));
3762 if (ret)
3763 return ret;
3764 }
3765 leaf = path->nodes[0];
3766 fi = btrfs_item_ptr(leaf, path->slots[0],
3767 struct btrfs_file_extent_item);
3768
3769 btrfs_set_token_file_extent_generation(leaf, fi, em->generation,
3770 &token);
3771 if (test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
3772 btrfs_set_token_file_extent_type(leaf, fi,
3773 BTRFS_FILE_EXTENT_PREALLOC,
3774 &token);
3775 else
3776 btrfs_set_token_file_extent_type(leaf, fi,
3777 BTRFS_FILE_EXTENT_REG,
3778 &token);
3779
3780 block_len = max(em->block_len, em->orig_block_len);
3781 if (em->compress_type != BTRFS_COMPRESS_NONE) {
3782 btrfs_set_token_file_extent_disk_bytenr(leaf, fi,
3783 em->block_start,
3784 &token);
3785 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, block_len,
3786 &token);
3787 } else if (em->block_start < EXTENT_MAP_LAST_BYTE) {
3788 btrfs_set_token_file_extent_disk_bytenr(leaf, fi,
3789 em->block_start -
3790 extent_offset, &token);
3791 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, block_len,
3792 &token);
3793 } else {
3794 btrfs_set_token_file_extent_disk_bytenr(leaf, fi, 0, &token);
3795 btrfs_set_token_file_extent_disk_num_bytes(leaf, fi, 0,
3796 &token);
3797 }
3798
3799 btrfs_set_token_file_extent_offset(leaf, fi, extent_offset, &token);
3800 btrfs_set_token_file_extent_num_bytes(leaf, fi, em->len, &token);
3801 btrfs_set_token_file_extent_ram_bytes(leaf, fi, em->ram_bytes, &token);
3802 btrfs_set_token_file_extent_compression(leaf, fi, em->compress_type,
3803 &token);
3804 btrfs_set_token_file_extent_encryption(leaf, fi, 0, &token);
3805 btrfs_set_token_file_extent_other_encoding(leaf, fi, 0, &token);
3806 btrfs_mark_buffer_dirty(leaf);
3807
3808 btrfs_release_path(path);
3809
3810 return ret;
3811}
3812
3763static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, 3813static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans,
3764 struct btrfs_root *root, 3814 struct btrfs_root *root,
3765 struct inode *inode, 3815 struct inode *inode,
3766 struct btrfs_path *path, 3816 struct btrfs_path *path,
3767 struct list_head *logged_list) 3817 struct list_head *logged_list,
3818 struct btrfs_log_ctx *ctx)
3768{ 3819{
3769 struct extent_map *em, *n; 3820 struct extent_map *em, *n;
3770 struct list_head extents; 3821 struct list_head extents;
@@ -3822,7 +3873,8 @@ process:
3822 3873
3823 write_unlock(&tree->lock); 3874 write_unlock(&tree->lock);
3824 3875
3825 ret = log_one_extent(trans, inode, root, em, path, logged_list); 3876 ret = log_one_extent(trans, inode, root, em, path, logged_list,
3877 ctx);
3826 write_lock(&tree->lock); 3878 write_lock(&tree->lock);
3827 clear_em_logging(tree, em); 3879 clear_em_logging(tree, em);
3828 free_extent_map(em); 3880 free_extent_map(em);
@@ -3849,8 +3901,11 @@ process:
3849 * This handles both files and directories. 3901 * This handles both files and directories.
3850 */ 3902 */
3851static int btrfs_log_inode(struct btrfs_trans_handle *trans, 3903static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3852 struct btrfs_root *root, struct inode *inode, 3904 struct btrfs_root *root, struct inode *inode,
3853 int inode_only) 3905 int inode_only,
3906 const loff_t start,
3907 const loff_t end,
3908 struct btrfs_log_ctx *ctx)
3854{ 3909{
3855 struct btrfs_path *path; 3910 struct btrfs_path *path;
3856 struct btrfs_path *dst_path; 3911 struct btrfs_path *dst_path;
@@ -3867,6 +3922,7 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3867 int ins_nr; 3922 int ins_nr;
3868 bool fast_search = false; 3923 bool fast_search = false;
3869 u64 ino = btrfs_ino(inode); 3924 u64 ino = btrfs_ino(inode);
3925 struct extent_map_tree *em_tree = &BTRFS_I(inode)->extent_tree;
3870 3926
3871 path = btrfs_alloc_path(); 3927 path = btrfs_alloc_path();
3872 if (!path) 3928 if (!path)
@@ -3950,7 +4006,6 @@ static int btrfs_log_inode(struct btrfs_trans_handle *trans,
3950 err = ret; 4006 err = ret;
3951 goto out_unlock; 4007 goto out_unlock;
3952 } 4008 }
3953 path->keep_locks = 1;
3954 4009
3955 while (1) { 4010 while (1) {
3956 ins_nr = 0; 4011 ins_nr = 0;
@@ -3980,7 +4035,8 @@ again:
3980 if (ret < 0) { 4035 if (ret < 0) {
3981 err = ret; 4036 err = ret;
3982 goto out_unlock; 4037 goto out_unlock;
3983 } if (ret) { 4038 }
4039 if (ret) {
3984 ins_nr = 0; 4040 ins_nr = 0;
3985 btrfs_release_path(path); 4041 btrfs_release_path(path);
3986 continue; 4042 continue;
@@ -4034,19 +4090,41 @@ log_extents:
4034 btrfs_release_path(dst_path); 4090 btrfs_release_path(dst_path);
4035 if (fast_search) { 4091 if (fast_search) {
4036 ret = btrfs_log_changed_extents(trans, root, inode, dst_path, 4092 ret = btrfs_log_changed_extents(trans, root, inode, dst_path,
4037 &logged_list); 4093 &logged_list, ctx);
4038 if (ret) { 4094 if (ret) {
4039 err = ret; 4095 err = ret;
4040 goto out_unlock; 4096 goto out_unlock;
4041 } 4097 }
4042 } else if (inode_only == LOG_INODE_ALL) { 4098 } else if (inode_only == LOG_INODE_ALL) {
4043 struct extent_map_tree *tree = &BTRFS_I(inode)->extent_tree;
4044 struct extent_map *em, *n; 4099 struct extent_map *em, *n;
4045 4100
4046 write_lock(&tree->lock); 4101 write_lock(&em_tree->lock);
4047 list_for_each_entry_safe(em, n, &tree->modified_extents, list) 4102 /*
4048 list_del_init(&em->list); 4103 * We can't just remove every em if we're called for a ranged
4049 write_unlock(&tree->lock); 4104 * fsync - that is, one that doesn't cover the whole possible
4105 * file range (0 to LLONG_MAX). This is because we can have
4106 * em's that fall outside the range we're logging and therefore
4107 * their ordered operations haven't completed yet
4108 * (btrfs_finish_ordered_io() not invoked yet). This means we
4109 * didn't get their respective file extent item in the fs/subvol
4110 * tree yet, and need to let the next fast fsync (one which
4111 * consults the list of modified extent maps) find the em so
4112 * that it logs a matching file extent item and waits for the
4113 * respective ordered operation to complete (if it's still
4114 * running).
4115 *
4116 * Removing every em outside the range we're logging would make
4117 * the next fast fsync not log their matching file extent items,
4118 * therefore making us lose data after a log replay.
4119 */
4120 list_for_each_entry_safe(em, n, &em_tree->modified_extents,
4121 list) {
4122 const u64 mod_end = em->mod_start + em->mod_len - 1;
4123
4124 if (em->mod_start >= start && mod_end <= end)
4125 list_del_init(&em->list);
4126 }
4127 write_unlock(&em_tree->lock);
4050 } 4128 }
4051 4129
4052 if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) { 4130 if (inode_only == LOG_INODE_ALL && S_ISDIR(inode->i_mode)) {
@@ -4056,6 +4134,7 @@ log_extents:
4056 goto out_unlock; 4134 goto out_unlock;
4057 } 4135 }
4058 } 4136 }
4137
4059 BTRFS_I(inode)->logged_trans = trans->transid; 4138 BTRFS_I(inode)->logged_trans = trans->transid;
4060 BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans; 4139 BTRFS_I(inode)->last_log_commit = BTRFS_I(inode)->last_sub_trans;
4061out_unlock: 4140out_unlock:
@@ -4152,7 +4231,10 @@ out:
4152 */ 4231 */
4153static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, 4232static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
4154 struct btrfs_root *root, struct inode *inode, 4233 struct btrfs_root *root, struct inode *inode,
4155 struct dentry *parent, int exists_only, 4234 struct dentry *parent,
4235 const loff_t start,
4236 const loff_t end,
4237 int exists_only,
4156 struct btrfs_log_ctx *ctx) 4238 struct btrfs_log_ctx *ctx)
4157{ 4239{
4158 int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL; 4240 int inode_only = exists_only ? LOG_INODE_EXISTS : LOG_INODE_ALL;
@@ -4198,7 +4280,7 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
4198 if (ret) 4280 if (ret)
4199 goto end_no_trans; 4281 goto end_no_trans;
4200 4282
4201 ret = btrfs_log_inode(trans, root, inode, inode_only); 4283 ret = btrfs_log_inode(trans, root, inode, inode_only, start, end, ctx);
4202 if (ret) 4284 if (ret)
4203 goto end_trans; 4285 goto end_trans;
4204 4286
@@ -4226,7 +4308,8 @@ static int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
4226 4308
4227 if (BTRFS_I(inode)->generation > 4309 if (BTRFS_I(inode)->generation >
4228 root->fs_info->last_trans_committed) { 4310 root->fs_info->last_trans_committed) {
4229 ret = btrfs_log_inode(trans, root, inode, inode_only); 4311 ret = btrfs_log_inode(trans, root, inode, inode_only,
4312 0, LLONG_MAX, ctx);
4230 if (ret) 4313 if (ret)
4231 goto end_trans; 4314 goto end_trans;
4232 } 4315 }
@@ -4260,13 +4343,15 @@ end_no_trans:
4260 */ 4343 */
4261int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans, 4344int btrfs_log_dentry_safe(struct btrfs_trans_handle *trans,
4262 struct btrfs_root *root, struct dentry *dentry, 4345 struct btrfs_root *root, struct dentry *dentry,
4346 const loff_t start,
4347 const loff_t end,
4263 struct btrfs_log_ctx *ctx) 4348 struct btrfs_log_ctx *ctx)
4264{ 4349{
4265 struct dentry *parent = dget_parent(dentry); 4350 struct dentry *parent = dget_parent(dentry);
4266 int ret; 4351 int ret;
4267 4352
4268 ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent, 4353 ret = btrfs_log_inode_parent(trans, root, dentry->d_inode, parent,
4269 0, ctx); 4354 start, end, 0, ctx);
4270 dput(parent); 4355 dput(parent);
4271 4356
4272 return ret; 4357 return ret;
@@ -4316,7 +4401,7 @@ int btrfs_recover_log_trees(struct btrfs_root *log_root_tree)
4316again: 4401again:
4317 key.objectid = BTRFS_TREE_LOG_OBJECTID; 4402 key.objectid = BTRFS_TREE_LOG_OBJECTID;
4318 key.offset = (u64)-1; 4403 key.offset = (u64)-1;
4319 btrfs_set_key_type(&key, BTRFS_ROOT_ITEM_KEY); 4404 key.type = BTRFS_ROOT_ITEM_KEY;
4320 4405
4321 while (1) { 4406 while (1) {
4322 ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0); 4407 ret = btrfs_search_slot(NULL, log_root_tree, &key, path, 0, 0);
@@ -4503,6 +4588,7 @@ int btrfs_log_new_name(struct btrfs_trans_handle *trans,
4503 root->fs_info->last_trans_committed)) 4588 root->fs_info->last_trans_committed))
4504 return 0; 4589 return 0;
4505 4590
4506 return btrfs_log_inode_parent(trans, root, inode, parent, 1, NULL); 4591 return btrfs_log_inode_parent(trans, root, inode, parent, 0,
4592 LLONG_MAX, 1, NULL);
4507} 4593}
4508 4594