summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/md/dm-rq.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
index 29a09452abc4..2689f4213d7d 100644
--- a/drivers/md/dm-rq.c
+++ b/drivers/md/dm-rq.c
@@ -110,14 +110,21 @@ static void end_clone_bio(struct bio *clone)
*/
tio->completed += nr_bytes;
+ if (!is_last)
+ return;
+ /*
+ * At this moment we know this is the last bio of the cloned request,
+ * and all cloned bios have been released, so reset the clone request's
+ * bio pointer to avoid double free.
+ */
+ tio->clone->bio = NULL;
+ exit:
/*
* Update the original request.
* Do not use blk_mq_end_request() here, because it may complete
* the original request before the clone, and break the ordering.
*/
- if (is_last)
- exit:
- blk_update_request(tio->orig, BLK_STS_OK, tio->completed);
+ blk_update_request(tio->orig, BLK_STS_OK, tio->completed);
}
static struct dm_rq_target_io *tio_from_request(struct request *rq)