* [PATCH 1/2 for-4.19] nvmet: handle bio allocation failure
@ 2018-09-28 0:40 Sagi Grimberg
2018-09-28 15:16 ` Christoph Hellwig
0 siblings, 1 reply; 3+ messages in thread
From: Sagi Grimberg @ 2018-09-28 0:40 UTC (permalink / raw)
We cannot rely on bio_alloc to succeed, so we first allocate
the needed bios in a list, and only then submit all of them so
we can cleanup if something fails in the process of building
the chained bios.
Signed-off-by: Sagi Grimberg <sagi at grimberg.me>
---
drivers/nvme/target/io-cmd-bdev.c | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/target/io-cmd-bdev.c b/drivers/nvme/target/io-cmd-bdev.c
index 7bc9f6240432..0664e2049fa4 100644
--- a/drivers/nvme/target/io-cmd-bdev.c
+++ b/drivers/nvme/target/io-cmd-bdev.c
@@ -59,9 +59,10 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
{
int sg_cnt = req->sg_cnt;
struct bio *bio = &req->b.inline_bio;
+ struct bio_list list;
struct scatterlist *sg;
sector_t sector;
- blk_qc_t cookie;
+ blk_qc_t cookie = BLK_QC_T_NONE;
int op, op_flags = 0, i;
if (!req->sg_cnt) {
@@ -88,27 +89,39 @@ static void nvmet_bdev_execute_rw(struct nvmet_req *req)
bio->bi_end_io = nvmet_bio_done;
bio_set_op_attrs(bio, op, op_flags);
+ bio_list_init(&list);
for_each_sg(req->sg, sg, req->sg_cnt, i) {
while (bio_add_page(bio, sg_page(sg), sg->length, sg->offset)
!= sg->length) {
struct bio *prev = bio;
bio = bio_alloc(GFP_KERNEL, min(sg_cnt, BIO_MAX_PAGES));
+ if (unlikely(!bio))
+ goto err;
+
bio_set_dev(bio, req->ns->bdev);
bio->bi_iter.bi_sector = sector;
bio_set_op_attrs(bio, op, op_flags);
bio_chain(bio, prev);
- submit_bio(prev);
+ bio_list_add(&list, bio);
}
sector += sg->length >> 9;
sg_cnt--;
}
- cookie = submit_bio(bio);
+ bio_list_add(&list, bio);
+ while ((bio = bio_list_pop(&list)))
+ cookie = submit_bio(bio);
blk_poll(bdev_get_queue(req->ns->bdev), cookie);
+ return;
+err:
+ while ((bio = bio_list_pop(&list)))
+ if (bio != &req->b.inline_bio)
+ bio_put(bio);
+ nvmet_req_complete(req, NVME_SC_INTERNAL);
}
static void nvmet_bdev_execute_flush(struct nvmet_req *req)
--
2.17.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [PATCH 1/2 for-4.19] nvmet: handle bio allocation failure
2018-09-28 0:40 [PATCH 1/2 for-4.19] nvmet: handle bio allocation failure Sagi Grimberg
@ 2018-09-28 15:16 ` Christoph Hellwig
2018-09-28 22:41 ` Sagi Grimberg
0 siblings, 1 reply; 3+ messages in thread
From: Christoph Hellwig @ 2018-09-28 15:16 UTC (permalink / raw)
On Thu, Sep 27, 2018@05:40:56PM -0700, Sagi Grimberg wrote:
> We cannot rely on bio_alloc to succeed,
Yes, we can (unless it is an atomic allocation or it exceeds
BIO_MAX_PAGES, neither of which we do here).
^ permalink raw reply [flat|nested] 3+ messages in thread
* [PATCH 1/2 for-4.19] nvmet: handle bio allocation failure
2018-09-28 15:16 ` Christoph Hellwig
@ 2018-09-28 22:41 ` Sagi Grimberg
0 siblings, 0 replies; 3+ messages in thread
From: Sagi Grimberg @ 2018-09-28 22:41 UTC (permalink / raw)
>> We cannot rely on bio_alloc to succeed,
>
> Yes, we can (unless it is an atomic allocation or it exceeds
> BIO_MAX_PAGES, neither of which we do here).
Yea I see that now... lets drop this one...
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2018-09-28 22:41 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-09-28 0:40 [PATCH 1/2 for-4.19] nvmet: handle bio allocation failure Sagi Grimberg
2018-09-28 15:16 ` Christoph Hellwig
2018-09-28 22:41 ` Sagi Grimberg
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.