diff --git a/block/blk-lib.c b/block/blk-lib.c index 7ec3e170e7f62..6e54ef140bab1 100644 --- a/block/blk-lib.c +++ b/block/blk-lib.c @@ -39,19 +39,6 @@ int __blkdev_issue_discard(struct block_device *bdev, sector_t sector, sector_t nr_sects, gfp_t gfp_mask, struct bio **biop) { struct bio *bio = *biop; - sector_t bs_mask; - - if (bdev_read_only(bdev)) - return -EPERM; - if (!bdev_max_discard_sectors(bdev)) - return -EOPNOTSUPP; - - bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1; - if ((sector | nr_sects) & bs_mask) - return -EINVAL; - - if (!nr_sects) - return -EINVAL; while (nr_sects) { sector_t req_sects = diff --git a/block/ioctl.c b/block/ioctl.c index 06ff3023e2a13..49fa02b17ec14 100644 --- a/block/ioctl.c +++ b/block/ioctl.c @@ -95,6 +95,7 @@ static int compat_blkpg_ioctl(struct block_device *bdev, static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, unsigned long arg) { + unsigned int bs_mask = bdev_logical_block_size(bdev) - 1; uint64_t range[2]; uint64_t start, len; struct inode *inode = bdev->bd_inode; @@ -105,6 +106,8 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, 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; @@ -112,9 +115,9 @@ static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, start = range[0]; len = range[1]; - if (start & 511) + if (!len) return -EINVAL; - if (len & 511) + if ((start | len) & bs_mask) return -EINVAL; if (start + len > bdev_nr_bytes(bdev))