summaryrefslogtreecommitdiff
path: root/drivers/lightnvm/pblk-write.c
diff options
context:
space:
mode:
authorJavier González <jg@lightnvm.io>2017-06-26 11:57:29 +0200
committerJens Axboe <axboe@kernel.dk>2017-06-26 16:27:39 -0600
commit588726d3ec68b66be2e2881d2b85060ff383078a (patch)
tree3e0775b496dea2ea0cb676280e924df027400df5 /drivers/lightnvm/pblk-write.c
parentef5764946b1314e0aa1ab261493de6b9aa482ff9 (diff)
lightnvm: pblk: fail gracefully on irrec. error
Due to user writes being decoupled from media writes because of the need of an intermediate write buffer, irrecoverable media write errors lead to pblk stalling; user writes fill up the buffer and end up in an infinite retry loop. In order to let user writes fail gracefully, it is necessary for pblk to keep track of its own internal state and prevent further writes from being placed into the write buffer. This patch implements a state machine to keep track of internal errors and, in case of failure, fail further user writes in an standard way. Depending on the type of error, pblk will do its best to persist buffered writes (which are already acknowledged) and close down on a graceful manner. This way, data might be recovered by re-instantiating pblk. Such state machine paves out the way for a state-based FTL log. Signed-off-by: Javier González <javier@cnexlabs.com> Signed-off-by: Matias Bjørling <matias@cnexlabs.com> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'drivers/lightnvm/pblk-write.c')
-rw-r--r--drivers/lightnvm/pblk-write.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/drivers/lightnvm/pblk-write.c b/drivers/lightnvm/pblk-write.c
index f071fb79e199..3e0b84937b90 100644
--- a/drivers/lightnvm/pblk-write.c
+++ b/drivers/lightnvm/pblk-write.c
@@ -171,6 +171,7 @@ static void pblk_end_io_write(struct nvm_rq *rqd)
#endif
pblk_complete_write(pblk, rqd, c_ctx);
+ atomic_dec(&pblk->inflight_io);
}
static void pblk_end_io_write_meta(struct nvm_rq *rqd)
@@ -203,6 +204,8 @@ static void pblk_end_io_write_meta(struct nvm_rq *rqd)
bio_put(rqd->bio);
pblk_free_rqd(pblk, rqd, READ);
+
+ atomic_dec(&pblk->inflight_io);
}
static int pblk_alloc_w_rq(struct pblk *pblk, struct nvm_rq *rqd,
@@ -254,7 +257,7 @@ static int pblk_setup_w_rq(struct pblk *pblk, struct nvm_rq *rqd,
return ret;
}
- if (likely(!atomic_read(&e_line->left_eblks) || !e_line))
+ if (likely(!e_line || !atomic_read(&e_line->left_eblks)))
pblk_map_rq(pblk, rqd, c_ctx->sentry, lun_bitmap, valid, 0);
else
pblk_map_erase_rq(pblk, rqd, c_ctx->sentry, lun_bitmap,