Lines Matching +full:mode +full:- +full:capable
1 // SPDX-License-Identifier: GPL-2.0
9 #include <linux/backing-dev.h>
22 struct gendisk *disk = bdev->bd_disk; in blkpg_do_ioctl()
26 if (!capable(CAP_SYS_ADMIN)) in blkpg_do_ioctl()
27 return -EACCES; in blkpg_do_ioctl()
29 return -EFAULT; in blkpg_do_ioctl()
31 return -EINVAL; in blkpg_do_ioctl()
34 return -EINVAL; in blkpg_do_ioctl()
39 if (p.start < 0 || p.length <= 0 || LLONG_MAX - p.length < p.start) in blkpg_do_ioctl()
40 return -EINVAL; in blkpg_do_ioctl()
43 return -EINVAL; in blkpg_do_ioctl()
50 return -EINVAL; in blkpg_do_ioctl()
53 return -EINVAL; in blkpg_do_ioctl()
61 return -EINVAL; in blkpg_do_ioctl()
71 if (get_user(op, &arg->op) || get_user(udata, &arg->data)) in blkpg_ioctl()
72 return -EFAULT; in blkpg_ioctl()
91 if (get_user(op, &arg->op) || get_user(udata, &arg->data)) in compat_blkpg_ioctl()
92 return -EFAULT; in compat_blkpg_ioctl()
106 unsigned int bs_mask = bdev_logical_block_size(bdev) - 1; in blk_validate_byte_range()
110 return -EINVAL; in blk_validate_byte_range()
112 return -EINVAL; in blk_validate_byte_range()
114 return -EINVAL; in blk_validate_byte_range()
119 static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode, in blk_ioctl_discard() argument
129 return -EFAULT; in blk_ioctl_discard()
134 return -EOPNOTSUPP; in blk_ioctl_discard()
136 if (!(mode & BLK_OPEN_WRITE)) in blk_ioctl_discard()
137 return -EBADF; in blk_ioctl_discard()
139 return -EPERM; in blk_ioctl_discard()
144 filemap_invalidate_lock(bdev->bd_mapping); in blk_ioctl_discard()
145 err = truncate_bdev_range(bdev, mode, start, start + len - 1); in blk_ioctl_discard()
157 err = -EINTR; in blk_ioctl_discard()
168 if (err == -EOPNOTSUPP) in blk_ioctl_discard()
175 filemap_invalidate_unlock(bdev->bd_mapping); in blk_ioctl_discard()
179 static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode, in blk_ioctl_secure_erase() argument
186 if (!(mode & BLK_OPEN_WRITE)) in blk_ioctl_secure_erase()
187 return -EBADF; in blk_ioctl_secure_erase()
189 return -EOPNOTSUPP; in blk_ioctl_secure_erase()
191 return -EFAULT; in blk_ioctl_secure_erase()
196 return -EINVAL; in blk_ioctl_secure_erase()
199 return -EINVAL; in blk_ioctl_secure_erase()
201 filemap_invalidate_lock(bdev->bd_mapping); in blk_ioctl_secure_erase()
202 err = truncate_bdev_range(bdev, mode, start, end - 1); in blk_ioctl_secure_erase()
206 filemap_invalidate_unlock(bdev->bd_mapping); in blk_ioctl_secure_erase()
211 static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode, in blk_ioctl_zeroout() argument
218 if (!(mode & BLK_OPEN_WRITE)) in blk_ioctl_zeroout()
219 return -EBADF; in blk_ioctl_zeroout()
222 return -EFAULT; in blk_ioctl_zeroout()
226 end = start + len - 1; in blk_ioctl_zeroout()
229 return -EINVAL; in blk_ioctl_zeroout()
231 return -EINVAL; in blk_ioctl_zeroout()
233 return -EINVAL; in blk_ioctl_zeroout()
235 return -EINVAL; in blk_ioctl_zeroout()
238 filemap_invalidate_lock(bdev->bd_mapping); in blk_ioctl_zeroout()
239 err = truncate_bdev_range(bdev, mode, start, end); in blk_ioctl_zeroout()
247 filemap_invalidate_unlock(bdev->bd_mapping); in blk_ioctl_zeroout()
297 * between 32-bit and 64-bit user space
299 int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode, in blkdev_compat_ptr_ioctl() argument
302 struct gendisk *disk = bdev->bd_disk; in blkdev_compat_ptr_ioctl()
304 if (disk->fops->ioctl) in blkdev_compat_ptr_ioctl()
305 return disk->fops->ioctl(bdev, mode, cmd, in blkdev_compat_ptr_ioctl()
308 return -ENOIOCTLCMD; in blkdev_compat_ptr_ioctl()
313 static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode) in blkdev_pr_allowed() argument
319 if (capable(CAP_SYS_ADMIN)) in blkdev_pr_allowed()
325 return mode & BLK_OPEN_WRITE; in blkdev_pr_allowed()
328 static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode, in blkdev_pr_register() argument
331 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; in blkdev_pr_register()
334 if (!blkdev_pr_allowed(bdev, mode)) in blkdev_pr_register()
335 return -EPERM; in blkdev_pr_register()
336 if (!ops || !ops->pr_register) in blkdev_pr_register()
337 return -EOPNOTSUPP; in blkdev_pr_register()
339 return -EFAULT; in blkdev_pr_register()
342 return -EOPNOTSUPP; in blkdev_pr_register()
343 return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags); in blkdev_pr_register()
346 static int blkdev_pr_reserve(struct block_device *bdev, blk_mode_t mode, in blkdev_pr_reserve() argument
349 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; in blkdev_pr_reserve()
352 if (!blkdev_pr_allowed(bdev, mode)) in blkdev_pr_reserve()
353 return -EPERM; in blkdev_pr_reserve()
354 if (!ops || !ops->pr_reserve) in blkdev_pr_reserve()
355 return -EOPNOTSUPP; in blkdev_pr_reserve()
357 return -EFAULT; in blkdev_pr_reserve()
360 return -EOPNOTSUPP; in blkdev_pr_reserve()
361 return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags); in blkdev_pr_reserve()
364 static int blkdev_pr_release(struct block_device *bdev, blk_mode_t mode, in blkdev_pr_release() argument
367 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; in blkdev_pr_release()
370 if (!blkdev_pr_allowed(bdev, mode)) in blkdev_pr_release()
371 return -EPERM; in blkdev_pr_release()
372 if (!ops || !ops->pr_release) in blkdev_pr_release()
373 return -EOPNOTSUPP; in blkdev_pr_release()
375 return -EFAULT; in blkdev_pr_release()
378 return -EOPNOTSUPP; in blkdev_pr_release()
379 return ops->pr_release(bdev, rsv.key, rsv.type); in blkdev_pr_release()
382 static int blkdev_pr_preempt(struct block_device *bdev, blk_mode_t mode, in blkdev_pr_preempt() argument
385 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; in blkdev_pr_preempt()
388 if (!blkdev_pr_allowed(bdev, mode)) in blkdev_pr_preempt()
389 return -EPERM; in blkdev_pr_preempt()
390 if (!ops || !ops->pr_preempt) in blkdev_pr_preempt()
391 return -EOPNOTSUPP; in blkdev_pr_preempt()
393 return -EFAULT; in blkdev_pr_preempt()
396 return -EOPNOTSUPP; in blkdev_pr_preempt()
397 return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort); in blkdev_pr_preempt()
400 static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode, in blkdev_pr_clear() argument
403 const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops; in blkdev_pr_clear()
406 if (!blkdev_pr_allowed(bdev, mode)) in blkdev_pr_clear()
407 return -EPERM; in blkdev_pr_clear()
408 if (!ops || !ops->pr_clear) in blkdev_pr_clear()
409 return -EOPNOTSUPP; in blkdev_pr_clear()
411 return -EFAULT; in blkdev_pr_clear()
414 return -EOPNOTSUPP; in blkdev_pr_clear()
415 return ops->pr_clear(bdev, c.key); in blkdev_pr_clear()
421 if (!capable(CAP_SYS_ADMIN)) in blkdev_flushbuf()
422 return -EACCES; in blkdev_flushbuf()
424 mutex_lock(&bdev->bd_holder_lock); in blkdev_flushbuf()
425 if (bdev->bd_holder_ops && bdev->bd_holder_ops->sync) in blkdev_flushbuf()
426 bdev->bd_holder_ops->sync(bdev); in blkdev_flushbuf()
428 mutex_unlock(&bdev->bd_holder_lock); in blkdev_flushbuf()
441 if (!capable(CAP_SYS_ADMIN)) in blkdev_roset()
442 return -EACCES; in blkdev_roset()
445 return -EFAULT; in blkdev_roset()
446 if (bdev->bd_disk->fops->set_read_only) { in blkdev_roset()
447 ret = bdev->bd_disk->fops->set_read_only(bdev, n); in blkdev_roset()
461 struct gendisk *disk = bdev->bd_disk; in blkdev_getgeo()
466 return -EINVAL; in blkdev_getgeo()
467 if (!disk->fops->getgeo) in blkdev_getgeo()
468 return -ENOTTY; in blkdev_getgeo()
476 ret = disk->fops->getgeo(bdev, &geo); in blkdev_getgeo()
480 return -EFAULT; in blkdev_getgeo()
495 struct gendisk *disk = bdev->bd_disk; in compat_hdio_getgeo()
500 return -EINVAL; in compat_hdio_getgeo()
501 if (!disk->fops->getgeo) in compat_hdio_getgeo()
502 return -ENOTTY; in compat_hdio_getgeo()
510 ret = disk->fops->getgeo(bdev, &geo); in compat_hdio_getgeo()
515 ret |= put_user(geo.start, &ugeo->start); in compat_hdio_getgeo()
517 ret = -EFAULT; in compat_hdio_getgeo()
524 static int blkdev_bszset(struct file *file, blk_mode_t mode, in blkdev_bszset() argument
527 // this one might be file_inode(file)->i_rdev - a rare valid in blkdev_bszset()
529 dev_t dev = I_BDEV(file->f_mapping->host)->bd_dev; in blkdev_bszset()
533 if (!capable(CAP_SYS_ADMIN)) in blkdev_bszset()
534 return -EACCES; in blkdev_bszset()
536 return -EINVAL; in blkdev_bszset()
538 return -EFAULT; in blkdev_bszset()
540 if (mode & BLK_OPEN_EXCL) in blkdev_bszset()
543 excl_file = bdev_file_open_by_dev(dev, mode, &dev, NULL); in blkdev_bszset()
545 return -EBUSY; in blkdev_bszset()
556 static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode, in blkdev_common_ioctl() argument
568 return blk_ioctl_discard(bdev, mode, arg); in blkdev_common_ioctl()
570 return blk_ioctl_secure_erase(bdev, mode, argp); in blkdev_common_ioctl()
572 return blk_ioctl_zeroout(bdev, mode, arg); in blkdev_common_ioctl()
574 return put_u64(argp, bdev->bd_disk->diskseq); in blkdev_common_ioctl()
581 return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg); in blkdev_common_ioctl()
608 if(!capable(CAP_SYS_ADMIN)) in blkdev_common_ioctl()
609 return -EACCES; in blkdev_common_ioctl()
610 bdev->bd_disk->bdi->ra_pages = (arg * 512) / PAGE_SIZE; in blkdev_common_ioctl()
613 if (!capable(CAP_SYS_ADMIN)) in blkdev_common_ioctl()
614 return -EACCES; in blkdev_common_ioctl()
616 return -EINVAL; in blkdev_common_ioctl()
617 return disk_scan_partitions(bdev->bd_disk, in blkdev_common_ioctl()
618 mode | BLK_OPEN_STRICT_SCAN); in blkdev_common_ioctl()
624 return blkdev_pr_register(bdev, mode, argp); in blkdev_common_ioctl()
626 return blkdev_pr_reserve(bdev, mode, argp); in blkdev_common_ioctl()
628 return blkdev_pr_release(bdev, mode, argp); in blkdev_common_ioctl()
630 return blkdev_pr_preempt(bdev, mode, argp, false); in blkdev_common_ioctl()
632 return blkdev_pr_preempt(bdev, mode, argp, true); in blkdev_common_ioctl()
634 return blkdev_pr_clear(bdev, mode, argp); in blkdev_common_ioctl()
636 return -ENOIOCTLCMD; in blkdev_common_ioctl()
648 struct block_device *bdev = I_BDEV(file->f_mapping->host); in blkdev_ioctl()
650 blk_mode_t mode = file_to_blk_mode(file); in blkdev_ioctl() local
660 /* Compat mode returns 32-bit data instead of 'long' */ in blkdev_ioctl()
664 return -EINVAL; in blkdev_ioctl()
666 (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512); in blkdev_ioctl()
669 return -EFBIG; in blkdev_ioctl()
676 return blkdev_bszset(file, mode, argp); in blkdev_ioctl()
687 ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp); in blkdev_ioctl()
688 if (ret != -ENOIOCTLCMD) in blkdev_ioctl()
691 if (!bdev->bd_disk->fops->ioctl) in blkdev_ioctl()
692 return -ENOTTY; in blkdev_ioctl()
693 return bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg); in blkdev_ioctl()
709 struct block_device *bdev = I_BDEV(file->f_mapping->host); in compat_blkdev_ioctl()
710 struct gendisk *disk = bdev->bd_disk; in compat_blkdev_ioctl()
711 blk_mode_t mode = file_to_blk_mode(file); in compat_blkdev_ioctl() local
720 /* Compat mode returns 32-bit data instead of 'long' */ in compat_blkdev_ioctl()
724 return -EINVAL; in compat_blkdev_ioctl()
726 (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512); in compat_blkdev_ioctl()
729 return -EFBIG; in compat_blkdev_ioctl()
736 return blkdev_bszset(file, mode, argp); in compat_blkdev_ioctl()
747 ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp); in compat_blkdev_ioctl()
748 if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl) in compat_blkdev_ioctl()
749 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg); in compat_blkdev_ioctl()
764 if (bic->res == -EAGAIN && bic->nowait) in blk_cmd_complete()
767 io_uring_cmd_done(cmd, bic->res, 0, issue_flags); in blk_cmd_complete()
772 struct io_uring_cmd *cmd = bio->bi_private; in bio_cmd_bio_end_io()
775 if (unlikely(bio->bi_status) && !bic->res) in bio_cmd_bio_end_io()
776 bic->res = blk_status_to_errno(bio->bi_status); in bio_cmd_bio_end_io()
794 return -EOPNOTSUPP; in blkdev_cmd_discard()
795 if (!(file_to_blk_mode(cmd->file) & BLK_OPEN_WRITE)) in blkdev_cmd_discard()
796 return -EBADF; in blkdev_cmd_discard()
798 return -EPERM; in blkdev_cmd_discard()
803 err = filemap_invalidate_pages(bdev->bd_mapping, start, in blkdev_cmd_discard()
804 start + len - 1, nowait); in blkdev_cmd_discard()
814 * Don't allow multi-bio non-blocking submissions as in blkdev_cmd_discard()
821 return -EAGAIN; in blkdev_cmd_discard()
823 bio->bi_opf |= REQ_NOWAIT; in blkdev_cmd_discard()
829 return -EAGAIN; in blkdev_cmd_discard()
831 bic->res = -EAGAIN; in blkdev_cmd_discard()
833 prev->bi_private = cmd; in blkdev_cmd_discard()
834 prev->bi_end_io = bio_cmd_bio_end_io; in blkdev_cmd_discard()
836 return -EIOCBQUEUED; in blkdev_cmd_discard()
841 struct block_device *bdev = I_BDEV(cmd->file->f_mapping->host); in blkdev_uring_cmd()
843 const struct io_uring_sqe *sqe = cmd->sqe; in blkdev_uring_cmd()
844 u32 cmd_op = cmd->cmd_op; in blkdev_uring_cmd()
847 if (unlikely(sqe->ioprio || sqe->__pad1 || sqe->len || in blkdev_uring_cmd()
848 sqe->rw_flags || sqe->file_index)) in blkdev_uring_cmd()
849 return -EINVAL; in blkdev_uring_cmd()
851 bic->res = 0; in blkdev_uring_cmd()
852 bic->nowait = issue_flags & IO_URING_F_NONBLOCK; in blkdev_uring_cmd()
854 start = READ_ONCE(sqe->addr); in blkdev_uring_cmd()
855 len = READ_ONCE(sqe->addr3); in blkdev_uring_cmd()
859 return blkdev_cmd_discard(cmd, bdev, start, len, bic->nowait); in blkdev_uring_cmd()
861 return -EINVAL; in blkdev_uring_cmd()