Skip to content

Commit ba88278

Browse files
adam900710kdave
authored andcommitted
btrfs: raid56: prepare rbio_bio_add_io_paddr() to support bs > ps cases
The function rbio_bio_add_io_paddr() assume each fs block can be mapped by one page, blocking bs > ps support for raid56. Prepare it for bs > ps cases by: - Introduce a helper bio_add_paddrs() Previously we only need to add a single page to a bio for a fs block, but now we need to add multiple pages, this means we can fail halfway. In that case we need to properly revert the bio (only for its size though) for halfway failed cases. - Rename rbio_add_io_paddr() to rbio_add_io_paddrs() And change the @paddr parameter to @paddrs[]. - Change all callers to use the updated rbio_add_io_paddrs() For the @paddrs pointer used for the new function, it can be grabbed using sector_paddrs_in_rbio() and rbio_stripe_paddrs() helpers. Signed-off-by: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
1 parent 53474a2 commit ba88278

1 file changed

Lines changed: 65 additions & 41 deletions

File tree

fs/btrfs/raid56.c

Lines changed: 65 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1245,17 +1245,41 @@ static int get_rbio_vertical_errors(struct btrfs_raid_bio *rbio, int sector_nr,
12451245
return found_errors;
12461246
}
12471247

1248+
static int bio_add_paddrs(struct bio *bio, phys_addr_t *paddrs, unsigned int nr_steps,
1249+
unsigned int step)
1250+
{
1251+
int added = 0;
1252+
int ret;
1253+
1254+
for (int i = 0; i < nr_steps; i++) {
1255+
ret = bio_add_page(bio, phys_to_page(paddrs[i]), step,
1256+
offset_in_page(paddrs[i]));
1257+
if (ret != step)
1258+
goto revert;
1259+
added += ret;
1260+
}
1261+
return added;
1262+
revert:
1263+
/*
1264+
* We don't need to revert the bvec, as the bio will be submitted immediately,
1265+
* as long as the size is reduced the extra bvec will not be accessed.
1266+
*/
1267+
bio->bi_iter.bi_size -= added;
1268+
return 0;
1269+
}
1270+
12481271
/*
12491272
* Add a single sector @sector into our list of bios for IO.
12501273
*
12511274
* Return 0 if everything went well.
1252-
* Return <0 for error.
1275+
* Return <0 for error, and no byte will be added to @rbio.
12531276
*/
1254-
static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_list,
1255-
phys_addr_t paddr, unsigned int stripe_nr,
1256-
unsigned int sector_nr, enum req_op op)
1277+
static int rbio_add_io_paddrs(struct btrfs_raid_bio *rbio, struct bio_list *bio_list,
1278+
phys_addr_t *paddrs, unsigned int stripe_nr,
1279+
unsigned int sector_nr, enum req_op op)
12571280
{
12581281
const u32 sectorsize = rbio->bioc->fs_info->sectorsize;
1282+
const u32 step = min(sectorsize, PAGE_SIZE);
12591283
struct bio *last = bio_list->tail;
12601284
int ret;
12611285
struct bio *bio;
@@ -1271,7 +1295,7 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
12711295
rbio, stripe_nr);
12721296
ASSERT_RBIO_SECTOR(sector_nr >= 0 && sector_nr < rbio->stripe_nsectors,
12731297
rbio, sector_nr);
1274-
ASSERT(paddr != INVALID_PADDR);
1298+
ASSERT(paddrs != NULL);
12751299

12761300
stripe = &rbio->bioc->stripes[stripe_nr];
12771301
disk_start = stripe->physical + sector_nr * sectorsize;
@@ -1302,8 +1326,7 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
13021326
*/
13031327
if (last_end == disk_start && !last->bi_status &&
13041328
last->bi_bdev == stripe->dev->bdev) {
1305-
ret = bio_add_page(last, phys_to_page(paddr), sectorsize,
1306-
offset_in_page(paddr));
1329+
ret = bio_add_paddrs(last, paddrs, rbio->sector_nsteps, step);
13071330
if (ret == sectorsize)
13081331
return 0;
13091332
}
@@ -1316,7 +1339,8 @@ static int rbio_add_io_paddr(struct btrfs_raid_bio *rbio, struct bio_list *bio_l
13161339
bio->bi_iter.bi_sector = disk_start >> SECTOR_SHIFT;
13171340
bio->bi_private = rbio;
13181341

1319-
__bio_add_page(bio, phys_to_page(paddr), sectorsize, offset_in_page(paddr));
1342+
ret = bio_add_paddrs(bio, paddrs, rbio->sector_nsteps, step);
1343+
ASSERT(ret == sectorsize);
13201344
bio_list_add(bio_list, bio);
13211345
return 0;
13221346
}
@@ -1497,7 +1521,7 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
14971521
*/
14981522
for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
14991523
total_sector_nr++) {
1500-
phys_addr_t paddr;
1524+
phys_addr_t *paddrs;
15011525

15021526
stripe = total_sector_nr / rbio->stripe_nsectors;
15031527
sectornr = total_sector_nr % rbio->stripe_nsectors;
@@ -1507,15 +1531,15 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15071531
continue;
15081532

15091533
if (stripe < rbio->nr_data) {
1510-
paddr = sector_paddr_in_rbio(rbio, stripe, sectornr, 1);
1511-
if (paddr == INVALID_PADDR)
1534+
paddrs = sector_paddrs_in_rbio(rbio, stripe, sectornr, 1);
1535+
if (paddrs == NULL)
15121536
continue;
15131537
} else {
1514-
paddr = rbio_stripe_paddr(rbio, stripe, sectornr);
1538+
paddrs = rbio_stripe_paddrs(rbio, stripe, sectornr);
15151539
}
15161540

1517-
ret = rbio_add_io_paddr(rbio, bio_list, paddr, stripe,
1518-
sectornr, REQ_OP_WRITE);
1541+
ret = rbio_add_io_paddrs(rbio, bio_list, paddrs, stripe,
1542+
sectornr, REQ_OP_WRITE);
15191543
if (ret)
15201544
goto error;
15211545
}
@@ -1532,7 +1556,7 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15321556

15331557
for (total_sector_nr = 0; total_sector_nr < rbio->nr_sectors;
15341558
total_sector_nr++) {
1535-
phys_addr_t paddr;
1559+
phys_addr_t *paddrs;
15361560

15371561
stripe = total_sector_nr / rbio->stripe_nsectors;
15381562
sectornr = total_sector_nr % rbio->stripe_nsectors;
@@ -1557,14 +1581,14 @@ static int rmw_assemble_write_bios(struct btrfs_raid_bio *rbio,
15571581
continue;
15581582

15591583
if (stripe < rbio->nr_data) {
1560-
paddr = sector_paddr_in_rbio(rbio, stripe, sectornr, 1);
1561-
if (paddr == INVALID_PADDR)
1584+
paddrs = sector_paddrs_in_rbio(rbio, stripe, sectornr, 1);
1585+
if (paddrs == NULL)
15621586
continue;
15631587
} else {
1564-
paddr = rbio_stripe_paddr(rbio, stripe, sectornr);
1588+
paddrs = rbio_stripe_paddrs(rbio, stripe, sectornr);
15651589
}
15661590

1567-
ret = rbio_add_io_paddr(rbio, bio_list, paddr,
1591+
ret = rbio_add_io_paddrs(rbio, bio_list, paddrs,
15681592
rbio->real_stripes,
15691593
sectornr, REQ_OP_WRITE);
15701594
if (ret)
@@ -2184,7 +2208,7 @@ static void recover_rbio(struct btrfs_raid_bio *rbio)
21842208
total_sector_nr++) {
21852209
int stripe = total_sector_nr / rbio->stripe_nsectors;
21862210
int sectornr = total_sector_nr % rbio->stripe_nsectors;
2187-
phys_addr_t paddr;
2211+
phys_addr_t *paddrs;
21882212

21892213
/*
21902214
* Skip the range which has error. It can be a range which is
@@ -2201,9 +2225,9 @@ static void recover_rbio(struct btrfs_raid_bio *rbio)
22012225
continue;
22022226
}
22032227

2204-
paddr = rbio_stripe_paddr(rbio, stripe, sectornr);
2205-
ret = rbio_add_io_paddr(rbio, &bio_list, paddr, stripe,
2206-
sectornr, REQ_OP_READ);
2228+
paddrs = rbio_stripe_paddrs(rbio, stripe, sectornr);
2229+
ret = rbio_add_io_paddrs(rbio, &bio_list, paddrs, stripe,
2230+
sectornr, REQ_OP_READ);
22072231
if (ret < 0) {
22082232
bio_list_put(&bio_list);
22092233
goto out;
@@ -2393,11 +2417,11 @@ static int rmw_read_wait_recover(struct btrfs_raid_bio *rbio)
23932417
total_sector_nr++) {
23942418
int stripe = total_sector_nr / rbio->stripe_nsectors;
23952419
int sectornr = total_sector_nr % rbio->stripe_nsectors;
2396-
phys_addr_t paddr;
2420+
phys_addr_t *paddrs;
23972421

2398-
paddr = rbio_stripe_paddr(rbio, stripe, sectornr);
2399-
ret = rbio_add_io_paddr(rbio, &bio_list, paddr, stripe,
2400-
sectornr, REQ_OP_READ);
2422+
paddrs = rbio_stripe_paddrs(rbio, stripe, sectornr);
2423+
ret = rbio_add_io_paddrs(rbio, &bio_list, paddrs, stripe,
2424+
sectornr, REQ_OP_READ);
24012425
if (ret) {
24022426
bio_list_put(&bio_list);
24032427
return ret;
@@ -2751,11 +2775,11 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
27512775
* everything else.
27522776
*/
27532777
for_each_set_bit(sectornr, &rbio->dbitmap, rbio->stripe_nsectors) {
2754-
phys_addr_t paddr;
2778+
phys_addr_t *paddrs;
27552779

2756-
paddr = rbio_stripe_paddr(rbio, rbio->scrubp, sectornr);
2757-
ret = rbio_add_io_paddr(rbio, &bio_list, paddr, rbio->scrubp,
2758-
sectornr, REQ_OP_WRITE);
2780+
paddrs = rbio_stripe_paddrs(rbio, rbio->scrubp, sectornr);
2781+
ret = rbio_add_io_paddrs(rbio, &bio_list, paddrs, rbio->scrubp,
2782+
sectornr, REQ_OP_WRITE);
27592783
if (ret)
27602784
goto cleanup;
27612785
}
@@ -2769,11 +2793,11 @@ static int finish_parity_scrub(struct btrfs_raid_bio *rbio)
27692793
*/
27702794
ASSERT_RBIO(rbio->bioc->replace_stripe_src >= 0, rbio);
27712795
for_each_set_bit(sectornr, pbitmap, rbio->stripe_nsectors) {
2772-
phys_addr_t paddr;
2796+
phys_addr_t *paddrs;
27732797

2774-
paddr = rbio_stripe_paddr(rbio, rbio->scrubp, sectornr);
2775-
ret = rbio_add_io_paddr(rbio, &bio_list, paddr, rbio->real_stripes,
2776-
sectornr, REQ_OP_WRITE);
2798+
paddrs = rbio_stripe_paddrs(rbio, rbio->scrubp, sectornr);
2799+
ret = rbio_add_io_paddrs(rbio, &bio_list, paddrs, rbio->real_stripes,
2800+
sectornr, REQ_OP_WRITE);
27772801
if (ret)
27782802
goto cleanup;
27792803
}
@@ -2889,7 +2913,7 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
28892913
total_sector_nr++) {
28902914
int sectornr = total_sector_nr % rbio->stripe_nsectors;
28912915
int stripe = total_sector_nr / rbio->stripe_nsectors;
2892-
phys_addr_t paddr;
2916+
phys_addr_t *paddrs;
28932917

28942918
/* No data in the vertical stripe, no need to read. */
28952919
if (!test_bit(sectornr, &rbio->dbitmap))
@@ -2900,11 +2924,11 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
29002924
* read them from the disk. If sector_paddr_in_rbio() finds a sector
29012925
* in the bio list we don't need to read it off the stripe.
29022926
*/
2903-
paddr = sector_paddr_in_rbio(rbio, stripe, sectornr, 1);
2904-
if (paddr == INVALID_PADDR)
2927+
paddrs = sector_paddrs_in_rbio(rbio, stripe, sectornr, 1);
2928+
if (paddrs == NULL)
29052929
continue;
29062930

2907-
paddr = rbio_stripe_paddr(rbio, stripe, sectornr);
2931+
paddrs = rbio_stripe_paddrs(rbio, stripe, sectornr);
29082932
/*
29092933
* The bio cache may have handed us an uptodate sector. If so,
29102934
* use it.
@@ -2913,8 +2937,8 @@ static int scrub_assemble_read_bios(struct btrfs_raid_bio *rbio)
29132937
rbio->stripe_uptodate_bitmap))
29142938
continue;
29152939

2916-
ret = rbio_add_io_paddr(rbio, &bio_list, paddr, stripe,
2917-
sectornr, REQ_OP_READ);
2940+
ret = rbio_add_io_paddrs(rbio, &bio_list, paddrs, stripe,
2941+
sectornr, REQ_OP_READ);
29182942
if (ret) {
29192943
bio_list_put(&bio_list);
29202944
return ret;

0 commit comments

Comments
 (0)