lkml.org 
[lkml]   [2018]   [Jul]   [10]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.14 30/53] block: cope with WRITE ZEROES failing in blkdev_issue_zeroout()
    Date
    4.14-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Ilya Dryomov <idryomov@gmail.com>

    commit d5ce4c31d6df518dd8f63bbae20d7423c5018a6c upstream.

    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: c20cfc27a473 ("block: stop using blkdev_issue_write_same for zeroing")
    Cc: Hannes Reinecke <hare@suse.com>
    Reviewed-by: Christoph Hellwig <hch@lst.de>
    Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
    Signed-off-by: Jens Axboe <axboe@kernel.dk>
    Cc: Janne Huttunen <janne.huttunen@nokia.com>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    block/blk-lib.c | 45 +++++++++++++++++++++++++++++++++++----------
    1 file changed, 35 insertions(+), 10 deletions(-)

    --- a/block/blk-lib.c
    +++ b/block/blk-lib.c
    @@ -322,12 +322,6 @@ static int __blkdev_issue_zero_pages(str
    * Zero-fill a block range, either using hardware offload or by explicitly
    * writing zeroes to the device.
    *
    - * Note that this function may fail with -EOPNOTSUPP if the driver signals
    - * zeroing offload support, but the device fails to process the command (for
    - * some devices there is no non-destructive way to verify whether this
    - * operation is actually supported). In this case the caller should call
    - * retry the call to blkdev_issue_zeroout() and the fallback path will be used.
    - *
    * If a device is using logical block provisioning, the underlying space will
    * not be released if %flags contains BLKDEV_ZERO_NOUNMAP.
    *
    @@ -371,18 +365,49 @@ EXPORT_SYMBOL(__blkdev_issue_zeroout);
    int blkdev_issue_zeroout(struct block_device *bdev, sector_t sector,
    sector_t nr_sects, gfp_t gfp_mask, unsigned flags)
    {
    - int ret;
    - struct bio *bio = NULL;
    + int ret = 0;
    + sector_t bs_mask;
    + struct bio *bio;
    struct blk_plug plug;
    + bool try_write_zeroes = !!bdev_write_zeroes_sectors(bdev);

    + bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
    + if ((sector | nr_sects) & bs_mask)
    + return -EINVAL;
    +
    +retry:
    + bio = NULL;
    blk_start_plug(&plug);
    - ret = __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask,
    - &bio, flags);
    + if (try_write_zeroes) {
    + ret = __blkdev_issue_write_zeroes(bdev, sector, nr_sects,
    + gfp_mask, &bio, flags);
    + } else if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
    + ret = __blkdev_issue_zero_pages(bdev, sector, nr_sects,
    + gfp_mask, &bio);
    + } else {
    + /* No zeroing offload support */
    + ret = -EOPNOTSUPP;
    + }
    if (ret == 0 && bio) {
    ret = submit_bio_wait(bio);
    bio_put(bio);
    }
    blk_finish_plug(&plug);
    + if (ret && try_write_zeroes) {
    + if (!(flags & BLKDEV_ZERO_NOFALLBACK)) {
    + try_write_zeroes = false;
    + goto retry;
    + }
    + if (!bdev_write_zeroes_sectors(bdev)) {
    + /*
    + * Zeroing offload support was indicated, but the
    + * device reported ILLEGAL REQUEST (for some devices
    + * there is no non-destructive way to verify whether
    + * WRITE ZEROES is actually supported).
    + */
    + ret = -EOPNOTSUPP;
    + }
    + }

    return ret;
    }

    \
     
     \ /
      Last update: 2018-07-10 20:45    [W:3.376 / U:0.008 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site