summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--block/blk-lib.c13
-rw-r--r--block/ioctl.c7
2 files changed, 5 insertions, 15 deletions
diff --git a/block/blk-lib.c b/block/blk-lib.c
index 7ec3e170e7f6..6e54ef140bab 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 06ff3023e2a1..49fa02b17ec1 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))