summaryrefslogtreecommitdiffstats
path: root/block/ioctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'block/ioctl.c')
-rw-r--r--block/ioctl.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/block/ioctl.c b/block/ioctl.c
index 09fd7f1ef23a..d8052f0dabd3 100644
--- a/block/ioctl.c
+++ b/block/ioctl.c
@@ -114,8 +114,10 @@ static int blkdev_reread_part(struct block_device *bdev)
}
static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
- uint64_t len)
+ uint64_t len, int secure)
{
+ unsigned long flags = BLKDEV_IFL_WAIT;
+
if (start & 511)
return -EINVAL;
if (len & 511)
@@ -125,8 +127,9 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start,
if (start + len > (bdev->bd_inode->i_size >> 9))
return -EINVAL;
- return blkdev_issue_discard(bdev, start, len, GFP_KERNEL,
- BLKDEV_IFL_WAIT);
+ if (secure)
+ flags |= BLKDEV_IFL_SECURE;
+ return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags);
}
static int put_ushort(unsigned long arg, unsigned short val)
@@ -213,7 +216,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
set_device_ro(bdev, n);
return 0;
- case BLKDISCARD: {
+ case BLKDISCARD:
+ case BLKSECDISCARD: {
uint64_t range[2];
if (!(mode & FMODE_WRITE))
@@ -222,7 +226,8 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
if (copy_from_user(range, (void __user *)arg, sizeof(range)))
return -EFAULT;
- return blk_ioctl_discard(bdev, range[0], range[1]);
+ return blk_ioctl_discard(bdev, range[0], range[1],
+ cmd == BLKSECDISCARD);
}
case HDIO_GETGEO: {