diff options
Diffstat (limited to 'drivers/md/dm-rq.c')
| -rw-r--r-- | drivers/md/dm-rq.c | 13 |
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) |
