Skip to content

Commit bc24370

Browse files
committed
Merge branch 'for-4.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux
Pull btrfs fixes from David Sterba: "We've identified and fixed a silent corruption (introduced by code in the first pull), a fixup after the blk_status_t merge and two fixes to incremental send that Filipe has been hunting for some time" * 'for-4.13-part2' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave/linux: Btrfs: fix unexpected return value of bio_readpage_error btrfs: btrfs_create_repair_bio never fails, skip error handling btrfs: cloned bios must not be iterated by bio_for_each_segment_all Btrfs: fix write corruption due to bio cloning on raid5/6 Btrfs: incremental send, fix invalid memory access Btrfs: incremental send, fix invalid path for link commands
2 parents 0ffff11 + c3cfb65 commit bc24370

File tree

7 files changed

+88
-57
lines changed

7 files changed

+88
-57
lines changed

fs/btrfs/compression.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ static void end_compressed_bio_read(struct bio *bio)
152152
* we have verified the checksum already, set page
153153
* checked so the end_io handlers know about it
154154
*/
155+
ASSERT(!bio_flagged(bio, BIO_CLONED));
155156
bio_for_each_segment_all(bvec, cb->orig_bio, i)
156157
SetPageChecked(bvec->bv_page);
157158

fs/btrfs/disk-io.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -964,6 +964,7 @@ static blk_status_t btree_csum_one_bio(struct bio *bio)
964964
struct btrfs_root *root;
965965
int i, ret = 0;
966966

967+
ASSERT(!bio_flagged(bio, BIO_CLONED));
967968
bio_for_each_segment_all(bvec, bio, i) {
968969
root = BTRFS_I(bvec->bv_page->mapping->host)->root;
969970
ret = csum_dirty_buffer(root->fs_info, bvec->bv_page);

fs/btrfs/extent_io.c

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2258,7 +2258,7 @@ int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
22582258
return 0;
22592259
}
22602260

2261-
int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
2261+
bool btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
22622262
struct io_failure_record *failrec, int failed_mirror)
22632263
{
22642264
struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -2274,7 +2274,7 @@ int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
22742274
btrfs_debug(fs_info,
22752275
"Check Repairable: cannot repair, num_copies=%d, next_mirror %d, failed_mirror %d",
22762276
num_copies, failrec->this_mirror, failed_mirror);
2277-
return 0;
2277+
return false;
22782278
}
22792279

22802280
/*
@@ -2315,10 +2315,10 @@ int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
23152315
btrfs_debug(fs_info,
23162316
"Check Repairable: (fail) num_copies=%d, next_mirror %d, failed_mirror %d",
23172317
num_copies, failrec->this_mirror, failed_mirror);
2318-
return 0;
2318+
return false;
23192319
}
23202320

2321-
return 1;
2321+
return true;
23222322
}
23232323

23242324

@@ -2382,8 +2382,8 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
23822382
if (ret)
23832383
return ret;
23842384

2385-
ret = btrfs_check_repairable(inode, failed_bio, failrec, failed_mirror);
2386-
if (!ret) {
2385+
if (!btrfs_check_repairable(inode, failed_bio, failrec,
2386+
failed_mirror)) {
23872387
free_io_failure(failure_tree, tree, failrec);
23882388
return -EIO;
23892389
}
@@ -2396,10 +2396,6 @@ static int bio_readpage_error(struct bio *failed_bio, u64 phy_offset,
23962396
start - page_offset(page),
23972397
(int)phy_offset, failed_bio->bi_end_io,
23982398
NULL);
2399-
if (!bio) {
2400-
free_io_failure(failure_tree, tree, failrec);
2401-
return -EIO;
2402-
}
24032399
bio_set_op_attrs(bio, REQ_OP_READ, read_mode);
24042400

24052401
btrfs_debug(btrfs_sb(inode->i_sb),
@@ -2456,6 +2452,7 @@ static void end_bio_extent_writepage(struct bio *bio)
24562452
u64 end;
24572453
int i;
24582454

2455+
ASSERT(!bio_flagged(bio, BIO_CLONED));
24592456
bio_for_each_segment_all(bvec, bio, i) {
24602457
struct page *page = bvec->bv_page;
24612458
struct inode *inode = page->mapping->host;
@@ -2526,6 +2523,7 @@ static void end_bio_extent_readpage(struct bio *bio)
25262523
int ret;
25272524
int i;
25282525

2526+
ASSERT(!bio_flagged(bio, BIO_CLONED));
25292527
bio_for_each_segment_all(bvec, bio, i) {
25302528
struct page *page = bvec->bv_page;
25312529
struct inode *inode = page->mapping->host;
@@ -3680,6 +3678,7 @@ static void end_bio_extent_buffer_writepage(struct bio *bio)
36803678
struct extent_buffer *eb;
36813679
int i, done;
36823680

3681+
ASSERT(!bio_flagged(bio, BIO_CLONED));
36833682
bio_for_each_segment_all(bvec, bio, i) {
36843683
struct page *page = bvec->bv_page;
36853684

fs/btrfs/extent_io.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -539,8 +539,8 @@ void btrfs_free_io_failure_record(struct btrfs_inode *inode, u64 start,
539539
u64 end);
540540
int btrfs_get_io_failure_record(struct inode *inode, u64 start, u64 end,
541541
struct io_failure_record **failrec_ret);
542-
int btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
543-
struct io_failure_record *failrec, int fail_mirror);
542+
bool btrfs_check_repairable(struct inode *inode, struct bio *failed_bio,
543+
struct io_failure_record *failrec, int fail_mirror);
544544
struct bio *btrfs_create_repair_bio(struct inode *inode, struct bio *failed_bio,
545545
struct io_failure_record *failrec,
546546
struct page *page, int pg_offset, int icsum,

fs/btrfs/inode.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8016,10 +8016,6 @@ static int dio_read_error(struct inode *inode, struct bio *failed_bio,
80168016
isector >>= inode->i_sb->s_blocksize_bits;
80178017
bio = btrfs_create_repair_bio(inode, failed_bio, failrec, page,
80188018
pgoff, isector, repair_endio, repair_arg);
8019-
if (!bio) {
8020-
free_io_failure(failure_tree, io_tree, failrec);
8021-
return -EIO;
8022-
}
80238019
bio_set_op_attrs(bio, REQ_OP_READ, read_mode);
80248020

80258021
btrfs_debug(BTRFS_I(inode)->root->fs_info,
@@ -8059,6 +8055,7 @@ static void btrfs_retry_endio_nocsum(struct bio *bio)
80598055
ASSERT(bio->bi_io_vec->bv_len == btrfs_inode_sectorsize(inode));
80608056

80618057
done->uptodate = 1;
8058+
ASSERT(!bio_flagged(bio, BIO_CLONED));
80628059
bio_for_each_segment_all(bvec, bio, i)
80638060
clean_io_failure(BTRFS_I(inode)->root->fs_info, failure_tree,
80648061
io_tree, done->start, bvec->bv_page,
@@ -8150,6 +8147,7 @@ static void btrfs_retry_endio(struct bio *bio)
81508147
io_tree = &BTRFS_I(inode)->io_tree;
81518148
failure_tree = &BTRFS_I(inode)->io_failure_tree;
81528149

8150+
ASSERT(!bio_flagged(bio, BIO_CLONED));
81538151
bio_for_each_segment_all(bvec, bio, i) {
81548152
ret = __readpage_endio_check(inode, io_bio, i, bvec->bv_page,
81558153
bvec->bv_offset, done->start,

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)