Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit 590ab1f

Browse files
idryomovJenkins OS
authored andcommitted
block: cope with WRITE ZEROES failing in blkdev_issue_zeroout()
sd_config_write_same() ignores ->max_ws_blocks == 0 and resets it to permit trying WRITE SAME on older SCSI devices, unless ->no_write_same is set. Because REQ_OP_WRITE_ZEROES is implemented in terms of WRITE SAME, blkdev_issue_zeroout() may fail with -EREMOTEIO: $ fallocate -zn -l 1k /dev/sdg fallocate: fallocate failed: Remote I/O error $ fallocate -zn -l 1k /dev/sdg # OK $ fallocate -zn -l 1k /dev/sdg # OK The following calls succeed because sd_done() sets ->no_write_same in response to a sense that would become BLK_STS_TARGET/-EREMOTEIO, causing __blkdev_issue_zeroout() to fall back to generating ZERO_PAGE bios. This means blkdev_issue_zeroout() must cope with WRITE ZEROES failing and fall back to manually zeroing, unless BLKDEV_ZERO_NOFALLBACK is specified. For BLKDEV_ZERO_NOFALLBACK case, return -EOPNOTSUPP if sd_done() has just set ->no_write_same thus indicating lack of offload support. Fixes: c20cfc2 ("block: stop using blkdev_issue_write_same for zeroing") Cc: Hannes Reinecke <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Martin K. Petersen <[email protected]> Signed-off-by: Ilya Dryomov <[email protected]> Signed-off-by: Jens Axboe <[email protected]>
1 parent 91d9cee commit 590ab1f

File tree

1 file changed

+35
-10
lines changed

1 file changed

+35
-10
lines changed

block/blk-lib.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -322,12 +322,6 @@ static int __blkdev_issue_zero_pages(struct block_device *bdev,
322322
* Zero-fill a block range, either using hardware offload or by explicitly
323323
* writing zeroes to the device.
324324
*
325-
* Note that this function may fail with -EOPNOTSUPP if the driver signals
326-
* zeroing offload support, but the device fails to process the command (for
327-
* some devices there is no non-destructive way to verify whether this
328-
* operation is actually supported). In this case the caller should call
329-
* retry the call to blkdev_issue_zeroout() and the fallback path will be used.
330-
*
331325
* If a device is using logical block provisioning, the underlying space will
332326
* not be released if %flags contains BLKDEV_ZERO_NOUNMAP.
333327
*
@@ -371,18 +365,49 @@ EXPORT_SYMBOL(__blkdev_issue_zeroout);
371365
int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
372366
sector_t nr_sects, gfp_t gfp_mask, unsigned flags)
373367
{
374-
int ret;
375-
struct bio *bio = NULL;
368+
int ret = 0;
369+
sector_t bs_mask;
370+
struct bio *bio;
376371
struct blk_plug plug;
372+
bool try_write_zeroes = !!bdev_write_zeroes_sectors(bdev);
377373

374+
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
375+
if ((sector | nr_sects) & bs_mask)
376+
return -EINVAL;
377+
378+
retry:
379+
bio = NULL;
378380
blk_start_plug(&plug);
379-
ret = __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask,
380-
&bio, flags);
381+
if (try_write_zeroes) {
382+
ret = __blkdev_issue_write_zeroes(bdev, sector, nr_sects,
383+
gfp_mask, &bio, flags);
384+
} else if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
385+
ret = __blkdev_issue_zero_pages(bdev, sector, nr_sects,
386+
gfp_mask, &bio);
387+
} else {
388+
/* No zeroing offload support */
389+
ret = -EOPNOTSUPP;
390+
}
381391
if (ret == 0 && bio) {
382392
ret = submit_bio_wait(bio);
383393
bio_put(bio);
384394
}
385395
blk_finish_plug(&plug);
396+
if (ret && try_write_zeroes) {
397+
if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
398+
try_write_zeroes = false;
399+
goto retry;
400+
}
401+
if (!bdev_write_zeroes_sectors(bdev)) {
402+
/*
403+
* Zeroing offload support was indicated, but the
404+
* device reported ILLEGAL REQUEST (for some devices
405+
* there is no non-destructive way to verify whether
406+
* WRITE ZEROES is actually supported).
407+
*/
408+
ret = -EOPNOTSUPP;
409+
}
410+
}
386411

387412
return ret;
388413
}

0 commit comments

Comments
 (0)