aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Sterba <dsterba@suse.com>2017-07-14 14:37:38 -0400
committerDavid Sterba <dsterba@suse.com>2017-07-14 14:37:38 -0400
commit1014f3d68fc4034966b15234dc12b81147ee83b2 (patch)
tree02c4fc56d21f6ec275d60bac8a8baad665f2e69e
parent848c23b78fafdcd3270b06a30737f8dbd70c347f (diff)
parent6592e58c6b68e61f003a01ba29a3716e7e2e9484 (diff)
Merge branch 'next/filipe' into for-4.13-part2
- incremental send fixes - raid56 corruption fix (cloned bio iteration)
-rw-r--r--fs/btrfs/raid56.c26
-rw-r--r--fs/btrfs/send.c88
2 files changed, 73 insertions, 41 deletions
diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index b9abb0b01021..b89d07003697 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1136,20 +1136,27 @@ static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio)
1136static void index_rbio_pages(struct btrfs_raid_bio *rbio) 1136static void index_rbio_pages(struct btrfs_raid_bio *rbio)
1137{ 1137{
1138 struct bio *bio; 1138 struct bio *bio;
1139 struct bio_vec *bvec;
1140 u64 start; 1139 u64 start;
1141 unsigned long stripe_offset; 1140 unsigned long stripe_offset;
1142 unsigned long page_index; 1141 unsigned long page_index;
1143 int i;
1144 1142
1145 spin_lock_irq(&rbio->bio_list_lock); 1143 spin_lock_irq(&rbio->bio_list_lock);
1146 bio_list_for_each(bio, &rbio->bio_list) { 1144 bio_list_for_each(bio, &rbio->bio_list) {
1145 struct bio_vec bvec;
1146 struct bvec_iter iter;
1147 int i = 0;
1148
1147 start = (u64)bio->bi_iter.bi_sector << 9; 1149 start = (u64)bio->bi_iter.bi_sector << 9;
1148 stripe_offset = start - rbio->bbio->raid_map[0]; 1150 stripe_offset = start - rbio->bbio->raid_map[0];
1149 page_index = stripe_offset >> PAGE_SHIFT; 1151 page_index = stripe_offset >> PAGE_SHIFT;
1150 1152
1151 bio_for_each_segment_all(bvec, bio, i) 1153 if (bio_flagged(bio, BIO_CLONED))
1152 rbio->bio_pages[page_index + i] = bvec->bv_page; 1154 bio->bi_iter = btrfs_io_bio(bio)->iter;
1155
1156 bio_for_each_segment(bvec, bio, iter) {
1157 rbio->bio_pages[page_index + i] = bvec.bv_page;
1158 i++;
1159 }
1153 } 1160 }
1154 spin_unlock_irq(&rbio->bio_list_lock); 1161 spin_unlock_irq(&rbio->bio_list_lock);
1155} 1162}
@@ -1423,11 +1430,14 @@ static int fail_bio_stripe(struct btrfs_raid_bio *rbio,
1423 */ 1430 */
1424static void set_bio_pages_uptodate(struct bio *bio) 1431static void set_bio_pages_uptodate(struct bio *bio)
1425{ 1432{
1426 struct bio_vec *bvec; 1433 struct bio_vec bvec;
1427 int i; 1434 struct bvec_iter iter;
1435
1436 if (bio_flagged(bio, BIO_CLONED))
1437 bio->bi_iter = btrfs_io_bio(bio)->iter;
1428 1438
1429 bio_for_each_segment_all(bvec, bio, i) 1439 bio_for_each_segment(bvec, bio, iter)
1430 SetPageUptodate(bvec->bv_page); 1440 SetPageUptodate(bvec.bv_page);
1431} 1441}
1432 1442
1433/* 1443/*
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index e937c10b8287..b082210df9c8 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -1856,7 +1856,7 @@ out:
1856 */ 1856 */
1857static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen, 1857static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
1858 const char *name, int name_len, 1858 const char *name, int name_len,
1859 u64 *who_ino, u64 *who_gen) 1859 u64 *who_ino, u64 *who_gen, u64 *who_mode)
1860{ 1860{
1861 int ret = 0; 1861 int ret = 0;
1862 u64 gen; 1862 u64 gen;
@@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
1905 if (other_inode > sctx->send_progress || 1905 if (other_inode > sctx->send_progress ||
1906 is_waiting_for_move(sctx, other_inode)) { 1906 is_waiting_for_move(sctx, other_inode)) {
1907 ret = get_inode_info(sctx->parent_root, other_inode, NULL, 1907 ret = get_inode_info(sctx->parent_root, other_inode, NULL,
1908 who_gen, NULL, NULL, NULL, NULL); 1908 who_gen, who_mode, NULL, NULL, NULL);
1909 if (ret < 0) 1909 if (ret < 0)
1910 goto out; 1910 goto out;
1911 1911
@@ -3683,6 +3683,36 @@ out:
3683 return ret; 3683 return ret;
3684} 3684}
3685 3685
3686static int update_ref_path(struct send_ctx *sctx, struct recorded_ref *ref)
3687{
3688 int ret;
3689 struct fs_path *new_path;
3690
3691 /*
3692 * Our reference's name member points to its full_path member string, so
3693 * we use here a new path.
3694 */
3695 new_path = fs_path_alloc();
3696 if (!new_path)
3697 return -ENOMEM;
3698
3699 ret = get_cur_path(sctx, ref->dir, ref->dir_gen, new_path);
3700 if (ret < 0) {
3701 fs_path_free(new_path);
3702 return ret;
3703 }
3704 ret = fs_path_add(new_path, ref->name, ref->name_len);
3705 if (ret < 0) {
3706 fs_path_free(new_path);
3707 return ret;
3708 }
3709
3710 fs_path_free(ref->full_path);
3711 set_ref_path(ref, new_path);
3712
3713 return 0;
3714}
3715
3686/* 3716/*
3687 * This does all the move/link/unlink/rmdir magic. 3717 * This does all the move/link/unlink/rmdir magic.
3688 */ 3718 */
@@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3696 struct fs_path *valid_path = NULL; 3726 struct fs_path *valid_path = NULL;
3697 u64 ow_inode = 0; 3727 u64 ow_inode = 0;
3698 u64 ow_gen; 3728 u64 ow_gen;
3729 u64 ow_mode;
3699 int did_overwrite = 0; 3730 int did_overwrite = 0;
3700 int is_orphan = 0; 3731 int is_orphan = 0;
3701 u64 last_dir_ino_rm = 0; 3732 u64 last_dir_ino_rm = 0;
3702 bool can_rename = true; 3733 bool can_rename = true;
3734 bool orphanized_dir = false;
3703 bool orphanized_ancestor = false; 3735 bool orphanized_ancestor = false;
3704 3736
3705 btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino); 3737 btrfs_debug(fs_info, "process_recorded_refs %llu", sctx->cur_ino);
@@ -3798,7 +3830,7 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3798 */ 3830 */
3799 ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen, 3831 ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen,
3800 cur->name, cur->name_len, 3832 cur->name, cur->name_len,
3801 &ow_inode, &ow_gen); 3833 &ow_inode, &ow_gen, &ow_mode);
3802 if (ret < 0) 3834 if (ret < 0)
3803 goto out; 3835 goto out;
3804 if (ret) { 3836 if (ret) {
@@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3815 cur->full_path); 3847 cur->full_path);
3816 if (ret < 0) 3848 if (ret < 0)
3817 goto out; 3849 goto out;
3850 if (S_ISDIR(ow_mode))
3851 orphanized_dir = true;
3818 3852
3819 /* 3853 /*
3820 * If ow_inode has its rename operation delayed 3854 * If ow_inode has its rename operation delayed
@@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3920 if (ret < 0) 3954 if (ret < 0)
3921 goto out; 3955 goto out;
3922 } else { 3956 } else {
3957 /*
3958 * We might have previously orphanized an inode
3959 * which is an ancestor of our current inode,
3960 * so our reference's full path, which was
3961 * computed before any such orphanizations, must
3962 * be updated.
3963 */
3964 if (orphanized_dir) {
3965 ret = update_ref_path(sctx, cur);
3966 if (ret < 0)
3967 goto out;
3968 }
3923 ret = send_link(sctx, cur->full_path, 3969 ret = send_link(sctx, cur->full_path,
3924 valid_path); 3970 valid_path);
3925 if (ret < 0) 3971 if (ret < 0)
@@ -3990,34 +4036,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
3990 * ancestor inode. 4036 * ancestor inode.
3991 */ 4037 */
3992 if (orphanized_ancestor) { 4038 if (orphanized_ancestor) {
3993 struct fs_path *new_path; 4039 ret = update_ref_path(sctx, cur);
3994 4040 if (ret < 0)
3995 /*
3996 * Our reference's name member points to
3997 * its full_path member string, so we
3998 * use here a new path.
3999 */
4000 new_path = fs_path_alloc();
4001 if (!new_path) {
4002 ret = -ENOMEM;
4003 goto out;
4004 }
4005 ret = get_cur_path(sctx, cur->dir,
4006 cur->dir_gen,
4007 new_path);
4008 if (ret < 0) {
4009 fs_path_free(new_path);
4010 goto out;
4011 }
4012 ret = fs_path_add(new_path,
4013 cur->name,
4014 cur->name_len);
4015 if (ret < 0) {
4016 fs_path_free(new_path);
4017 goto out; 4041 goto out;
4018 }
4019 fs_path_free(cur->full_path);
4020 set_ref_path(cur, new_path);
4021 } 4042 }
4022 ret = send_unlink(sctx, cur->full_path); 4043 ret = send_unlink(sctx, cur->full_path);
4023 if (ret < 0) 4044 if (ret < 0)
@@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx,
5249 goto out; 5270 goto out;
5250 } 5271 }
5251 5272
5252 right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
5253 if (right_type == BTRFS_FILE_EXTENT_INLINE) { 5273 if (right_type == BTRFS_FILE_EXTENT_INLINE) {
5254 right_len = btrfs_file_extent_inline_len(eb, slot, ei); 5274 right_len = btrfs_file_extent_inline_len(eb, slot, ei);
5255 right_len = PAGE_ALIGN(right_len); 5275 right_len = PAGE_ALIGN(right_len);
5256 } else { 5276 } else {
5257 right_len = btrfs_file_extent_num_bytes(eb, ei); 5277 right_len = btrfs_file_extent_num_bytes(eb, ei);
5258 } 5278 }
5259 right_offset = btrfs_file_extent_offset(eb, ei);
5260 right_gen = btrfs_file_extent_generation(eb, ei);
5261 5279
5262 /* 5280 /*
5263 * Are we at extent 8? If yes, we know the extent is changed. 5281 * Are we at extent 8? If yes, we know the extent is changed.
@@ -5282,6 +5300,10 @@ static int is_extent_unchanged(struct send_ctx *sctx,
5282 goto out; 5300 goto out;
5283 } 5301 }
5284 5302
5303 right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
5304 right_offset = btrfs_file_extent_offset(eb, ei);
5305 right_gen = btrfs_file_extent_generation(eb, ei);
5306
5285 left_offset_fixed = left_offset; 5307 left_offset_fixed = left_offset;
5286 if (key.offset < ekey->offset) { 5308 if (key.offset < ekey->offset) {
5287 /* Fix the right offset for 2a and 7. */ 5309 /* Fix the right offset for 2a and 7. */