Skip to content

Commit 7dd06a2

Browse files
author
Mike Snitzer
committed
dm: allow dm_accept_partial_bio() for dm_io without duplicate bios
The intent behind commit e6fc9f6 ("dm: flag clones created by __send_duplicate_bios") was to formally disallow the use of dm_accept_partial_bio() where it simply isn't possible -- due to constraint that multiple bios cannot meaningfully update a shared tio->len_ptr. But that commit went too far and disallowed the case where "abormal" IO (e.g. WRITE_ZEROES) is only using a single bio. Fix this by not marking a dm_io with a single dm_target_io (and bio), that happens to be created by __send_duplicate_bios, as DM_TIO_IS_DUPLICATE_BIO. Also remove 'unsigned *len' parameter from alloc_multiple_bios(). This commit fixes a dm_accept_partial_bio() BUG_ON() with dm-zoned when a WRITE_ZEROES bio is issued. Fixes: 655f3aa ("dm: switch dm_target_io booleans over to proper flags") Reported-by: Shinichiro Kawasaki <[email protected]> Reviewed-by: Damien Le Moal <[email protected]> Signed-off-by: Mike Snitzer <[email protected]>
1 parent 73d7b06 commit 7dd06a2

File tree

1 file changed

+6
-11
lines changed

1 file changed

+6
-11
lines changed

drivers/md/dm.c

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,8 +1323,7 @@ static void __map_bio(struct bio *clone)
13231323
}
13241324

13251325
static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
1326-
struct dm_target *ti, unsigned num_bios,
1327-
unsigned *len)
1326+
struct dm_target *ti, unsigned num_bios)
13281327
{
13291328
struct bio *bio;
13301329
int try;
@@ -1335,7 +1334,7 @@ static void alloc_multiple_bios(struct bio_list *blist, struct clone_info *ci,
13351334
if (try)
13361335
mutex_lock(&ci->io->md->table_devices_lock);
13371336
for (bio_nr = 0; bio_nr < num_bios; bio_nr++) {
1338-
bio = alloc_tio(ci, ti, bio_nr, len,
1337+
bio = alloc_tio(ci, ti, bio_nr, NULL,
13391338
try ? GFP_NOIO : GFP_NOWAIT);
13401339
if (!bio)
13411340
break;
@@ -1363,11 +1362,11 @@ static void __send_duplicate_bios(struct clone_info *ci, struct dm_target *ti,
13631362
break;
13641363
case 1:
13651364
clone = alloc_tio(ci, ti, 0, len, GFP_NOIO);
1366-
dm_tio_set_flag(clone_to_tio(clone), DM_TIO_IS_DUPLICATE_BIO);
13671365
__map_bio(clone);
13681366
break;
13691367
default:
1370-
alloc_multiple_bios(&blist, ci, ti, num_bios, len);
1368+
/* dm_accept_partial_bio() is not supported with shared tio->len_ptr */
1369+
alloc_multiple_bios(&blist, ci, ti, num_bios);
13711370
while ((clone = bio_list_pop(&blist))) {
13721371
dm_tio_set_flag(clone_to_tio(clone), DM_TIO_IS_DUPLICATE_BIO);
13731372
__map_bio(clone);
@@ -1407,14 +1406,10 @@ static void __send_changing_extent_only(struct clone_info *ci, struct dm_target
14071406
len = min_t(sector_t, ci->sector_count,
14081407
max_io_len_target_boundary(ti, dm_target_offset(ti, ci->sector)));
14091408

1410-
/*
1411-
* dm_accept_partial_bio cannot be used with duplicate bios,
1412-
* so update clone_info cursor before __send_duplicate_bios().
1413-
*/
1409+
__send_duplicate_bios(ci, ti, num_bios, &len);
1410+
14141411
ci->sector += len;
14151412
ci->sector_count -= len;
1416-
1417-
__send_duplicate_bios(ci, ti, num_bios, &len);
14181413
}
14191414

14201415
static bool is_abnormal_io(struct bio *bio)

0 commit comments

Comments
 (0)