Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

block: introduce blk_validate_byte_range()

In preparation to further changes extract a helper function out of
blk_ioctl_discard() that validates if we can do IO against the given
range of disk byte addresses.

Signed-off-by: Pavel Begunkov <asml.silence@gmail.com>
Link: https://lore.kernel.org/r/19a7779323c71e742a2f511e4cf49efcfd68cfd4.1726072086.git.asml.silence@gmail.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Pavel Begunkov and committed by
Jens Axboe
7a07210b a12c883a

+32 -19
+32 -19
block/ioctl.c
··· 92 92 } 93 93 #endif 94 94 95 + /* 96 + * Check that [start, start + len) is a valid range from the block device's 97 + * perspective, including verifying that it can be correctly translated into 98 + * logical block addresses. 99 + */ 100 + static int blk_validate_byte_range(struct block_device *bdev, 101 + uint64_t start, uint64_t len) 102 + { 103 + unsigned int bs_mask = bdev_logical_block_size(bdev) - 1; 104 + uint64_t end; 105 + 106 + if ((start | len) & bs_mask) 107 + return -EINVAL; 108 + if (!len) 109 + return -EINVAL; 110 + if (check_add_overflow(start, len, &end) || end > bdev_nr_bytes(bdev)) 111 + return -EINVAL; 112 + 113 + return 0; 114 + } 115 + 95 116 static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, 96 117 unsigned long arg) 97 118 { 98 - unsigned int bs_mask = bdev_logical_block_size(bdev) - 1; 99 - uint64_t range[2], start, len, end; 119 + uint64_t range[2], start, len; 100 120 struct bio *prev = NULL, *bio; 101 121 sector_t sector, nr_sects; 102 122 struct blk_plug plug; 103 123 int err; 104 124 105 - if (!(mode & BLK_OPEN_WRITE)) 106 - return -EBADF; 107 - 108 - if (!bdev_max_discard_sectors(bdev)) 109 - return -EOPNOTSUPP; 110 - if (bdev_read_only(bdev)) 111 - return -EPERM; 112 - 113 125 if (copy_from_user(range, (void __user *)arg, sizeof(range))) 114 126 return -EFAULT; 115 - 116 127 start = range[0]; 117 128 len = range[1]; 118 129 119 - if (!len) 120 - return -EINVAL; 121 - if ((start | len) & bs_mask) 122 - return -EINVAL; 130 + if (!bdev_max_discard_sectors(bdev)) 131 + return -EOPNOTSUPP; 123 132 124 - if (check_add_overflow(start, len, &end) || 125 - end > bdev_nr_bytes(bdev)) 126 - return -EINVAL; 133 + if (!(mode & BLK_OPEN_WRITE)) 134 + return -EBADF; 135 + if (bdev_read_only(bdev)) 136 + return -EPERM; 137 + err = blk_validate_byte_range(bdev, start, len); 138 + if (err) 139 + return err; 127 140 128 141 filemap_invalidate_lock(bdev->bd_mapping); 129 - err = truncate_bdev_range(bdev, mode, start, end - 1); 142 + err = truncate_bdev_range(bdev, mode, start, start + len - 1); 130 143 if (err) 131 144 goto fail; 132 145