Skip to content

Commit

Permalink
block: remove QUEUE_FLAG_DISCARD
Browse files Browse the repository at this point in the history
Just use a non-zero max_discard_sectors as an indicator for discard
support, similar to what is done for write zeroes.

The only places where needs special attention is the RAID5 driver,
which must clear discard support for security reasons by default,
even if the default stacking rules would allow for it.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Martin K. Petersen <martin.petersen@oracle.com>
Acked-by: Christoph Böhmwalder <christoph.boehmwalder@linbit.com> [drbd]
Acked-by: Jan Höppner <hoeppner@linux.ibm.com> [s390]
Acked-by: Coly Li <colyli@suse.de> [bcache]
Acked-by: David Sterba <dsterba@suse.com> [btrfs]
Reviewed-by: Chaitanya Kulkarni <kch@nvidia.com>
Link: https://lore.kernel.org/r/20220415045258.199825-25-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
  • Loading branch information
Christoph Hellwig authored and Jens Axboe committed Apr 18, 2022
1 parent cf0fbf8 commit 7020057
Show file tree
Hide file tree
Showing 61 changed files with 73 additions and 244 deletions.
2 changes: 0 additions & 2 deletions arch/um/drivers/ubd_kern.c
Original file line number Diff line number Diff line change
Expand Up @@ -483,7 +483,6 @@ static void ubd_handler(void)
if ((io_req->error == BLK_STS_NOTSUPP) && (req_op(io_req->req) == REQ_OP_DISCARD)) {
blk_queue_max_discard_sectors(io_req->req->q, 0);
blk_queue_max_write_zeroes_sectors(io_req->req->q, 0);
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, io_req->req->q);
}
blk_mq_end_request(io_req->req, io_req->error);
kfree(io_req);
Expand Down Expand Up @@ -803,7 +802,6 @@ static int ubd_open_dev(struct ubd *ubd_dev)
ubd_dev->queue->limits.discard_alignment = SECTOR_SIZE;
blk_queue_max_discard_sectors(ubd_dev->queue, UBD_MAX_REQUEST);
blk_queue_max_write_zeroes_sectors(ubd_dev->queue, UBD_MAX_REQUEST);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, ubd_dev->queue);
}
blk_queue_flag_set(QUEUE_FLAG_NONROT, ubd_dev->queue);
return 0;
Expand Down
2 changes: 1 addition & 1 deletion block/blk-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,7 +820,7 @@ void submit_bio_noacct(struct bio *bio)

switch (bio_op(bio)) {
case REQ_OP_DISCARD:
if (!blk_queue_discard(q))
if (!bdev_max_discard_sectors(bdev))
goto not_supported;
break;
case REQ_OP_SECURE_ERASE:
Expand Down
2 changes: 1 addition & 1 deletion block/blk-lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector,
return -EOPNOTSUPP;
op = REQ_OP_SECURE_ERASE;
} else {
if (!blk_queue_discard(q))
if (!bdev_max_discard_sectors(bdev))
return -EOPNOTSUPP;
op = REQ_OP_DISCARD;
}
Expand Down
1 change: 0 additions & 1 deletion block/blk-mq-debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ static const char *const blk_queue_flag_name[] = {
QUEUE_FLAG_NAME(FAIL_IO),
QUEUE_FLAG_NAME(NONROT),
QUEUE_FLAG_NAME(IO_STAT),
QUEUE_FLAG_NAME(DISCARD),
QUEUE_FLAG_NAME(NOXMERGES),
QUEUE_FLAG_NAME(ADD_RANDOM),
QUEUE_FLAG_NAME(SECERASE),
Expand Down
3 changes: 1 addition & 2 deletions block/ioctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,14 +87,13 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
{
uint64_t range[2];
uint64_t start, len;
struct request_queue *q = bdev_get_queue(bdev);
struct inode *inode = bdev->bd_inode;
int err;

if (!(mode & FMODE_WRITE))
return -EBADF;

if (!blk_queue_discard(q))
if (!bdev_max_discard_sectors(bdev))
return -EOPNOTSUPP;

if (copy_from_user(range, (void __user *)arg, sizeof(range)))
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/drbd/drbd_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -942,7 +942,7 @@ int drbd_send_sizes(struct drbd_peer_device *peer_device, int trigger_reply, enu
cpu_to_be32(bdev_alignment_offset(bdev));
p->qlim->io_min = cpu_to_be32(bdev_io_min(bdev));
p->qlim->io_opt = cpu_to_be32(bdev_io_opt(bdev));
p->qlim->discard_enabled = blk_queue_discard(q);
p->qlim->discard_enabled = !!bdev_max_discard_sectors(bdev);
put_ldev(device);
} else {
struct request_queue *q = device->rq_queue;
Expand Down
19 changes: 2 additions & 17 deletions drivers/block/drbd/drbd_nl.c
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,7 @@ static void decide_on_discard_support(struct drbd_device *device,
first_peer_device(device)->connection;
struct request_queue *q = device->rq_queue;

if (bdev && !blk_queue_discard(bdev->backing_bdev->bd_disk->queue))
if (bdev && !bdev_max_discard_sectors(bdev->backing_bdev))
goto not_supported;

if (connection->cstate >= C_CONNECTED &&
Expand All @@ -1230,30 +1230,16 @@ static void decide_on_discard_support(struct drbd_device *device,
*/
blk_queue_discard_granularity(q, 512);
q->limits.max_discard_sectors = drbd_max_discard_sectors(connection);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
q->limits.max_write_zeroes_sectors =
drbd_max_discard_sectors(connection);
return;

not_supported:
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
blk_queue_discard_granularity(q, 0);
q->limits.max_discard_sectors = 0;
q->limits.max_write_zeroes_sectors = 0;
}

static void fixup_discard_if_not_supported(struct request_queue *q)
{
/* To avoid confusion, if this queue does not support discard, clear
* max_discard_sectors, which is what lsblk -D reports to the user.
* Older kernels got this wrong in "stack limits".
* */
if (!blk_queue_discard(q)) {
blk_queue_max_discard_sectors(q, 0);
blk_queue_discard_granularity(q, 0);
}
}

static void fixup_write_zeroes(struct drbd_device *device, struct request_queue *q)
{
/* Fixup max_write_zeroes_sectors after blk_stack_limits():
Expand Down Expand Up @@ -1300,7 +1286,6 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
blk_stack_limits(&q->limits, &b->limits, 0);
disk_update_readahead(device->vdisk);
}
fixup_discard_if_not_supported(q);
fixup_write_zeroes(device, q);
}

Expand Down Expand Up @@ -1447,7 +1432,7 @@ static void sanitize_disk_conf(struct drbd_device *device, struct disk_conf *dis
if (disk_conf->al_extents > drbd_al_extents_max(nbc))
disk_conf->al_extents = drbd_al_extents_max(nbc);

if (!blk_queue_discard(q)) {
if (!bdev_max_discard_sectors(bdev)) {
if (disk_conf->rs_discard_granularity) {
disk_conf->rs_discard_granularity = 0; /* disable feature */
drbd_info(device, "rs_discard_granularity feature disabled\n");
Expand Down
3 changes: 1 addition & 2 deletions drivers/block/drbd/drbd_receiver.c
Original file line number Diff line number Diff line change
Expand Up @@ -1575,11 +1575,10 @@ int drbd_issue_discard_or_zero_out(struct drbd_device *device, sector_t start, u

static bool can_do_reliable_discards(struct drbd_device *device)
{
struct request_queue *q = bdev_get_queue(device->ldev->backing_bdev);
struct disk_conf *dc;
bool can_do;

if (!blk_queue_discard(q))
if (!bdev_max_discard_sectors(device->ldev->backing_bdev))
return false;

rcu_read_lock();
Expand Down
11 changes: 3 additions & 8 deletions drivers/block/loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -314,15 +314,12 @@ static int lo_fallocate(struct loop_device *lo, struct request *rq, loff_t pos,

mode |= FALLOC_FL_KEEP_SIZE;

if (!blk_queue_discard(lo->lo_queue)) {
ret = -EOPNOTSUPP;
goto out;
}
if (!bdev_max_discard_sectors(lo->lo_device))
return -EOPNOTSUPP;

ret = file->f_op->fallocate(file, mode, pos, blk_rq_bytes(rq));
if (unlikely(ret && ret != -EINVAL && ret != -EOPNOTSUPP))
ret = -EIO;
out:
return -EIO;
return ret;
}

Expand Down Expand Up @@ -787,12 +784,10 @@ static void loop_config_discard(struct loop_device *lo)
q->limits.discard_granularity = granularity;
blk_queue_max_discard_sectors(q, max_discard_sectors);
blk_queue_max_write_zeroes_sectors(q, max_discard_sectors);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
} else {
q->limits.discard_granularity = 0;
blk_queue_max_discard_sectors(q, 0);
blk_queue_max_write_zeroes_sectors(q, 0);
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, q);
}
q->limits.discard_alignment = 0;
}
Expand Down
5 changes: 1 addition & 4 deletions drivers/block/nbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,8 +1231,6 @@ static void nbd_parse_flags(struct nbd_device *nbd)
set_disk_ro(nbd->disk, true);
else
set_disk_ro(nbd->disk, false);
if (config->flags & NBD_FLAG_SEND_TRIM)
blk_queue_flag_set(QUEUE_FLAG_DISCARD, nbd->disk->queue);
if (config->flags & NBD_FLAG_SEND_FLUSH) {
if (config->flags & NBD_FLAG_SEND_FUA)
blk_queue_write_cache(nbd->disk->queue, true, true);
Expand Down Expand Up @@ -1319,8 +1317,7 @@ static void nbd_config_put(struct nbd_device *nbd)
nbd->tag_set.timeout = 0;
nbd->disk->queue->limits.discard_granularity = 0;
nbd->disk->queue->limits.discard_alignment = 0;
blk_queue_max_discard_sectors(nbd->disk->queue, UINT_MAX);
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, nbd->disk->queue);
blk_queue_max_discard_sectors(nbd->disk->queue, 0);

mutex_unlock(&nbd->config_lock);
nbd_put(nbd);
Expand Down
1 change: 0 additions & 1 deletion drivers/block/null_blk/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1767,7 +1767,6 @@ static void null_config_discard(struct nullb *nullb)
nullb->q->limits.discard_granularity = nullb->dev->blocksize;
nullb->q->limits.discard_alignment = nullb->dev->blocksize;
blk_queue_max_discard_sectors(nullb->q, UINT_MAX >> 9);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, nullb->q);
}

static const struct block_device_operations null_bio_ops = {
Expand Down
1 change: 0 additions & 1 deletion drivers/block/rbd.c
Original file line number Diff line number Diff line change
Expand Up @@ -4942,7 +4942,6 @@ static int rbd_init_disk(struct rbd_device *rbd_dev)
blk_queue_io_opt(q, rbd_dev->opts->alloc_size);

if (rbd_dev->opts->trim) {
blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
q->limits.discard_granularity = rbd_dev->opts->alloc_size;
blk_queue_max_discard_sectors(q, objset_bytes >> SECTOR_SHIFT);
blk_queue_max_write_zeroes_sectors(q, objset_bytes >> SECTOR_SHIFT);
Expand Down
2 changes: 0 additions & 2 deletions drivers/block/rnbd/rnbd-clt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1364,8 +1364,6 @@ static void setup_request_queue(struct rnbd_clt_dev *dev)
blk_queue_max_discard_sectors(dev->queue, dev->max_discard_sectors);
dev->queue->limits.discard_granularity = dev->discard_granularity;
dev->queue->limits.discard_alignment = dev->discard_alignment;
if (dev->max_discard_sectors)
blk_queue_flag_set(QUEUE_FLAG_DISCARD, dev->queue);
if (dev->secure_discard)
blk_queue_flag_set(QUEUE_FLAG_SECERASE, dev->queue);

Expand Down
3 changes: 0 additions & 3 deletions drivers/block/rnbd/rnbd-srv-dev.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,6 @@ static inline int rnbd_dev_get_secure_discard(const struct rnbd_dev *dev)

static inline int rnbd_dev_get_max_discard_sects(const struct rnbd_dev *dev)
{
if (!blk_queue_discard(bdev_get_queue(dev->bdev)))
return 0;

return bdev_max_discard_sectors(dev->bdev);
}

Expand Down
2 changes: 0 additions & 2 deletions drivers/block/virtio_blk.c
Original file line number Diff line number Diff line change
Expand Up @@ -888,8 +888,6 @@ static int virtblk_probe(struct virtio_device *vdev)
v = sg_elems;
blk_queue_max_discard_segments(q,
min(v, MAX_DISCARD_SEGMENTS));

blk_queue_flag_set(QUEUE_FLAG_DISCARD, q);
}

if (virtio_has_feature(vdev, VIRTIO_BLK_F_WRITE_ZEROES)) {
Expand Down
2 changes: 1 addition & 1 deletion drivers/block/xen-blkback/xenbus.c
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,7 @@ static void xen_blkbk_discard(struct xenbus_transaction xbt, struct backend_info
if (!xenbus_read_unsigned(dev->nodename, "discard-enable", 1))
return;

if (blk_queue_discard(q)) {
if (bdev_max_discard_sectors(bdev)) {
err = xenbus_printf(xbt, dev->nodename,
"discard-granularity", "%u",
q->limits.discard_granularity);
Expand Down
3 changes: 1 addition & 2 deletions drivers/block/xen-blkfront.c
Original file line number Diff line number Diff line change
Expand Up @@ -944,7 +944,6 @@ static void blkif_set_queue_limits(struct blkfront_info *info)
blk_queue_flag_set(QUEUE_FLAG_VIRT, rq);

if (info->feature_discard) {
blk_queue_flag_set(QUEUE_FLAG_DISCARD, rq);
blk_queue_max_discard_sectors(rq, get_capacity(gd));
rq->limits.discard_granularity = info->discard_granularity ?:
info->physical_sector_size;
Expand Down Expand Up @@ -1606,7 +1605,7 @@ static irqreturn_t blkif_interrupt(int irq, void *dev_id)
blkif_req(req)->error = BLK_STS_NOTSUPP;
info->feature_discard = 0;
info->feature_secdiscard = 0;
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, rq);
blk_queue_max_discard_sectors(rq, 0);
blk_queue_flag_clear(QUEUE_FLAG_SECERASE, rq);
}
break;
Expand Down
1 change: 0 additions & 1 deletion drivers/block/zram/zram_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1952,7 +1952,6 @@ static int zram_add(void)
blk_queue_io_opt(zram->disk->queue, PAGE_SIZE);
zram->disk->queue->limits.discard_granularity = PAGE_SIZE;
blk_queue_max_discard_sectors(zram->disk->queue, UINT_MAX);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, zram->disk->queue);

/*
* zram_bio_discard() will clear all logical blocks if logical block
Expand Down
4 changes: 2 additions & 2 deletions drivers/md/bcache/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -1005,7 +1005,7 @@ static void cached_dev_write(struct cached_dev *dc, struct search *s)
bio_get(s->iop.bio);

if (bio_op(bio) == REQ_OP_DISCARD &&
!blk_queue_discard(bdev_get_queue(dc->bdev)))
!bdev_max_discard_sectors(dc->bdev))
goto insert_data;

/* I/O request sent to backing device */
Expand Down Expand Up @@ -1115,7 +1115,7 @@ static void detached_dev_do_request(struct bcache_device *d, struct bio *bio,
bio->bi_private = ddip;

if ((bio_op(bio) == REQ_OP_DISCARD) &&
!blk_queue_discard(bdev_get_queue(dc->bdev)))
!bdev_max_discard_sectors(dc->bdev))
bio->bi_end_io(bio);
else
submit_bio_noacct(bio);
Expand Down
3 changes: 1 addition & 2 deletions drivers/md/bcache/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -973,7 +973,6 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size,

blk_queue_flag_set(QUEUE_FLAG_NONROT, d->disk->queue);
blk_queue_flag_clear(QUEUE_FLAG_ADD_RANDOM, d->disk->queue);
blk_queue_flag_set(QUEUE_FLAG_DISCARD, d->disk->queue);

blk_queue_write_cache(q, true, true);

Expand Down Expand Up @@ -2350,7 +2349,7 @@ static int register_cache(struct cache_sb *sb, struct cache_sb_disk *sb_disk,
ca->bdev->bd_holder = ca;
ca->sb_disk = sb_disk;

if (blk_queue_discard(bdev_get_queue(bdev)))
if (bdev_max_discard_sectors((bdev)))
ca->discard = CACHE_DISCARD(&ca->sb);

ret = cache_alloc(ca);
Expand Down
2 changes: 1 addition & 1 deletion drivers/md/bcache/sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1151,7 +1151,7 @@ STORE(__bch_cache)
if (attr == &sysfs_discard) {
bool v = strtoul_or_return(buf);

if (blk_queue_discard(bdev_get_queue(ca->bdev)))
if (bdev_max_discard_sectors(ca->bdev))
ca->discard = v;

if (v != CACHE_DISCARD(&ca->sb)) {
Expand Down
9 changes: 1 addition & 8 deletions drivers/md/dm-cache-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -3329,13 +3329,6 @@ static int cache_iterate_devices(struct dm_target *ti,
return r;
}

static bool origin_dev_supports_discard(struct block_device *origin_bdev)
{
struct request_queue *q = bdev_get_queue(origin_bdev);

return blk_queue_discard(q);
}

/*
* If discard_passdown was enabled verify that the origin device
* supports discards. Disable discard_passdown if not.
Expand All @@ -3349,7 +3342,7 @@ static void disable_passdown_if_not_supported(struct cache *cache)
if (!cache->features.discard_passdown)
return;

if (!origin_dev_supports_discard(origin_bdev))
if (!bdev_max_discard_sectors(origin_bdev))
reason = "discard unsupported";

else if (origin_limits->max_discard_sectors < cache->sectors_per_block)
Expand Down
9 changes: 1 addition & 8 deletions drivers/md/dm-clone-target.c
Original file line number Diff line number Diff line change
Expand Up @@ -2016,13 +2016,6 @@ static void clone_resume(struct dm_target *ti)
do_waker(&clone->waker.work);
}

static bool bdev_supports_discards(struct block_device *bdev)
{
struct request_queue *q = bdev_get_queue(bdev);

return (q && blk_queue_discard(q));
}

/*
* If discard_passdown was enabled verify that the destination device supports
* discards. Disable discard_passdown if not.
Expand All @@ -2036,7 +2029,7 @@ static void disable_passdown_if_not_supported(struct clone *clone)
if (!test_bit(DM_CLONE_DISCARD_PASSDOWN, &clone->flags))
return;

if (!bdev_supports_discards(dest_dev))
if (!bdev_max_discard_sectors(dest_dev))
reason = "discard unsupported";
else if (dest_limits->max_discard_sectors < clone->region_size)
reason = "max discard sectors smaller than a region";
Expand Down
3 changes: 1 addition & 2 deletions drivers/md/dm-log-writes.c
Original file line number Diff line number Diff line change
Expand Up @@ -866,9 +866,8 @@ static int log_writes_message(struct dm_target *ti, unsigned argc, char **argv,
static void log_writes_io_hints(struct dm_target *ti, struct queue_limits *limits)
{
struct log_writes_c *lc = ti->private;
struct request_queue *q = bdev_get_queue(lc->dev->bdev);

if (!q || !blk_queue_discard(q)) {
if (!bdev_max_discard_sectors(lc->dev->bdev)) {
lc->device_supports_discard = false;
limits->discard_granularity = lc->sectorsize;
limits->max_discard_sectors = (UINT_MAX >> SECTOR_SHIFT);
Expand Down
9 changes: 2 additions & 7 deletions drivers/md/dm-raid.c
Original file line number Diff line number Diff line change
Expand Up @@ -2963,13 +2963,8 @@ static void configure_discard_support(struct raid_set *rs)
raid456 = rs_is_raid456(rs);

for (i = 0; i < rs->raid_disks; i++) {
struct request_queue *q;

if (!rs->dev[i].rdev.bdev)
continue;

q = bdev_get_queue(rs->dev[i].rdev.bdev);
if (!q || !blk_queue_discard(q))
if (!rs->dev[i].rdev.bdev ||
!bdev_max_discard_sectors(rs->dev[i].rdev.bdev))
return;

if (raid456) {
Expand Down
Loading

0 comments on commit 7020057

Please sign in to comment.