[RFC 4/5] block: introduce blk_validate_discard()

Pavel Begunkov
2024-08-14T10:45:34Z

In preparation to further changes extract a helper function out of
blk_ioctl_discard() that validates discard arguments.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
---
block/ioctl.c | 45 ++++++++++++++++++++++++++++-----------------
1 file changed, 28 insertions(+), 17 deletions(-)

diff --git a/block/ioctl.c b/block/ioctl.c
index e8e4a4190f18..c7a3e6c6f5fa 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -92,39 +92,50 @@ static int compat_blkpg_ioctl(struct block_device *bdev,
}
#endif

-static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
- unsigned long arg)
+static int blk_validate_discard(struct block_device *bdev, blk_mode_t mode,
+ uint64_t start, uint64_t len)
{
- unsigned int bs_mask = bdev_logical_block_size(bdev) - 1;
- uint64_t range[2], start, len, end;
- struct bio *prev = NULL, *bio;
- sector_t sector, nr_sects;
- struct blk_plug plug;
- int err;
+ unsigned int bs_mask;
+ uint64_t end;

if (!(mode & BLK_OPEN_WRITE))
return -EBADF;
-
if (!bdev_max_discard_sectors(bdev))
return -EOPNOTSUPP;
if (bdev_read_only(bdev))
return -EPERM;

- if (copy_from_user(range, (void __user *)arg, sizeof(range)))
- return -EFAULT;
-
- start = range[0];
- len = range[1];
-
- if (!len)
- return -EINVAL;
+ bs_mask = bdev_logical_block_size(bdev) - 1;
if ((start | len) & bs_mask)
return -EINVAL;
+ if (!len)
+ return -EINVAL;

if (check_add_overflow(start, len, &end) ||
end > bdev_nr_bytes(bdev))
return -EINVAL;

+ return 0;
+}
+
+static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
+ unsigned long arg)
+{
+ uint64_t range[2], start, len;
+ struct bio *prev = NULL, *bio;
+ sector_t sector, nr_sects;
+ struct blk_plug plug;
+ int err;
+
+ if (copy_from_user(range, (void __user *)arg, sizeof(range)))
+ return -EFAULT;
+ start = range[0];
+ len = range[1];
+
+ err = blk_validate_discard(bdev, mode, start, len);
+ if (err)
+ return err;
+
filemap_invalidate_lock(bdev->bd_mapping);
err = truncate_bdev_range(bdev, mode, start, start + len - 1);
if (err)
--
2.45.2