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
> 


Reply via email to