0001
0002 #include <linux/capability.h>
0003 #include <linux/compat.h>
0004 #include <linux/blkdev.h>
0005 #include <linux/export.h>
0006 #include <linux/gfp.h>
0007 #include <linux/blkpg.h>
0008 #include <linux/hdreg.h>
0009 #include <linux/backing-dev.h>
0010 #include <linux/fs.h>
0011 #include <linux/blktrace_api.h>
0012 #include <linux/pr.h>
0013 #include <linux/uaccess.h>
0014 #include "blk.h"
0015
0016 static int blkpg_do_ioctl(struct block_device *bdev,
0017 struct blkpg_partition __user *upart, int op)
0018 {
0019 struct gendisk *disk = bdev->bd_disk;
0020 struct blkpg_partition p;
0021 long long start, length;
0022
0023 if (!capable(CAP_SYS_ADMIN))
0024 return -EACCES;
0025 if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
0026 return -EFAULT;
0027 if (bdev_is_partition(bdev))
0028 return -EINVAL;
0029
0030 if (p.pno <= 0)
0031 return -EINVAL;
0032
0033 if (op == BLKPG_DEL_PARTITION)
0034 return bdev_del_partition(disk, p.pno);
0035
0036 start = p.start >> SECTOR_SHIFT;
0037 length = p.length >> SECTOR_SHIFT;
0038
0039 switch (op) {
0040 case BLKPG_ADD_PARTITION:
0041
0042 if (p.start & (bdev_logical_block_size(bdev) - 1))
0043 return -EINVAL;
0044 return bdev_add_partition(disk, p.pno, start, length);
0045 case BLKPG_RESIZE_PARTITION:
0046 return bdev_resize_partition(disk, p.pno, start, length);
0047 default:
0048 return -EINVAL;
0049 }
0050 }
0051
0052 static int blkpg_ioctl(struct block_device *bdev,
0053 struct blkpg_ioctl_arg __user *arg)
0054 {
0055 struct blkpg_partition __user *udata;
0056 int op;
0057
0058 if (get_user(op, &arg->op) || get_user(udata, &arg->data))
0059 return -EFAULT;
0060
0061 return blkpg_do_ioctl(bdev, udata, op);
0062 }
0063
0064 #ifdef CONFIG_COMPAT
0065 struct compat_blkpg_ioctl_arg {
0066 compat_int_t op;
0067 compat_int_t flags;
0068 compat_int_t datalen;
0069 compat_caddr_t data;
0070 };
0071
0072 static int compat_blkpg_ioctl(struct block_device *bdev,
0073 struct compat_blkpg_ioctl_arg __user *arg)
0074 {
0075 compat_caddr_t udata;
0076 int op;
0077
0078 if (get_user(op, &arg->op) || get_user(udata, &arg->data))
0079 return -EFAULT;
0080
0081 return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
0082 }
0083 #endif
0084
0085 static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
0086 unsigned long arg)
0087 {
0088 uint64_t range[2];
0089 uint64_t start, len;
0090 struct inode *inode = bdev->bd_inode;
0091 int err;
0092
0093 if (!(mode & FMODE_WRITE))
0094 return -EBADF;
0095
0096 if (!bdev_max_discard_sectors(bdev))
0097 return -EOPNOTSUPP;
0098
0099 if (copy_from_user(range, (void __user *)arg, sizeof(range)))
0100 return -EFAULT;
0101
0102 start = range[0];
0103 len = range[1];
0104
0105 if (start & 511)
0106 return -EINVAL;
0107 if (len & 511)
0108 return -EINVAL;
0109
0110 if (start + len > bdev_nr_bytes(bdev))
0111 return -EINVAL;
0112
0113 filemap_invalidate_lock(inode->i_mapping);
0114 err = truncate_bdev_range(bdev, mode, start, start + len - 1);
0115 if (err)
0116 goto fail;
0117 err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
0118 fail:
0119 filemap_invalidate_unlock(inode->i_mapping);
0120 return err;
0121 }
0122
0123 static int blk_ioctl_secure_erase(struct block_device *bdev, fmode_t mode,
0124 void __user *argp)
0125 {
0126 uint64_t start, len;
0127 uint64_t range[2];
0128 int err;
0129
0130 if (!(mode & FMODE_WRITE))
0131 return -EBADF;
0132 if (!bdev_max_secure_erase_sectors(bdev))
0133 return -EOPNOTSUPP;
0134 if (copy_from_user(range, argp, sizeof(range)))
0135 return -EFAULT;
0136
0137 start = range[0];
0138 len = range[1];
0139 if ((start & 511) || (len & 511))
0140 return -EINVAL;
0141 if (start + len > bdev_nr_bytes(bdev))
0142 return -EINVAL;
0143
0144 filemap_invalidate_lock(bdev->bd_inode->i_mapping);
0145 err = truncate_bdev_range(bdev, mode, start, start + len - 1);
0146 if (!err)
0147 err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
0148 GFP_KERNEL);
0149 filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
0150 return err;
0151 }
0152
0153
0154 static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
0155 unsigned long arg)
0156 {
0157 uint64_t range[2];
0158 uint64_t start, end, len;
0159 struct inode *inode = bdev->bd_inode;
0160 int err;
0161
0162 if (!(mode & FMODE_WRITE))
0163 return -EBADF;
0164
0165 if (copy_from_user(range, (void __user *)arg, sizeof(range)))
0166 return -EFAULT;
0167
0168 start = range[0];
0169 len = range[1];
0170 end = start + len - 1;
0171
0172 if (start & 511)
0173 return -EINVAL;
0174 if (len & 511)
0175 return -EINVAL;
0176 if (end >= (uint64_t)bdev_nr_bytes(bdev))
0177 return -EINVAL;
0178 if (end < start)
0179 return -EINVAL;
0180
0181
0182 filemap_invalidate_lock(inode->i_mapping);
0183 err = truncate_bdev_range(bdev, mode, start, end);
0184 if (err)
0185 goto fail;
0186
0187 err = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
0188 BLKDEV_ZERO_NOUNMAP);
0189
0190 fail:
0191 filemap_invalidate_unlock(inode->i_mapping);
0192 return err;
0193 }
0194
0195 static int put_ushort(unsigned short __user *argp, unsigned short val)
0196 {
0197 return put_user(val, argp);
0198 }
0199
0200 static int put_int(int __user *argp, int val)
0201 {
0202 return put_user(val, argp);
0203 }
0204
0205 static int put_uint(unsigned int __user *argp, unsigned int val)
0206 {
0207 return put_user(val, argp);
0208 }
0209
0210 static int put_long(long __user *argp, long val)
0211 {
0212 return put_user(val, argp);
0213 }
0214
0215 static int put_ulong(unsigned long __user *argp, unsigned long val)
0216 {
0217 return put_user(val, argp);
0218 }
0219
0220 static int put_u64(u64 __user *argp, u64 val)
0221 {
0222 return put_user(val, argp);
0223 }
0224
0225 #ifdef CONFIG_COMPAT
0226 static int compat_put_long(compat_long_t __user *argp, long val)
0227 {
0228 return put_user(val, argp);
0229 }
0230
0231 static int compat_put_ulong(compat_ulong_t __user *argp, compat_ulong_t val)
0232 {
0233 return put_user(val, argp);
0234 }
0235 #endif
0236
0237 #ifdef CONFIG_COMPAT
0238
0239
0240
0241
0242
0243 int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode,
0244 unsigned cmd, unsigned long arg)
0245 {
0246 struct gendisk *disk = bdev->bd_disk;
0247
0248 if (disk->fops->ioctl)
0249 return disk->fops->ioctl(bdev, mode, cmd,
0250 (unsigned long)compat_ptr(arg));
0251
0252 return -ENOIOCTLCMD;
0253 }
0254 EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
0255 #endif
0256
0257 static int blkdev_pr_register(struct block_device *bdev,
0258 struct pr_registration __user *arg)
0259 {
0260 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
0261 struct pr_registration reg;
0262
0263 if (!capable(CAP_SYS_ADMIN))
0264 return -EPERM;
0265 if (!ops || !ops->pr_register)
0266 return -EOPNOTSUPP;
0267 if (copy_from_user(®, arg, sizeof(reg)))
0268 return -EFAULT;
0269
0270 if (reg.flags & ~PR_FL_IGNORE_KEY)
0271 return -EOPNOTSUPP;
0272 return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags);
0273 }
0274
0275 static int blkdev_pr_reserve(struct block_device *bdev,
0276 struct pr_reservation __user *arg)
0277 {
0278 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
0279 struct pr_reservation rsv;
0280
0281 if (!capable(CAP_SYS_ADMIN))
0282 return -EPERM;
0283 if (!ops || !ops->pr_reserve)
0284 return -EOPNOTSUPP;
0285 if (copy_from_user(&rsv, arg, sizeof(rsv)))
0286 return -EFAULT;
0287
0288 if (rsv.flags & ~PR_FL_IGNORE_KEY)
0289 return -EOPNOTSUPP;
0290 return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags);
0291 }
0292
0293 static int blkdev_pr_release(struct block_device *bdev,
0294 struct pr_reservation __user *arg)
0295 {
0296 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
0297 struct pr_reservation rsv;
0298
0299 if (!capable(CAP_SYS_ADMIN))
0300 return -EPERM;
0301 if (!ops || !ops->pr_release)
0302 return -EOPNOTSUPP;
0303 if (copy_from_user(&rsv, arg, sizeof(rsv)))
0304 return -EFAULT;
0305
0306 if (rsv.flags)
0307 return -EOPNOTSUPP;
0308 return ops->pr_release(bdev, rsv.key, rsv.type);
0309 }
0310
0311 static int blkdev_pr_preempt(struct block_device *bdev,
0312 struct pr_preempt __user *arg, bool abort)
0313 {
0314 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
0315 struct pr_preempt p;
0316
0317 if (!capable(CAP_SYS_ADMIN))
0318 return -EPERM;
0319 if (!ops || !ops->pr_preempt)
0320 return -EOPNOTSUPP;
0321 if (copy_from_user(&p, arg, sizeof(p)))
0322 return -EFAULT;
0323
0324 if (p.flags)
0325 return -EOPNOTSUPP;
0326 return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort);
0327 }
0328
0329 static int blkdev_pr_clear(struct block_device *bdev,
0330 struct pr_clear __user *arg)
0331 {
0332 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
0333 struct pr_clear c;
0334
0335 if (!capable(CAP_SYS_ADMIN))
0336 return -EPERM;
0337 if (!ops || !ops->pr_clear)
0338 return -EOPNOTSUPP;
0339 if (copy_from_user(&c, arg, sizeof(c)))
0340 return -EFAULT;
0341
0342 if (c.flags)
0343 return -EOPNOTSUPP;
0344 return ops->pr_clear(bdev, c.key);
0345 }
0346
0347 static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
0348 unsigned cmd, unsigned long arg)
0349 {
0350 if (!capable(CAP_SYS_ADMIN))
0351 return -EACCES;
0352 fsync_bdev(bdev);
0353 invalidate_bdev(bdev);
0354 return 0;
0355 }
0356
0357 static int blkdev_roset(struct block_device *bdev, fmode_t mode,
0358 unsigned cmd, unsigned long arg)
0359 {
0360 int ret, n;
0361
0362 if (!capable(CAP_SYS_ADMIN))
0363 return -EACCES;
0364
0365 if (get_user(n, (int __user *)arg))
0366 return -EFAULT;
0367 if (bdev->bd_disk->fops->set_read_only) {
0368 ret = bdev->bd_disk->fops->set_read_only(bdev, n);
0369 if (ret)
0370 return ret;
0371 }
0372 bdev->bd_read_only = n;
0373 return 0;
0374 }
0375
0376 static int blkdev_getgeo(struct block_device *bdev,
0377 struct hd_geometry __user *argp)
0378 {
0379 struct gendisk *disk = bdev->bd_disk;
0380 struct hd_geometry geo;
0381 int ret;
0382
0383 if (!argp)
0384 return -EINVAL;
0385 if (!disk->fops->getgeo)
0386 return -ENOTTY;
0387
0388
0389
0390
0391
0392 memset(&geo, 0, sizeof(geo));
0393 geo.start = get_start_sect(bdev);
0394 ret = disk->fops->getgeo(bdev, &geo);
0395 if (ret)
0396 return ret;
0397 if (copy_to_user(argp, &geo, sizeof(geo)))
0398 return -EFAULT;
0399 return 0;
0400 }
0401
0402 #ifdef CONFIG_COMPAT
0403 struct compat_hd_geometry {
0404 unsigned char heads;
0405 unsigned char sectors;
0406 unsigned short cylinders;
0407 u32 start;
0408 };
0409
0410 static int compat_hdio_getgeo(struct block_device *bdev,
0411 struct compat_hd_geometry __user *ugeo)
0412 {
0413 struct gendisk *disk = bdev->bd_disk;
0414 struct hd_geometry geo;
0415 int ret;
0416
0417 if (!ugeo)
0418 return -EINVAL;
0419 if (!disk->fops->getgeo)
0420 return -ENOTTY;
0421
0422 memset(&geo, 0, sizeof(geo));
0423
0424
0425
0426
0427 geo.start = get_start_sect(bdev);
0428 ret = disk->fops->getgeo(bdev, &geo);
0429 if (ret)
0430 return ret;
0431
0432 ret = copy_to_user(ugeo, &geo, 4);
0433 ret |= put_user(geo.start, &ugeo->start);
0434 if (ret)
0435 ret = -EFAULT;
0436
0437 return ret;
0438 }
0439 #endif
0440
0441
0442 static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
0443 int __user *argp)
0444 {
0445 int ret, n;
0446
0447 if (!capable(CAP_SYS_ADMIN))
0448 return -EACCES;
0449 if (!argp)
0450 return -EINVAL;
0451 if (get_user(n, argp))
0452 return -EFAULT;
0453
0454 if (mode & FMODE_EXCL)
0455 return set_blocksize(bdev, n);
0456
0457 if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode | FMODE_EXCL, &bdev)))
0458 return -EBUSY;
0459 ret = set_blocksize(bdev, n);
0460 blkdev_put(bdev, mode | FMODE_EXCL);
0461
0462 return ret;
0463 }
0464
0465
0466
0467
0468
0469
0470 static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
0471 unsigned cmd, unsigned long arg, void __user *argp)
0472 {
0473 unsigned int max_sectors;
0474
0475 switch (cmd) {
0476 case BLKFLSBUF:
0477 return blkdev_flushbuf(bdev, mode, cmd, arg);
0478 case BLKROSET:
0479 return blkdev_roset(bdev, mode, cmd, arg);
0480 case BLKDISCARD:
0481 return blk_ioctl_discard(bdev, mode, arg);
0482 case BLKSECDISCARD:
0483 return blk_ioctl_secure_erase(bdev, mode, argp);
0484 case BLKZEROOUT:
0485 return blk_ioctl_zeroout(bdev, mode, arg);
0486 case BLKGETDISKSEQ:
0487 return put_u64(argp, bdev->bd_disk->diskseq);
0488 case BLKREPORTZONE:
0489 return blkdev_report_zones_ioctl(bdev, mode, cmd, arg);
0490 case BLKRESETZONE:
0491 case BLKOPENZONE:
0492 case BLKCLOSEZONE:
0493 case BLKFINISHZONE:
0494 return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg);
0495 case BLKGETZONESZ:
0496 return put_uint(argp, bdev_zone_sectors(bdev));
0497 case BLKGETNRZONES:
0498 return put_uint(argp, bdev_nr_zones(bdev));
0499 case BLKROGET:
0500 return put_int(argp, bdev_read_only(bdev) != 0);
0501 case BLKSSZGET:
0502 return put_int(argp, bdev_logical_block_size(bdev));
0503 case BLKPBSZGET:
0504 return put_uint(argp, bdev_physical_block_size(bdev));
0505 case BLKIOMIN:
0506 return put_uint(argp, bdev_io_min(bdev));
0507 case BLKIOOPT:
0508 return put_uint(argp, bdev_io_opt(bdev));
0509 case BLKALIGNOFF:
0510 return put_int(argp, bdev_alignment_offset(bdev));
0511 case BLKDISCARDZEROES:
0512 return put_uint(argp, 0);
0513 case BLKSECTGET:
0514 max_sectors = min_t(unsigned int, USHRT_MAX,
0515 queue_max_sectors(bdev_get_queue(bdev)));
0516 return put_ushort(argp, max_sectors);
0517 case BLKROTATIONAL:
0518 return put_ushort(argp, !bdev_nonrot(bdev));
0519 case BLKRASET:
0520 case BLKFRASET:
0521 if(!capable(CAP_SYS_ADMIN))
0522 return -EACCES;
0523 bdev->bd_disk->bdi->ra_pages = (arg * 512) / PAGE_SIZE;
0524 return 0;
0525 case BLKRRPART:
0526 if (!capable(CAP_SYS_ADMIN))
0527 return -EACCES;
0528 if (bdev_is_partition(bdev))
0529 return -EINVAL;
0530 return disk_scan_partitions(bdev->bd_disk, mode & ~FMODE_EXCL);
0531 case BLKTRACESTART:
0532 case BLKTRACESTOP:
0533 case BLKTRACETEARDOWN:
0534 return blk_trace_ioctl(bdev, cmd, argp);
0535 case IOC_PR_REGISTER:
0536 return blkdev_pr_register(bdev, argp);
0537 case IOC_PR_RESERVE:
0538 return blkdev_pr_reserve(bdev, argp);
0539 case IOC_PR_RELEASE:
0540 return blkdev_pr_release(bdev, argp);
0541 case IOC_PR_PREEMPT:
0542 return blkdev_pr_preempt(bdev, argp, false);
0543 case IOC_PR_PREEMPT_ABORT:
0544 return blkdev_pr_preempt(bdev, argp, true);
0545 case IOC_PR_CLEAR:
0546 return blkdev_pr_clear(bdev, argp);
0547 default:
0548 return -ENOIOCTLCMD;
0549 }
0550 }
0551
0552
0553
0554
0555
0556
0557
0558 long blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
0559 {
0560 struct block_device *bdev = I_BDEV(file->f_mapping->host);
0561 void __user *argp = (void __user *)arg;
0562 fmode_t mode = file->f_mode;
0563 int ret;
0564
0565
0566
0567
0568
0569 if (file->f_flags & O_NDELAY)
0570 mode |= FMODE_NDELAY;
0571 else
0572 mode &= ~FMODE_NDELAY;
0573
0574 switch (cmd) {
0575
0576 case HDIO_GETGEO:
0577 return blkdev_getgeo(bdev, argp);
0578 case BLKPG:
0579 return blkpg_ioctl(bdev, argp);
0580
0581
0582 case BLKRAGET:
0583 case BLKFRAGET:
0584 if (!argp)
0585 return -EINVAL;
0586 return put_long(argp,
0587 (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512);
0588 case BLKGETSIZE:
0589 if (bdev_nr_sectors(bdev) > ~0UL)
0590 return -EFBIG;
0591 return put_ulong(argp, bdev_nr_sectors(bdev));
0592
0593
0594 case BLKBSZGET:
0595 return put_int(argp, block_size(bdev));
0596 case BLKBSZSET:
0597 return blkdev_bszset(bdev, mode, argp);
0598 case BLKGETSIZE64:
0599 return put_u64(argp, bdev_nr_bytes(bdev));
0600
0601
0602 case BLKTRACESETUP:
0603 return blk_trace_ioctl(bdev, cmd, argp);
0604 default:
0605 break;
0606 }
0607
0608 ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
0609 if (ret != -ENOIOCTLCMD)
0610 return ret;
0611
0612 if (!bdev->bd_disk->fops->ioctl)
0613 return -ENOTTY;
0614 return bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg);
0615 }
0616
0617 #ifdef CONFIG_COMPAT
0618
0619 #define BLKBSZGET_32 _IOR(0x12, 112, int)
0620 #define BLKBSZSET_32 _IOW(0x12, 113, int)
0621 #define BLKGETSIZE64_32 _IOR(0x12, 114, int)
0622
0623
0624
0625
0626 long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
0627 {
0628 int ret;
0629 void __user *argp = compat_ptr(arg);
0630 struct block_device *bdev = I_BDEV(file->f_mapping->host);
0631 struct gendisk *disk = bdev->bd_disk;
0632 fmode_t mode = file->f_mode;
0633
0634
0635
0636
0637
0638 if (file->f_flags & O_NDELAY)
0639 mode |= FMODE_NDELAY;
0640 else
0641 mode &= ~FMODE_NDELAY;
0642
0643 switch (cmd) {
0644
0645 case HDIO_GETGEO:
0646 return compat_hdio_getgeo(bdev, argp);
0647 case BLKPG:
0648 return compat_blkpg_ioctl(bdev, argp);
0649
0650
0651 case BLKRAGET:
0652 case BLKFRAGET:
0653 if (!argp)
0654 return -EINVAL;
0655 return compat_put_long(argp,
0656 (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512);
0657 case BLKGETSIZE:
0658 if (bdev_nr_sectors(bdev) > ~(compat_ulong_t)0)
0659 return -EFBIG;
0660 return compat_put_ulong(argp, bdev_nr_sectors(bdev));
0661
0662
0663 case BLKBSZGET_32:
0664 return put_int(argp, bdev_logical_block_size(bdev));
0665 case BLKBSZSET_32:
0666 return blkdev_bszset(bdev, mode, argp);
0667 case BLKGETSIZE64_32:
0668 return put_u64(argp, bdev_nr_bytes(bdev));
0669
0670
0671 case BLKTRACESETUP32:
0672 return blk_trace_ioctl(bdev, cmd, argp);
0673 default:
0674 break;
0675 }
0676
0677 ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
0678 if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
0679 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
0680
0681 return ret;
0682 }
0683 #endif