Commit 1fc3b305 authored by Igor Konopko's avatar Igor Konopko Committed by Jens Axboe
Browse files

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: default avatarIgor Konopko <igor.j.konopko@intel.com>
Signed-off-by: default avatarMatias Bjørling <mb@lightnvm.io>
Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
parent d165a7a6
Loading
Loading
Loading
Loading
+12 −13
Original line number Diff line number Diff line
@@ -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);
	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 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
						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 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
	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 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
	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 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
	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 @@ static int pblk_recov_pad_line(struct pblk *pblk, struct pblk_line *line,
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)