Skip to content

Commit 7a07210

Browse files
isilenceaxboe
authored andcommitted
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 <[email protected]> Link: https://lore.kernel.org/r/19a7779323c71e742a2f511e4cf49efcfd68cfd4.1726072086.git.asml.silence@gmail.com Signed-off-by: Jens Axboe <[email protected]>
1 parent a12c883 commit 7a07210

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

block/ioctl.c

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -92,41 +92,54 @@ static int compat_blkpg_ioctl(struct block_device *bdev,
9292
}
9393
#endif
9494

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+
95116
static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
96117
unsigned long arg)
97118
{
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;
100120
struct bio *prev = NULL, *bio;
101121
sector_t sector, nr_sects;
102122
struct blk_plug plug;
103123
int err;
104124

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-
113125
if (copy_from_user(range, (void __user *)arg, sizeof(range)))
114126
return -EFAULT;
115-
116127
start = range[0];
117128
len = range[1];
118129

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;
123132

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;
127140

128141
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);
130143
if (err)
131144
goto fail;
132145

0 commit comments

Comments
 (0)