aboutsummaryrefslogtreecommitdiffstats
path: root/block/compat_ioctl.c
diff options
context:
space:
mode:
authorAl Viro <al@aretha.pdmi.ras.ru>2008-09-18 15:53:24 -0400
committerAl Viro <viro@zeniv.linux.org.uk>2008-10-21 07:49:10 -0400
commit45048d0961cdbf7ddfba906797ad8cb42489e070 (patch)
treed471933ccf9e8c52f608d0cef88de0569982a933 /block/compat_ioctl.c
parente436fdae70a31102d2be32969b80fe8545edebd9 (diff)
[PATCH] get rid of blkdev_locked_ioctl()
Most of that stuff doesn't need BKL at all; expand in the (only) caller, merge the switch into one there and leave BKL only around the stuff that might actually need it. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'block/compat_ioctl.c')
-rw-r--r--block/compat_ioctl.c101
1 files changed, 49 insertions, 52 deletions
diff --git a/block/compat_ioctl.c b/block/compat_ioctl.c
index 504344d29022..5b3db0640d87 100644
--- a/block/compat_ioctl.c
+++ b/block/compat_ioctl.c
@@ -688,12 +688,40 @@ static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
688 return __blkdev_driver_ioctl(bdev, mode, cmd, arg); 688 return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
689} 689}
690 690
691static int compat_blkdev_locked_ioctl(struct block_device *bdev, 691/* Most of the generic ioctls are handled in the normal fallback path.
692 unsigned cmd, unsigned long arg) 692 This assumes the blkdev's low level compat_ioctl always returns
693 ENOIOCTLCMD for unknown ioctls. */
694long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
693{ 695{
696 int ret = -ENOIOCTLCMD;
697 struct inode *inode = file->f_mapping->host;
698 struct block_device *bdev = inode->i_bdev;
699 struct gendisk *disk = bdev->bd_disk;
700 fmode_t mode = file->f_mode;
694 struct backing_dev_info *bdi; 701 struct backing_dev_info *bdi;
702 loff_t size;
703
704 if (file->f_flags & O_NDELAY)
705 mode |= FMODE_NDELAY_NOW;
695 706
696 switch (cmd) { 707 switch (cmd) {
708 case HDIO_GETGEO:
709 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
710 case BLKFLSBUF:
711 case BLKROSET:
712 case BLKDISCARD:
713 /*
714 * the ones below are implemented in blkdev_locked_ioctl,
715 * but we call blkdev_ioctl, which gets the lock for us
716 */
717 case BLKRRPART:
718 return blkdev_ioctl(inode, file, cmd,
719 (unsigned long)compat_ptr(arg));
720 case BLKBSZSET_32:
721 return blkdev_ioctl(inode, file, BLKBSZSET,
722 (unsigned long)compat_ptr(arg));
723 case BLKPG:
724 return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg));
697 case BLKRAGET: 725 case BLKRAGET:
698 case BLKFRAGET: 726 case BLKFRAGET:
699 if (!arg) 727 if (!arg)
@@ -719,67 +747,36 @@ static int compat_blkdev_locked_ioctl(struct block_device *bdev,
719 bdi = blk_get_backing_dev_info(bdev); 747 bdi = blk_get_backing_dev_info(bdev);
720 if (bdi == NULL) 748 if (bdi == NULL)
721 return -ENOTTY; 749 return -ENOTTY;
750 lock_kernel();
722 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE; 751 bdi->ra_pages = (arg * 512) / PAGE_CACHE_SIZE;
752 unlock_kernel();
723 return 0; 753 return 0;
724 case BLKGETSIZE: 754 case BLKGETSIZE:
725 if ((bdev->bd_inode->i_size >> 9) > ~0UL) 755 size = bdev->bd_inode->i_size;
756 if ((size >> 9) > ~0UL)
726 return -EFBIG; 757 return -EFBIG;
727 return compat_put_ulong(arg, bdev->bd_inode->i_size >> 9); 758 return compat_put_ulong(arg, size >> 9);
728 759
729 case BLKGETSIZE64_32: 760 case BLKGETSIZE64_32:
730 return compat_put_u64(arg, bdev->bd_inode->i_size); 761 return compat_put_u64(arg, bdev->bd_inode->i_size);
731 762
732 case BLKTRACESETUP32: 763 case BLKTRACESETUP32:
733 return compat_blk_trace_setup(bdev, compat_ptr(arg)); 764 lock_kernel();
765 ret = compat_blk_trace_setup(bdev, compat_ptr(arg));
766 unlock_kernel();
767 return ret;
734 case BLKTRACESTART: /* compatible */ 768 case BLKTRACESTART: /* compatible */
735 case BLKTRACESTOP: /* compatible */ 769 case BLKTRACESTOP: /* compatible */
736 case BLKTRACETEARDOWN: /* compatible */ 770 case BLKTRACETEARDOWN: /* compatible */
737 return blk_trace_ioctl(bdev, cmd, compat_ptr(arg)); 771 lock_kernel();
738 } 772 ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
739 return -ENOIOCTLCMD; 773 unlock_kernel();
740}
741
742/* Most of the generic ioctls are handled in the normal fallback path.
743 This assumes the blkdev's low level compat_ioctl always returns
744 ENOIOCTLCMD for unknown ioctls. */
745long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
746{
747 int ret = -ENOIOCTLCMD;
748 struct inode *inode = file->f_mapping->host;
749 struct block_device *bdev = inode->i_bdev;
750 struct gendisk *disk = bdev->bd_disk;
751 fmode_t mode = file->f_mode;
752 if (file->f_flags & O_NDELAY)
753 mode |= FMODE_NDELAY_NOW;
754
755 switch (cmd) {
756 case HDIO_GETGEO:
757 return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
758 case BLKFLSBUF:
759 case BLKROSET:
760 case BLKDISCARD:
761 /*
762 * the ones below are implemented in blkdev_locked_ioctl,
763 * but we call blkdev_ioctl, which gets the lock for us
764 */
765 case BLKRRPART:
766 return blkdev_ioctl(inode, file, cmd,
767 (unsigned long)compat_ptr(arg));
768 case BLKBSZSET_32:
769 return blkdev_ioctl(inode, file, BLKBSZSET,
770 (unsigned long)compat_ptr(arg));
771 case BLKPG:
772 return compat_blkpg_ioctl(inode, file, cmd, compat_ptr(arg));
773 }
774
775 lock_kernel();
776 ret = compat_blkdev_locked_ioctl(bdev, cmd, arg);
777 unlock_kernel();
778 if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
779 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
780
781 if (ret != -ENOIOCTLCMD)
782 return ret; 774 return ret;
783 775 default:
784 return compat_blkdev_driver_ioctl(bdev, mode, cmd, arg); 776 if (disk->fops->compat_ioctl)
777 ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
778 if (ret == -ENOIOCTLCMD)
779 ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
780 return ret;
781 }
785} 782}