diff options
author | Igor Konopko <igor.j.konopko@intel.com> | 2019-05-04 20:38:03 +0200 |
---|---|---|
committer | Jens Axboe <axboe@kernel.dk> | 2019-05-06 18:19:18 +0200 |
commit | 1fc3b30569bc1087dc8c8b8eff27ca7727b807c4 (patch) | |
tree | 5fd5d77ce820e85d6e94920502fdcf87b651676b /drivers/lightnvm | |
parent | lightnvm: pblk: propagate errors when reading meta (diff) | |
download | linux-1fc3b30569bc1087dc8c8b8eff27ca7727b807c4.tar.xz linux-1fc3b30569bc1087dc8c8b8eff27ca7727b807c4.zip |
lightnvm: pblk: wait for inflight IOs in recovery
This patch changes the behaviour of recovery padding in order to
support a case, when some IOs were already submitted to the drive and
some next one are not submitted due to error returned.
Currently in case of errors we simply exit the pad function without
waiting for inflight IOs, which leads to panic on inflight IOs
completion.
After the changes we always wait for all the inflight IOs before
exiting the function.
Signed-off-by: Igor Konopko <igor.j.konopko@intel.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm')
-rw-r--r-- | drivers/lightnvm/pblk-recovery.c | 25 |
1 files changed, 12 insertions, 13 deletions
diff --git a/drivers/lightnvm/pblk-recovery.c b/drivers/lightnvm/pblk-recovery.c index 124d8179b2ad..137e963cd51d 100644 --- a/drivers/lightnvm/pblk-recovery.c +++ b/drivers/lightnvm/pblk-recovery.c @@ -208,7 +208,7 @@ next_pad_rq: rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false); if (rq_ppas < pblk->min_write_pgs) { pblk_err(pblk, "corrupted pad line %d\n", line->id); - goto fail_free_pad; + goto fail_complete; } rq_len = rq_ppas * geo->csecs; @@ -217,7 +217,7 @@ next_pad_rq: PBLK_VMALLOC_META, GFP_KERNEL); if (IS_ERR(bio)) { ret = PTR_ERR(bio); - goto fail_free_pad; + goto fail_complete; } bio->bi_iter.bi_sector = 0; /* internal bio */ @@ -226,8 +226,11 @@ next_pad_rq: rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT); ret = pblk_alloc_rqd_meta(pblk, rqd); - if (ret) - goto fail_free_rqd; + if (ret) { + pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT); + bio_put(bio); + goto fail_complete; + } rqd->bio = bio; rqd->opcode = NVM_OP_PWRITE; @@ -274,7 +277,10 @@ next_pad_rq: if (ret) { pblk_err(pblk, "I/O submission failed: %d\n", ret); pblk_up_chunk(pblk, rqd->ppa_list[0]); - goto fail_free_rqd; + kref_put(&pad_rq->ref, pblk_recov_complete); + pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT); + bio_put(bio); + goto fail_complete; } left_line_ppas -= rq_ppas; @@ -282,6 +288,7 @@ next_pad_rq: if (left_ppas && left_line_ppas) goto next_pad_rq; +fail_complete: kref_put(&pad_rq->ref, pblk_recov_complete); if (!wait_for_completion_io_timeout(&pad_rq->wait, @@ -297,14 +304,6 @@ next_pad_rq: free_rq: kfree(pad_rq); return ret; - -fail_free_rqd: - pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT); - bio_put(bio); -fail_free_pad: - kfree(pad_rq); - vfree(data); - return ret; } static int pblk_pad_distance(struct pblk *pblk, struct pblk_line *line) |