Skip to content

Commit 1014f3d

Browse files
committed
Merge branch 'next/filipe' into for-4.13-part2
- incremental send fixes - raid56 corruption fix (cloned bio iteration)
2 parents 848c23b + 6592e58 commit 1014f3d

File tree

2 files changed

+73
-41
lines changed

2 files changed

+73
-41
lines changed

fs/btrfs/raid56.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1136,20 +1136,27 @@ static void validate_rbio_for_rmw(struct btrfs_raid_bio *rbio)
11361136
static void index_rbio_pages(struct btrfs_raid_bio *rbio)
11371137
{
11381138
struct bio *bio;
1139-
struct bio_vec *bvec;
11401139
u64 start;
11411140
unsigned long stripe_offset;
11421141
unsigned long page_index;
1143-
int i;
11441142

11451143
spin_lock_irq(&rbio->bio_list_lock);
11461144
bio_list_for_each(bio, &rbio->bio_list) {
1145+
struct bio_vec bvec;
1146+
struct bvec_iter iter;
1147+
int i = 0;
1148+
11471149
start = (u64)bio->bi_iter.bi_sector << 9;
11481150
stripe_offset = start - rbio->bbio->raid_map[0];
11491151
page_index = stripe_offset >> PAGE_SHIFT;
11501152

1151-
bio_for_each_segment_all(bvec, bio, i)
1152-
rbio->bio_pages[page_index + i] = bvec->bv_page;
1153+
if (bio_flagged(bio, BIO_CLONED))
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+
}
11531160
}
11541161
spin_unlock_irq(&rbio->bio_list_lock);
11551162
}
@@ -1423,11 +1430,14 @@ static int fail_bio_stripe(struct btrfs_raid_bio *rbio,
14231430
*/
14241431
static void set_bio_pages_uptodate(struct bio *bio)
14251432
{
1426-
struct bio_vec *bvec;
1427-
int i;
1433+
struct bio_vec bvec;
1434+
struct bvec_iter iter;
1435+
1436+
if (bio_flagged(bio, BIO_CLONED))
1437+
bio->bi_iter = btrfs_io_bio(bio)->iter;
14281438

1429-
bio_for_each_segment_all(bvec, bio, i)
1430-
SetPageUptodate(bvec->bv_page);
1439+
bio_for_each_segment(bvec, bio, iter)
1440+
SetPageUptodate(bvec.bv_page);
14311441
}
14321442

14331443
/*

fs/btrfs/send.c

Lines changed: 55 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1856,7 +1856,7 @@ static int is_first_ref(struct btrfs_root *root,
18561856
*/
18571857
static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
18581858
const char *name, int name_len,
1859-
u64 *who_ino, u64 *who_gen)
1859+
u64 *who_ino, u64 *who_gen, u64 *who_mode)
18601860
{
18611861
int ret = 0;
18621862
u64 gen;
@@ -1905,7 +1905,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
19051905
if (other_inode > sctx->send_progress ||
19061906
is_waiting_for_move(sctx, other_inode)) {
19071907
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);
19091909
if (ret < 0)
19101910
goto out;
19111911

@@ -3683,6 +3683,36 @@ static int wait_for_parent_move(struct send_ctx *sctx,
36833683
return ret;
36843684
}
36853685

3686+
static 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+
36863716
/*
36873717
* This does all the move/link/unlink/rmdir magic.
36883718
*/
@@ -3696,10 +3726,12 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
36963726
struct fs_path *valid_path = NULL;
36973727
u64 ow_inode = 0;
36983728
u64 ow_gen;
3729+
u64 ow_mode;
36993730
int did_overwrite = 0;
37003731
int is_orphan = 0;
37013732
u64 last_dir_ino_rm = 0;
37023733
bool can_rename = true;
3734+
bool orphanized_dir = false;
37033735
bool orphanized_ancestor = false;
37043736

37053737
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)
37983830
*/
37993831
ret = will_overwrite_ref(sctx, cur->dir, cur->dir_gen,
38003832
cur->name, cur->name_len,
3801-
&ow_inode, &ow_gen);
3833+
&ow_inode, &ow_gen, &ow_mode);
38023834
if (ret < 0)
38033835
goto out;
38043836
if (ret) {
@@ -3815,6 +3847,8 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
38153847
cur->full_path);
38163848
if (ret < 0)
38173849
goto out;
3850+
if (S_ISDIR(ow_mode))
3851+
orphanized_dir = true;
38183852

38193853
/*
38203854
* If ow_inode has its rename operation delayed
@@ -3920,6 +3954,18 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
39203954
if (ret < 0)
39213955
goto out;
39223956
} 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+
}
39233969
ret = send_link(sctx, cur->full_path,
39243970
valid_path);
39253971
if (ret < 0)
@@ -3990,34 +4036,9 @@ static int process_recorded_refs(struct send_ctx *sctx, int *pending_move)
39904036
* ancestor inode.
39914037
*/
39924038
if (orphanized_ancestor) {
3993-
struct fs_path *new_path;
3994-
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);
4039+
ret = update_ref_path(sctx, cur);
4040+
if (ret < 0)
40174041
goto out;
4018-
}
4019-
fs_path_free(cur->full_path);
4020-
set_ref_path(cur, new_path);
40214042
}
40224043
ret = send_unlink(sctx, cur->full_path);
40234044
if (ret < 0)
@@ -5249,15 +5270,12 @@ static int is_extent_unchanged(struct send_ctx *sctx,
52495270
goto out;
52505271
}
52515272

5252-
right_disknr = btrfs_file_extent_disk_bytenr(eb, ei);
52535273
if (right_type == BTRFS_FILE_EXTENT_INLINE) {
52545274
right_len = btrfs_file_extent_inline_len(eb, slot, ei);
52555275
right_len = PAGE_ALIGN(right_len);
52565276
} else {
52575277
right_len = btrfs_file_extent_num_bytes(eb, ei);
52585278
}
5259-
right_offset = btrfs_file_extent_offset(eb, ei);
5260-
right_gen = btrfs_file_extent_generation(eb, ei);
52615279

52625280
/*
52635281
* 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,
52825300
goto out;
52835301
}
52845302

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+
52855307
left_offset_fixed = left_offset;
52865308
if (key.offset < ekey->offset) {
52875309
/* Fix the right offset for 2a and 7. */

0 commit comments

Comments
 (0)