[ Upstream commit 510fd8ea98fcb586c01aef93d87c060a159ac30a ]

bio_add_pc_page() may merge pages when a bio is padded due to a flush.
Fix iteration over the bio to free the correct pages in case of a merge.

Signed-off-by: Heiner Litz <hl...@ucsc.edu>
Reviewed-by: Javier González <jav...@javigon.com>
Signed-off-by: Matias Bjørling <m...@lightnvm.io>
Signed-off-by: Jens Axboe <ax...@kernel.dk>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 drivers/lightnvm/pblk-core.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/lightnvm/pblk-core.c b/drivers/lightnvm/pblk-core.c
index 6ca868868fee..7393d64757a1 100644
--- a/drivers/lightnvm/pblk-core.c
+++ b/drivers/lightnvm/pblk-core.c
@@ -323,14 +323,16 @@ void pblk_free_rqd(struct pblk *pblk, struct nvm_rq *rqd, 
int type)
 void pblk_bio_free_pages(struct pblk *pblk, struct bio *bio, int off,
                         int nr_pages)
 {
-       struct bio_vec bv;
-       int i;
-
-       WARN_ON(off + nr_pages != bio->bi_vcnt);
-
-       for (i = off; i < nr_pages + off; i++) {
-               bv = bio->bi_io_vec[i];
-               mempool_free(bv.bv_page, &pblk->page_bio_pool);
+       struct bio_vec *bv;
+       struct page *page;
+       int i, e, nbv = 0;
+
+       for (i = 0; i < bio->bi_vcnt; i++) {
+               bv = &bio->bi_io_vec[i];
+               page = bv->bv_page;
+               for (e = 0; e < bv->bv_len; e += PBLK_EXPOSED_PAGE_SIZE, nbv++)
+                       if (nbv >= off)
+                               mempool_free(page++, &pblk->page_bio_pool);
        }
 }
 
-- 
2.20.1



Reply via email to