On Tue, 9 Jun 2026, Wentao Liang wrote:
> In log_writes_map(), when a discard bio is received and the device
> does not support discard, a pending block is allocated and its
> pending_blocks refcount is incremented, but the block is never
> freed. The function calls bio_endio(bio) and returns
> DM_MAPIO_SUBMITTED directly, bypassing normal_end_io() which would
Hi
Is this true? From my reading of the code, bio_endio calls clone_endio,
clone_endio calls ti->type->end_io (that is normal_end_io for
dm-log-writes), normal_end_io sees that bio_data_dir(bio) == WRITE
(discards are treated as write requests in bio_data_dir), pb->block is
non-NULL, so we grab spin_lock_irqsave(&lc->blocks_lock, flags); and add
pb->block to the queue.
Am I missing something?
Mikulas
> enqueue the block for later release via the kthread. As a result,
> the refcount for the associated pending block is leaked, and
> pending_blocks never reaches zero, preventing log_writes_dtr() from
> completing and causing the device destruction to hang.
>
> Free the block with free_pending_block() before completing the bio
> in the !device_supports_discard path, matching the error handling
> done when page allocation fails.
>
> Cc: [email protected]
> Fixes: 0e9cebe72459 ("dm: add log writes target")
> Signed-off-by: Wentao Liang <[email protected]>
> ---
> drivers/md/dm-log-writes.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/md/dm-log-writes.c b/drivers/md/dm-log-writes.c
> index c72e07c3f5a0..05133b1553ca 100644
> --- a/drivers/md/dm-log-writes.c
> +++ b/drivers/md/dm-log-writes.c
> @@ -709,6 +709,8 @@ static int log_writes_map(struct dm_target *ti, struct
> bio *bio)
> WARN_ON(flush_bio || fua_bio);
> if (lc->device_supports_discard)
> goto map_bio;
> + free_pending_block(lc, block);
> + pb->block = NULL;
> bio_endio(bio);
> return DM_MAPIO_SUBMITTED;
> }
> --
> 2.34.1
>