[lkml]   [2017]   [Nov]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
Messages in this thread
    Patch in this message
    Subject[PATCH 4.14 047/193] dm: discard support requires all targets in a table support discards
    4.14-stable review patch.  If anyone has any objections, please let me know.


    From: Mike Snitzer <>

    commit 8a74d29d541cd86569139c6f3f44b2d210458071 upstream.

    A DM device with a mix of discard capabilities (due to some underlying
    devices not having discard support) _should_ just return -EOPNOTSUPP for
    the region of the device that doesn't support discards (even if only by
    way of the underlying driver formally not supporting discards). BUT,
    that does ask the underlying driver to handle something that it never
    advertised support for. In doing so we're exposing users to the
    potential for a underlying disk driver hanging if/when a discard is
    issued a the device that is incapable and never claimed to support

    Fix this by requiring that each DM target in a DM table provide discard
    support as a prereq for a DM device to advertise support for discards.

    This may cause some configurations that were happily supporting discards
    (even in the face of a mix of discard support) to stop supporting
    discards -- but the risk of users hitting driver hangs, and forced
    reboots, outweighs supporting those fringe mixed discard

    Signed-off-by: Mike Snitzer <>
    Signed-off-by: Greg Kroah-Hartman <>

    drivers/md/dm-table.c | 33 ++++++++++++++-------------------
    1 file changed, 14 insertions(+), 19 deletions(-)

    --- a/drivers/md/dm-table.c
    +++ b/drivers/md/dm-table.c
    @@ -1758,13 +1758,12 @@ static bool dm_table_supports_write_zero
    return true;

    -static int device_discard_capable(struct dm_target *ti, struct dm_dev *dev,
    - sector_t start, sector_t len, void *data)
    +static int device_not_discard_capable(struct dm_target *ti, struct dm_dev *dev,
    + sector_t start, sector_t len, void *data)
    struct request_queue *q = bdev_get_queue(dev->bdev);

    - return q && blk_queue_discard(q);
    + return q && !blk_queue_discard(q);

    static bool dm_table_supports_discards(struct dm_table *t)
    @@ -1772,28 +1771,24 @@ static bool dm_table_supports_discards(s
    struct dm_target *ti;
    unsigned i;

    - /*
    - * Unless any target used by the table set discards_supported,
    - * require at least one underlying device to support discards.
    - * t->devices includes internal dm devices such as mirror logs
    - * so we need to use iterate_devices here, which targets
    - * supporting discard selectively must provide.
    - */
    for (i = 0; i < dm_table_get_num_targets(t); i++) {
    ti = dm_table_get_target(t, i);

    if (!ti->num_discard_bios)
    - continue;
    - if (ti->discards_supported)
    - return true;
    + return false;

    - if (ti->type->iterate_devices &&
    - ti->type->iterate_devices(ti, device_discard_capable, NULL))
    - return true;
    + /*
    + * Either the target provides discard support (as implied by setting
    + * 'discards_supported') or it relies on _all_ data devices having
    + * discard support.
    + */
    + if (!ti->discards_supported &&
    + (!ti->type->iterate_devices ||
    + ti->type->iterate_devices(ti, device_not_discard_capable, NULL)))
    + return false;

    - return false;
    + return true;

    void dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,

     \ /
      Last update: 2017-11-28 12:32    [W:2.615 / U:2.600 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site