Re: [PATCH for-next v3 5/5] null_blk: do partial IO for bad blocks

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 1/15/25 1:29 PM, Shin'ichiro Kawasaki wrote:
> The current null_blk implementation checks if any bad blocks exist in
> the target blocks of each IO. If so, the IO fails and data is not
> transferred for all of the IO target blocks. However, when real storage
> devices have bad blocks, the devices may transfer data partially up to
> the first bad blocks (e.g., SAS drives). Especially, when the IO is a
> write operation, such partial IO leaves partially written data on the
> device.
> 
> To simulate such partial IO using null_blk, introduce the new parameter
> 'badblocks_partial_io'. When this parameter is set,
> null_handle_badblocks() returns the number of the sectors for the
> partial IO as its third pointer argument. Pass the returned number of
> sectors to the following calls to null_handle_memory_backend() in
> null_process_cmd() and null_zone_write().
> 
> Signed-off-by: Shin'ichiro Kawasaki <shinichiro.kawasaki@xxxxxxx>

A couple of nits below. Otherwise looks OK to me.

Reviewed-by: Damien Le Moal <dlemoal@xxxxxxxxxx>


> +/*
> + * Check if the command should fail for the badblocks. If so, return
> + * BLK_STS_IOERR and return number of partial I/O sectors.

...and return the number of sectors that were read or written, which may be less
than the requested number of sectors.

> + *
> + * @cmd:        The command to handle.
> + * @sector:     The start sector for I/O.
> + * @nr_sectors: The caller specifies number of sectors to write or read.
> + *              Returns number of sectors to be written or read for partial I/O.

@nr_sectors: Specifies number of sectors to read or write and returns the number
	     of sectors that were read or written.

> + */
>  blk_status_t null_handle_badblocks(struct nullb_cmd *cmd, sector_t sector,
> -				   sector_t nr_sectors)
> +				   unsigned int *nr_sectors)
>  {
>  	struct badblocks *bb = &cmd->nq->dev->badblocks;
> +	struct nullb_device *dev = cmd->nq->dev;
> +	unsigned int block_sectors = dev->blocksize >> SECTOR_SHIFT;
>  	sector_t first_bad;
>  	int bad_sectors;
> +	unsigned int partial_io_sectors = 0;
>  
> -	if (!badblocks_check(bb, sector, nr_sectors, &first_bad, &bad_sectors))
> +	if (!badblocks_check(bb, sector, *nr_sectors, &first_bad, &bad_sectors))
>  		return BLK_STS_OK;
>  
>  	if (cmd->nq->dev->badblocks_once)
>  		badblocks_clear(bb, first_bad, bad_sectors);
>  
> +	if (cmd->nq->dev->badblocks_partial_io) {
> +		if (!IS_ALIGNED(first_bad, block_sectors))
> +			first_bad = ALIGN_DOWN(first_bad, block_sectors);
> +		if (sector < first_bad)
> +			partial_io_sectors = first_bad - sector;
> +	}
> +	*nr_sectors = partial_io_sectors;
> +
>  	return BLK_STS_IOERR;
>  }

-- 
Damien Le Moal
Western Digital Research




[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux