diff options
| -rw-r--r-- | block/ioctl.c | 27 | ||||
| -rw-r--r-- | include/linux/fs.h | 1 |
2 files changed, 28 insertions, 0 deletions
diff --git a/block/ioctl.c b/block/ioctl.c index 4476e0e85d16..769d2960c0a6 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
| @@ -185,6 +185,22 @@ static int blk_ioctl_discard(struct block_device *bdev, uint64_t start, | |||
| 185 | return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); | 185 | return blkdev_issue_discard(bdev, start, len, GFP_KERNEL, flags); |
| 186 | } | 186 | } |
| 187 | 187 | ||
| 188 | static int blk_ioctl_zeroout(struct block_device *bdev, uint64_t start, | ||
| 189 | uint64_t len) | ||
| 190 | { | ||
| 191 | if (start & 511) | ||
| 192 | return -EINVAL; | ||
| 193 | if (len & 511) | ||
| 194 | return -EINVAL; | ||
| 195 | start >>= 9; | ||
| 196 | len >>= 9; | ||
| 197 | |||
| 198 | if (start + len > (i_size_read(bdev->bd_inode) >> 9)) | ||
| 199 | return -EINVAL; | ||
| 200 | |||
| 201 | return blkdev_issue_zeroout(bdev, start, len, GFP_KERNEL); | ||
| 202 | } | ||
| 203 | |||
| 188 | static int put_ushort(unsigned long arg, unsigned short val) | 204 | static int put_ushort(unsigned long arg, unsigned short val) |
| 189 | { | 205 | { |
| 190 | return put_user(val, (unsigned short __user *)arg); | 206 | return put_user(val, (unsigned short __user *)arg); |
| @@ -300,6 +316,17 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd, | |||
| 300 | return blk_ioctl_discard(bdev, range[0], range[1], | 316 | return blk_ioctl_discard(bdev, range[0], range[1], |
| 301 | cmd == BLKSECDISCARD); | 317 | cmd == BLKSECDISCARD); |
| 302 | } | 318 | } |
| 319 | case BLKZEROOUT: { | ||
| 320 | uint64_t range[2]; | ||
| 321 | |||
| 322 | if (!(mode & FMODE_WRITE)) | ||
| 323 | return -EBADF; | ||
| 324 | |||
| 325 | if (copy_from_user(range, (void __user *)arg, sizeof(range))) | ||
| 326 | return -EFAULT; | ||
| 327 | |||
| 328 | return blk_ioctl_zeroout(bdev, range[0], range[1]); | ||
| 329 | } | ||
| 303 | 330 | ||
| 304 | case HDIO_GETGEO: { | 331 | case HDIO_GETGEO: { |
| 305 | struct hd_geometry geo; | 332 | struct hd_geometry geo; |
diff --git a/include/linux/fs.h b/include/linux/fs.h index aa110476a95b..bd6f6e7ca48e 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -335,6 +335,7 @@ struct inodes_stat_t { | |||
| 335 | #define BLKDISCARDZEROES _IO(0x12,124) | 335 | #define BLKDISCARDZEROES _IO(0x12,124) |
| 336 | #define BLKSECDISCARD _IO(0x12,125) | 336 | #define BLKSECDISCARD _IO(0x12,125) |
| 337 | #define BLKROTATIONAL _IO(0x12,126) | 337 | #define BLKROTATIONAL _IO(0x12,126) |
| 338 | #define BLKZEROOUT _IO(0x12,127) | ||
| 338 | 339 | ||
| 339 | #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ | 340 | #define BMAP_IOCTL 1 /* obsolete - kept for compatibility */ |
| 340 | #define FIBMAP _IO(0x00,1) /* bmap access */ | 341 | #define FIBMAP _IO(0x00,1) /* bmap access */ |
