aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob N <rob.norris@klarasystems.com>2024-04-12 16:00:20 +0000
committerGitHub <noreply@github.com>2024-04-12 16:00:20 +0000
commitb181b2e604de3f36feab1092c702cdec5e78c693 (patch)
treefa7386b45105beececf3b210a910563d383a105e
parentd7605ae77b7ad176e8dbd5649fe4d14f5f4e8b9f (diff)
downloadsrc-b181b2e604de3f36feab1092c702cdec5e78c693.tar.gz
src-b181b2e604de3f36feab1092c702cdec5e78c693.zip
bdev_discard_supported: understand discard_granularity=0
Kernel documentation for the discard_granularity property says: A discard_granularity of 0 means that the device does not support discard functionality. Some older kernels had drivers (notably loop, but also some USB-SATA adapters) that would set the QUEUE_FLAG_DISCARD capability flag, but have discard_granularity=0. Since 5.10 (torvalds/linux@b35fd7422c2f) the discard entry point blkdev_issue_discard() has had a check for this, which would immediately reject the call with EOPNOTSUPP, and throw a scary diagnostic message into the log. See #16068. Since 6.8, the block layer sets a non-zero default for discard_granularity (torvalds/linux@3c407dc723bb), and a future kernel will remove the check entirely[1]. As such, there's no good reason for us to enable discard when discard_granularity=0. The kernel will never let the request go in anyway; better that we just disable it so we can report it properly to the user. 1. https://patchwork.kernel.org/project/linux-block/patch/20240312144826.1045212-2-hch@lst.de/ Sponsored-by: Klara, Inc. Sponsored-by: Wasabi Technology, Inc. Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Signed-off-by: Rob Norris <rob.norris@klarasystems.com> Closes #16068 Closes #16082
-rw-r--r--include/os/linux/kernel/linux/blkdev_compat.h6
1 files changed, 4 insertions, 2 deletions
diff --git a/include/os/linux/kernel/linux/blkdev_compat.h b/include/os/linux/kernel/linux/blkdev_compat.h
index f111e648ccf7..b0f398354e4f 100644
--- a/include/os/linux/kernel/linux/blkdev_compat.h
+++ b/include/os/linux/kernel/linux/blkdev_compat.h
@@ -563,9 +563,11 @@ static inline boolean_t
bdev_discard_supported(struct block_device *bdev)
{
#if defined(HAVE_BDEV_MAX_DISCARD_SECTORS)
- return (!!bdev_max_discard_sectors(bdev));
+ return (bdev_max_discard_sectors(bdev) > 0 &&
+ bdev_discard_granularity(bdev) > 0);
#elif defined(HAVE_BLK_QUEUE_DISCARD)
- return (!!blk_queue_discard(bdev_get_queue(bdev)));
+ return (blk_queue_discard(bdev_get_queue(bdev)) > 0 &&
+ bdev_get_queue(bdev)->limits.discard_granularity > 0);
#else
#error "Unsupported kernel"
#endif