mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-21 08:19:28 +00:00
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>
This commit is contained in:
parent
d165a7a6f5
commit
1fc3b30569
1 changed files with 12 additions and 13 deletions
|
@ -208,7 +208,7 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
|
rq_ppas = pblk_calc_secs(pblk, left_ppas, 0, false);
|
||||||
if (rq_ppas < pblk->min_write_pgs) {
|
if (rq_ppas < pblk->min_write_pgs) {
|
||||||
pblk_err(pblk, "corrupted pad line %d\n", line->id);
|
pblk_err(pblk, "corrupted pad line %d\n", line->id);
|
||||||
goto fail_free_pad;
|
goto fail_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
rq_len = rq_ppas * geo->csecs;
|
rq_len = rq_ppas * geo->csecs;
|
||||||
|
@ -217,7 +217,7 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
PBLK_VMALLOC_META, GFP_KERNEL);
|
PBLK_VMALLOC_META, GFP_KERNEL);
|
||||||
if (IS_ERR(bio)) {
|
if (IS_ERR(bio)) {
|
||||||
ret = PTR_ERR(bio);
|
ret = PTR_ERR(bio);
|
||||||
goto fail_free_pad;
|
goto fail_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
bio->bi_iter.bi_sector = 0; /* internal bio */
|
bio->bi_iter.bi_sector = 0; /* internal bio */
|
||||||
|
@ -226,8 +226,11 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
|
rqd = pblk_alloc_rqd(pblk, PBLK_WRITE_INT);
|
||||||
|
|
||||||
ret = pblk_alloc_rqd_meta(pblk, rqd);
|
ret = pblk_alloc_rqd_meta(pblk, rqd);
|
||||||
if (ret)
|
if (ret) {
|
||||||
goto fail_free_rqd;
|
pblk_free_rqd(pblk, rqd, PBLK_WRITE_INT);
|
||||||
|
bio_put(bio);
|
||||||
|
goto fail_complete;
|
||||||
|
}
|
||||||
|
|
||||||
rqd->bio = bio;
|
rqd->bio = bio;
|
||||||
rqd->opcode = NVM_OP_PWRITE;
|
rqd->opcode = NVM_OP_PWRITE;
|
||||||
|
@ -274,7 +277,10 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pblk_err(pblk, "I/O submission failed: %d\n", ret);
|
pblk_err(pblk, "I/O submission failed: %d\n", ret);
|
||||||
pblk_up_chunk(pblk, rqd->ppa_list[0]);
|
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;
|
left_line_ppas -= rq_ppas;
|
||||||
|
@ -282,6 +288,7 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
if (left_ppas && left_line_ppas)
|
if (left_ppas && left_line_ppas)
|
||||||
goto next_pad_rq;
|
goto next_pad_rq;
|
||||||
|
|
||||||
|
fail_complete:
|
||||||
kref_put(&pad_rq->ref, pblk_recov_complete);
|
kref_put(&pad_rq->ref, pblk_recov_complete);
|
||||||
|
|
||||||
if (!wait_for_completion_io_timeout(&pad_rq->wait,
|
if (!wait_for_completion_io_timeout(&pad_rq->wait,
|
||||||
|
@ -297,14 +304,6 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
|
||||||
free_rq:
|
free_rq:
|
||||||
kfree(pad_rq);
|
kfree(pad_rq);
|
||||||
return ret;
|
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)
|
static int pblk_pad_distance(struct pblk *pblk, struct pblk_line *line)
|
||||||
|
|
Loading…
Reference in a new issue