Skip to content

Commit ca52248

Browse files
author
Mike Snitzer
committed
dm: pass NULL bdev to bio_alloc_clone
Most DM targets will remap the clone bio passed to their ->map function using bio_set_bdev(). So this change to pass NULL bdev to bio_alloc_clone avoids clone-time work that sets up resources for a bdev association that will not be used in practice (e.g. clone issued to underlying device will not use DM device's blk-cgroups resources). But clone->bi_bdev is still initialized following bio_alloc_clone to preserve DM target expectations that clone->bi_bdev will be set. Follow-up work is needed to audit DM targets to remove accesses to a clone->bi_bdev that the target didn't initialize with bio_set_dev(). Depends-on: 7ecc56c ("block: allow passing a NULL bdev to bio_alloc_clone/bio_init_clone") Signed-off-by: Mike Snitzer <[email protected]>
1 parent d254c36 commit ca52248

File tree

1 file changed

+24
-16
lines changed

1 file changed

+24
-16
lines changed

drivers/md/dm.c

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,9 @@ static struct dm_io *alloc_io(struct mapped_device *md, struct bio *bio)
581581
struct dm_target_io *tio;
582582
struct bio *clone;
583583

584-
clone = bio_alloc_clone(bio->bi_bdev, bio, GFP_NOIO, &md->io_bs);
584+
clone = bio_alloc_clone(NULL, bio, GFP_NOIO, &md->io_bs);
585+
/* Set default bdev, but target must bio_set_dev() before issuing IO */
586+
clone->bi_bdev = md->disk->part0;
585587

586588
tio = clone_to_tio(clone);
587589
tio->flags = 0;
@@ -613,7 +615,7 @@ static void free_io(struct dm_io *io)
613615
}
614616

615617
static struct bio *alloc_tio(struct clone_info *ci, struct dm_target *ti,
616-
unsigned target_bio_nr, unsigned *len, gfp_t gfp_mask)
618+
unsigned target_bio_nr, unsigned *len, gfp_t gfp_mask)
617619
{
618620
struct dm_target_io *tio;
619621
struct bio *clone;
@@ -624,10 +626,13 @@ static struct bio *alloc_tio(struct clone_info *ci, struct dm_target *ti,
624626
/* alloc_io() already initialized embedded clone */
625627
clone = &tio->clone;
626628
} else {
627-
clone = bio_alloc_clone(ci->bio->bi_bdev, ci->bio,
628-
gfp_mask, &ci->io->md->bs);
629+
struct mapped_device *md = ci->io->md;
630+
631+
clone = bio_alloc_clone(NULL, ci->bio, gfp_mask, &md->bs);
629632
if (!clone)
630633
return NULL;
634+
/* Set default bdev, but target must bio_set_dev() before issuing IO */
635+
clone->bi_bdev = md->disk->part0;
631636

632637
/* REQ_DM_POLL_LIST shouldn't be inherited */
633638
clone->bi_opf &= ~REQ_DM_POLL_LIST;
@@ -1012,25 +1017,28 @@ static bool swap_bios_limit(struct dm_target *ti, struct bio *bio)
10121017
static void clone_endio(struct bio *bio)
10131018
{
10141019
blk_status_t error = bio->bi_status;
1015-
struct request_queue *q = bio->bi_bdev->bd_disk->queue;
10161020
struct dm_target_io *tio = clone_to_tio(bio);
10171021
struct dm_target *ti = tio->ti;
10181022
dm_endio_fn endio = ti->type->end_io;
10191023
struct dm_io *io = tio->io;
10201024
struct mapped_device *md = io->md;
10211025

1022-
if (unlikely(error == BLK_STS_TARGET)) {
1023-
if (bio_op(bio) == REQ_OP_DISCARD &&
1024-
!bdev_max_discard_sectors(bio->bi_bdev))
1025-
disable_discard(md);
1026-
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
1027-
!q->limits.max_write_zeroes_sectors)
1028-
disable_write_zeroes(md);
1029-
}
1026+
if (likely(bio->bi_bdev != md->disk->part0)) {
1027+
struct request_queue *q = bdev_get_queue(bio->bi_bdev);
10301028

1031-
if (static_branch_unlikely(&zoned_enabled) &&
1032-
unlikely(blk_queue_is_zoned(q)))
1033-
dm_zone_endio(io, bio);
1029+
if (unlikely(error == BLK_STS_TARGET)) {
1030+
if (bio_op(bio) == REQ_OP_DISCARD &&
1031+
!bdev_max_discard_sectors(bio->bi_bdev))
1032+
disable_discard(md);
1033+
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
1034+
!q->limits.max_write_zeroes_sectors)
1035+
disable_write_zeroes(md);
1036+
}
1037+
1038+
if (static_branch_unlikely(&zoned_enabled) &&
1039+
unlikely(blk_queue_is_zoned(q)))
1040+
dm_zone_endio(io, bio);
1041+
}
10341042

10351043
if (endio) {
10361044
int r = endio(ti, bio, &error);

0 commit comments

Comments
 (0)