• Damien Le Moal's avatar
    sd_zbc: Fix report zones buffer allocation · b091ac61
    Damien Le Moal authored
    During disk scan and revalidation done with sd_revalidate(), the zones
    of a zoned disk are checked using the helper function
    blk_revalidate_disk_zones() if a configuration change is detected
    (change in the number of zones or zone size). The function
    blk_revalidate_disk_zones() issues report_zones calls that are very
    large, that is, to obtain zone information for all zones of the disk
    with a single command. The size of the report zones command buffer
    necessary for such large request generally is lower than the disk
    max_hw_sectors and KMALLOC_MAX_SIZE (4MB) and succeeds on boot (no
    memory fragmentation), but often fail at run time (e.g. hot-plug
    event). This causes the disk revalidation to fail and the disk
    capacity to be changed to 0.
    
    This problem can be avoided by using vmalloc() instead of kmalloc() for
    the buffer allocation. To limit the amount of memory to be allocated,
    this patch also introduces the arbitrary SD_ZBC_REPORT_MAX_ZONES
    maximum number of zones to report with a single report zones command.
    This limit may be lowered further to satisfy the disk max_hw_sectors
    limit. Finally, to ensure that the vmalloc-ed buffer can always be
    mapped in a request, the buffer size is further limited to at most
    queue_max_segments() pages, allowing successful mapping of the buffer
    even in the worst case scenario where none of the buffer pages are
    contiguous.
    
    Fixes: 515ce606 ("scsi: sd_zbc: Fix sd_zbc_report_zones() buffer allocation")
    Fixes: e76239a3 ("block: add a report_zones method")
    Cc: stable@vger.kernel.org
    Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
    Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: default avatarDamien Le Moal <damien.lemoal@wdc.com>
    Signed-off-by: default avatarJens Axboe <axboe@kernel.dk>
    b091ac61
sd_zbc.c 13.8 KB