Commit 3e77605d authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

btrfs: raid56: make rbio_add_io_page() subpage compatible

Make rbio_add_io_page() subpage compatible, which involves:

- Rename rbio_add_io_page() to rbio_add_io_sector()
  Although we still rely on PAGE_SIZE == sectorsize, so add a new
  ASSERT() inside rbio_add_io_sector() to make sure all pgoff is 0.

- Introduce rbio_stripe_sector() helper
  The equivalent of rbio_stripe_page().

  This new helper has extra ASSERT()s to validate the stripe and sector
  number.

- Introduce sector_in_rbio() helper
  The equivalent of page_in_rbio().

- Rename @pagenr variables to @sectornr

- Use rbio::stripe_nsectors when iterating the bitmap

Please note that, this only changes the interface, the bios are still
using full page for IO.
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 00425dd9
...@@ -666,6 +666,25 @@ static int rbio_can_merge(struct btrfs_raid_bio *last, ...@@ -666,6 +666,25 @@ static int rbio_can_merge(struct btrfs_raid_bio *last,
return 1; return 1;
} }
static unsigned int rbio_stripe_sector_index(const struct btrfs_raid_bio *rbio,
unsigned int stripe_nr,
unsigned int sector_nr)
{
ASSERT(stripe_nr < rbio->real_stripes);
ASSERT(sector_nr < rbio->stripe_nsectors);
return stripe_nr * rbio->stripe_nsectors + sector_nr;
}
/* Return a sector from rbio->stripe_sectors, not from the bio list */
static struct sector_ptr *rbio_stripe_sector(const struct btrfs_raid_bio *rbio,
unsigned int stripe_nr,
unsigned int sector_nr)
{
return &rbio->stripe_sectors[rbio_stripe_sector_index(rbio, stripe_nr,
sector_nr)];
}
static int rbio_stripe_page_index(struct btrfs_raid_bio *rbio, int stripe, static int rbio_stripe_page_index(struct btrfs_raid_bio *rbio, int stripe,
int index) int index)
{ {
...@@ -977,6 +996,45 @@ static void raid_write_end_io(struct bio *bio) ...@@ -977,6 +996,45 @@ static void raid_write_end_io(struct bio *bio)
rbio_orig_end_io(rbio, err); rbio_orig_end_io(rbio, err);
} }
/**
* Get a sector pointer specified by its @stripe_nr and @sector_nr
*
* @rbio: The raid bio
* @stripe_nr: Stripe number, valid range [0, real_stripe)
* @sector_nr: Sector number inside the stripe,
* valid range [0, stripe_nsectors)
* @bio_list_only: Whether to use sectors inside the bio list only.
*
* The read/modify/write code wants to reuse the original bio page as much
* as possible, and only use stripe_sectors as fallback.
*/
static struct sector_ptr *sector_in_rbio(struct btrfs_raid_bio *rbio,
int stripe_nr, int sector_nr,
bool bio_list_only)
{
struct sector_ptr *sector;
int index;
ASSERT(stripe_nr >= 0 && stripe_nr < rbio->real_stripes);
ASSERT(sector_nr >= 0 && sector_nr < rbio->stripe_nsectors);
index = stripe_nr * rbio->stripe_nsectors + sector_nr;
ASSERT(index >= 0 && index < rbio->nr_sectors);
spin_lock_irq(&rbio->bio_list_lock);
sector = &rbio->bio_sectors[index];
if (sector->page || bio_list_only) {
/* Don't return sector without a valid page pointer */
if (!sector->page)
sector = NULL;
spin_unlock_irq(&rbio->bio_list_lock);
return sector;
}
spin_unlock_irq(&rbio->bio_list_lock);
return &rbio->stripe_sectors[index];
}
/* /*
* the read/modify/write code wants to use the original bio for * the read/modify/write code wants to use the original bio for
* any pages it included, and then use the rbio for everything * any pages it included, and then use the rbio for everything
...@@ -1119,26 +1177,40 @@ static int alloc_rbio_parity_pages(struct btrfs_raid_bio *rbio) ...@@ -1119,26 +1177,40 @@ static int alloc_rbio_parity_pages(struct btrfs_raid_bio *rbio)
} }
/* /*
* add a single page from a specific stripe into our list of bios for IO * Add a single sector @sector into our list of bios for IO.
* this will try to merge into existing bios if possible, and returns *
* zero if all went well. * Return 0 if everything went well.
* Return <0 for error.
*/ */
static int rbio_add_io_page(struct btrfs_raid_bio *rbio, static int rbio_add_io_sector(struct btrfs_raid_bio *rbio,
struct bio_list *bio_list, struct bio_list *bio_list,
struct page *page, struct sector_ptr *sector,
int stripe_nr, unsigned int stripe_nr,
unsigned long page_index, unsigned int sector_nr,
unsigned long bio_max_len, unsigned long bio_max_len,
unsigned int opf) unsigned int opf)
{ {
const u32 sectorsize = rbio->bioc->fs_info->sectorsize;
struct bio *last = bio_list->tail; struct bio *last = bio_list->tail;
int ret; int ret;
struct bio *bio; struct bio *bio;
struct btrfs_io_stripe *stripe; struct btrfs_io_stripe *stripe;
u64 disk_start; u64 disk_start;
/*
* Note: here stripe_nr has taken device replace into consideration,
* thus it can be larger than rbio->real_stripe.
* So here we check against bioc->num_stripes, not rbio->real_stripes.
*/
ASSERT(stripe_nr >= 0 && stripe_nr < rbio->bioc->num_stripes);
ASSERT(sector_nr >= 0 && sector_nr < rbio->stripe_nsectors);
ASSERT(sector->page);
/* We don't yet support subpage, thus pgoff should always be 0 */
ASSERT(sector->pgoff == 0);
stripe = &rbio->bioc->stripes[stripe_nr]; stripe = &rbio->bioc->stripes[stripe_nr];
disk_start = stripe->physical + (page_index << PAGE_SHIFT); disk_start = stripe->physical + sector_nr * sectorsize;
/* if the device is missing, just fail this stripe */ /* if the device is missing, just fail this stripe */
if (!stripe->dev->bdev) if (!stripe->dev->bdev)
...@@ -1155,8 +1227,9 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio, ...@@ -1155,8 +1227,9 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
*/ */
if (last_end == disk_start && !last->bi_status && if (last_end == disk_start && !last->bi_status &&
last->bi_bdev == stripe->dev->bdev) { last->bi_bdev == stripe->dev->bdev) {
ret = bio_add_page(last, page, PAGE_SIZE, 0); ret = bio_add_page(last, sector->page, sectorsize,
if (ret == PAGE_SIZE) sector->pgoff);
if (ret == sectorsize)
return 0; return 0;
} }
} }
...@@ -1167,7 +1240,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio, ...@@ -1167,7 +1240,7 @@ static int rbio_add_io_page(struct btrfs_raid_bio *rbio,
bio->bi_iter.bi_sector = disk_start >> 9; bio->bi_iter.bi_sector = disk_start >> 9;
bio->bi_private = rbio; bio->bi_private = rbio;
bio_add_page(bio, page, PAGE_SIZE, 0); bio_add_page(bio, sector->page, sectorsize, sector->pgoff);
bio_list_add(bio_list, bio); bio_list_add(bio_list, bio);
return 0; return 0;
} }
...@@ -1266,7 +1339,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1266,7 +1339,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
void **pointers = rbio->finish_pointers; void **pointers = rbio->finish_pointers;
int nr_data = rbio->nr_data; int nr_data = rbio->nr_data;
int stripe; int stripe;
int pagenr; int sectornr;
bool has_qstripe; bool has_qstripe;
struct bio_list bio_list; struct bio_list bio_list;
struct bio *bio; struct bio *bio;
...@@ -1310,16 +1383,16 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1310,16 +1383,16 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
else else
clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags); clear_bit(RBIO_CACHE_READY_BIT, &rbio->flags);
for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) { for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
struct page *p; struct page *p;
/* first collect one page from each data stripe */ /* first collect one page from each data stripe */
for (stripe = 0; stripe < nr_data; stripe++) { for (stripe = 0; stripe < nr_data; stripe++) {
p = page_in_rbio(rbio, stripe, pagenr, 0); p = page_in_rbio(rbio, stripe, sectornr, 0);
pointers[stripe] = kmap_local_page(p); pointers[stripe] = kmap_local_page(p);
} }
/* then add the parity stripe */ /* then add the parity stripe */
p = rbio_pstripe_page(rbio, pagenr); p = rbio_pstripe_page(rbio, sectornr);
SetPageUptodate(p); SetPageUptodate(p);
pointers[stripe++] = kmap_local_page(p); pointers[stripe++] = kmap_local_page(p);
...@@ -1329,7 +1402,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1329,7 +1402,7 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
* raid6, add the qstripe and call the * raid6, add the qstripe and call the
* library function to fill in our p/q * library function to fill in our p/q
*/ */
p = rbio_qstripe_page(rbio, pagenr); p = rbio_qstripe_page(rbio, sectornr);
SetPageUptodate(p); SetPageUptodate(p);
pointers[stripe++] = kmap_local_page(p); pointers[stripe++] = kmap_local_page(p);
...@@ -1350,19 +1423,20 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1350,19 +1423,20 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
* everything else. * everything else.
*/ */
for (stripe = 0; stripe < rbio->real_stripes; stripe++) { for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) { for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
struct page *page; struct sector_ptr *sector;
if (stripe < rbio->nr_data) { if (stripe < rbio->nr_data) {
page = page_in_rbio(rbio, stripe, pagenr, 1); sector = sector_in_rbio(rbio, stripe, sectornr, 1);
if (!page) if (!sector)
continue; continue;
} else { } else {
page = rbio_stripe_page(rbio, stripe, pagenr); sector = rbio_stripe_sector(rbio, stripe, sectornr);
} }
ret = rbio_add_io_page(rbio, &bio_list, ret = rbio_add_io_sector(rbio, &bio_list, sector, stripe,
page, stripe, pagenr, rbio->stripe_len, sectornr, rbio->stripe_len,
REQ_OP_WRITE); REQ_OP_WRITE);
if (ret) if (ret)
goto cleanup; goto cleanup;
} }
...@@ -1375,19 +1449,20 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1375,19 +1449,20 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
if (!bioc->tgtdev_map[stripe]) if (!bioc->tgtdev_map[stripe])
continue; continue;
for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) { for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
struct page *page; struct sector_ptr *sector;
if (stripe < rbio->nr_data) { if (stripe < rbio->nr_data) {
page = page_in_rbio(rbio, stripe, pagenr, 1); sector = sector_in_rbio(rbio, stripe, sectornr, 1);
if (!page) if (!sector)
continue; continue;
} else { } else {
page = rbio_stripe_page(rbio, stripe, pagenr); sector = rbio_stripe_sector(rbio, stripe, sectornr);
} }
ret = rbio_add_io_page(rbio, &bio_list, page, ret = rbio_add_io_sector(rbio, &bio_list, sector,
rbio->bioc->tgtdev_map[stripe], rbio->bioc->tgtdev_map[stripe],
pagenr, rbio->stripe_len, sectornr, rbio->stripe_len,
REQ_OP_WRITE); REQ_OP_WRITE);
if (ret) if (ret)
goto cleanup; goto cleanup;
...@@ -1564,7 +1639,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio) ...@@ -1564,7 +1639,7 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
int bios_to_read = 0; int bios_to_read = 0;
struct bio_list bio_list; struct bio_list bio_list;
int ret; int ret;
int pagenr; int sectornr;
int stripe; int stripe;
struct bio *bio; struct bio *bio;
...@@ -1582,28 +1657,29 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio) ...@@ -1582,28 +1657,29 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
* stripe * stripe
*/ */
for (stripe = 0; stripe < rbio->nr_data; stripe++) { for (stripe = 0; stripe < rbio->nr_data; stripe++) {
for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) { for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
struct page *page; struct sector_ptr *sector;
/* /*
* we want to find all the pages missing from * We want to find all the sectors missing from the
* the rbio and read them from the disk. If * rbio and read them from the disk. If * sector_in_rbio()
* page_in_rbio finds a page in the bio list * finds a page in the bio list we don't need to read
* we don't need to read it off the stripe. * it off the stripe.
*/ */
page = page_in_rbio(rbio, stripe, pagenr, 1); sector = sector_in_rbio(rbio, stripe, sectornr, 1);
if (page) if (sector)
continue; continue;
page = rbio_stripe_page(rbio, stripe, pagenr); sector = rbio_stripe_sector(rbio, stripe, sectornr);
/* /*
* the bio cache may have handed us an uptodate * The bio cache may have handed us an uptodate page.
* page. If so, be happy and use it * If so, be happy and use it.
*/ */
if (PageUptodate(page)) if (sector->uptodate)
continue; continue;
ret = rbio_add_io_page(rbio, &bio_list, page, ret = rbio_add_io_sector(rbio, &bio_list, sector,
stripe, pagenr, rbio->stripe_len, stripe, sectornr, rbio->stripe_len,
REQ_OP_READ); REQ_OP_READ);
if (ret) if (ret)
goto cleanup; goto cleanup;
...@@ -2107,7 +2183,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) ...@@ -2107,7 +2183,7 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
int bios_to_read = 0; int bios_to_read = 0;
struct bio_list bio_list; struct bio_list bio_list;
int ret; int ret;
int pagenr; int sectornr;
int stripe; int stripe;
struct bio *bio; struct bio *bio;
...@@ -2130,21 +2206,20 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) ...@@ -2130,21 +2206,20 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
continue; continue;
} }
for (pagenr = 0; pagenr < rbio->stripe_npages; pagenr++) { for (sectornr = 0; sectornr < rbio->stripe_nsectors; sectornr++) {
struct page *p; struct sector_ptr *sector;
/* /*
* the rmw code may have already read this * the rmw code may have already read this
* page in * page in
*/ */
p = rbio_stripe_page(rbio, stripe, pagenr); sector = rbio_stripe_sector(rbio, stripe, sectornr);
if (PageUptodate(p)) if (sector->uptodate)
continue; continue;
ret = rbio_add_io_page(rbio, &bio_list, ret = rbio_add_io_sector(rbio, &bio_list, sector,
rbio_stripe_page(rbio, stripe, pagenr), stripe, sectornr, rbio->stripe_len,
stripe, pagenr, rbio->stripe_len, REQ_OP_READ);
REQ_OP_READ);
if (ret < 0) if (ret < 0)
goto cleanup; goto cleanup;
} }
...@@ -2399,7 +2474,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2399,7 +2474,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
unsigned long *pbitmap = rbio->finish_pbitmap; unsigned long *pbitmap = rbio->finish_pbitmap;
int nr_data = rbio->nr_data; int nr_data = rbio->nr_data;
int stripe; int stripe;
int pagenr; int sectornr;
bool has_qstripe; bool has_qstripe;
struct page *p_page = NULL; struct page *p_page = NULL;
struct page *q_page = NULL; struct page *q_page = NULL;
...@@ -2419,7 +2494,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2419,7 +2494,7 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
if (bioc->num_tgtdevs && bioc->tgtdev_map[rbio->scrubp]) { if (bioc->num_tgtdevs && bioc->tgtdev_map[rbio->scrubp]) {
is_replace = 1; is_replace = 1;
bitmap_copy(pbitmap, rbio->dbitmap, rbio->stripe_npages); bitmap_copy(pbitmap, rbio->dbitmap, rbio->stripe_nsectors);
} }
/* /*
...@@ -2453,12 +2528,12 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2453,12 +2528,12 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
/* Map the parity stripe just once */ /* Map the parity stripe just once */
pointers[nr_data] = kmap_local_page(p_page); pointers[nr_data] = kmap_local_page(p_page);
for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { for_each_set_bit(sectornr, rbio->dbitmap, rbio->stripe_nsectors) {
struct page *p; struct page *p;
void *parity; void *parity;
/* first collect one page from each data stripe */ /* first collect one page from each data stripe */
for (stripe = 0; stripe < nr_data; stripe++) { for (stripe = 0; stripe < nr_data; stripe++) {
p = page_in_rbio(rbio, stripe, pagenr, 0); p = page_in_rbio(rbio, stripe, sectornr, 0);
pointers[stripe] = kmap_local_page(p); pointers[stripe] = kmap_local_page(p);
} }
...@@ -2473,13 +2548,13 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2473,13 +2548,13 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
} }
/* Check scrubbing parity and repair it */ /* Check scrubbing parity and repair it */
p = rbio_stripe_page(rbio, rbio->scrubp, pagenr); p = rbio_stripe_page(rbio, rbio->scrubp, sectornr);
parity = kmap_local_page(p); parity = kmap_local_page(p);
if (memcmp(parity, pointers[rbio->scrubp], PAGE_SIZE)) if (memcmp(parity, pointers[rbio->scrubp], PAGE_SIZE))
copy_page(parity, pointers[rbio->scrubp]); copy_page(parity, pointers[rbio->scrubp]);
else else
/* Parity is right, needn't writeback */ /* Parity is right, needn't writeback */
bitmap_clear(rbio->dbitmap, pagenr, 1); bitmap_clear(rbio->dbitmap, sectornr, 1);
kunmap_local(parity); kunmap_local(parity);
for (stripe = nr_data - 1; stripe >= 0; stripe--) for (stripe = nr_data - 1; stripe >= 0; stripe--)
...@@ -2499,12 +2574,12 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2499,12 +2574,12 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
* higher layers (the bio_list in our rbio) and our p/q. Ignore * higher layers (the bio_list in our rbio) and our p/q. Ignore
* everything else. * everything else.
*/ */
for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { for_each_set_bit(sectornr, rbio->dbitmap, rbio->stripe_nsectors) {
struct page *page; struct sector_ptr *sector;
page = rbio_stripe_page(rbio, rbio->scrubp, pagenr); sector = rbio_stripe_sector(rbio, rbio->scrubp, sectornr);
ret = rbio_add_io_page(rbio, &bio_list, page, rbio->scrubp, ret = rbio_add_io_sector(rbio, &bio_list, sector, rbio->scrubp,
pagenr, rbio->stripe_len, REQ_OP_WRITE); sectornr, rbio->stripe_len, REQ_OP_WRITE);
if (ret) if (ret)
goto cleanup; goto cleanup;
} }
...@@ -2512,13 +2587,13 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2512,13 +2587,13 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
if (!is_replace) if (!is_replace)
goto submit_write; goto submit_write;
for_each_set_bit(pagenr, pbitmap, rbio->stripe_npages) { for_each_set_bit(sectornr, pbitmap, rbio->stripe_nsectors) {
struct page *page; struct sector_ptr *sector;
page = rbio_stripe_page(rbio, rbio->scrubp, pagenr); sector = rbio_stripe_sector(rbio, rbio->scrubp, sectornr);
ret = rbio_add_io_page(rbio, &bio_list, page, ret = rbio_add_io_sector(rbio, &bio_list, sector,
bioc->tgtdev_map[rbio->scrubp], bioc->tgtdev_map[rbio->scrubp],
pagenr, rbio->stripe_len, REQ_OP_WRITE); sectornr, rbio->stripe_len, REQ_OP_WRITE);
if (ret) if (ret)
goto cleanup; goto cleanup;
} }
...@@ -2650,7 +2725,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) ...@@ -2650,7 +2725,7 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
int bios_to_read = 0; int bios_to_read = 0;
struct bio_list bio_list; struct bio_list bio_list;
int ret; int ret;
int pagenr; int sectornr;
int stripe; int stripe;
struct bio *bio; struct bio *bio;
...@@ -2666,28 +2741,29 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) ...@@ -2666,28 +2741,29 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
* stripe * stripe
*/ */
for (stripe = 0; stripe < rbio->real_stripes; stripe++) { for (stripe = 0; stripe < rbio->real_stripes; stripe++) {
for_each_set_bit(pagenr, rbio->dbitmap, rbio->stripe_npages) { for_each_set_bit(sectornr , rbio->dbitmap, rbio->stripe_nsectors) {
struct page *page; struct sector_ptr *sector;
/* /*
* we want to find all the pages missing from * We want to find all the sectors missing from the
* the rbio and read them from the disk. If * rbio and read them from the disk. If * sector_in_rbio()
* page_in_rbio finds a page in the bio list * finds a sector in the bio list we don't need to read
* we don't need to read it off the stripe. * it off the stripe.
*/ */
page = page_in_rbio(rbio, stripe, pagenr, 1); sector = sector_in_rbio(rbio, stripe, sectornr, 1);
if (page) if (sector)
continue; continue;
page = rbio_stripe_page(rbio, stripe, pagenr); sector = rbio_stripe_sector(rbio, stripe, sectornr);
/* /*
* the bio cache may have handed us an uptodate * The bio cache may have handed us an uptodate sector.
* page. If so, be happy and use it * If so, be happy and use it.
*/ */
if (PageUptodate(page)) if (sector->uptodate)
continue; continue;
ret = rbio_add_io_page(rbio, &bio_list, page, stripe, ret = rbio_add_io_sector(rbio, &bio_list, sector,
pagenr, rbio->stripe_len, REQ_OP_READ); stripe, sectornr, rbio->stripe_len,
REQ_OP_READ);
if (ret) if (ret)
goto cleanup; goto cleanup;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment