block: remove i_bdev
[linux-2.6-microblaze.git] / block / ioctl.c
index bdb3bbb..a6d8171 100644 (file)
@@ -23,7 +23,7 @@ static int blkpg_do_ioctl(struct block_device *bdev,
                return -EACCES;
        if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
                return -EFAULT;
-       if (bdev != bdev->bd_contains)
+       if (bdev_is_partition(bdev))
                return -EINVAL;
 
        if (p.pno <= 0)
@@ -35,15 +35,6 @@ static int blkpg_do_ioctl(struct block_device *bdev,
        start = p.start >> SECTOR_SHIFT;
        length = p.length >> SECTOR_SHIFT;
 
-       /* check for fit in a hd_struct */
-       if (sizeof(sector_t) < sizeof(long long)) {
-               long pstart = start, plength = length;
-
-               if (pstart != start || plength != length || pstart < 0 ||
-                   plength < 0 || p.pno > 65535)
-                       return -EINVAL;
-       }
-
        switch (op) {
        case BLKPG_ADD_PARTITION:
                /* check if partition is aligned to blocksize */
@@ -94,7 +85,7 @@ static int blkdev_reread_part(struct block_device *bdev)
 {
        int ret;
 
-       if (!disk_part_scan_enabled(bdev->bd_disk) || bdev != bdev->bd_contains)
+       if (!disk_part_scan_enabled(bdev->bd_disk) || bdev_is_partition(bdev))
                return -EINVAL;
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
@@ -112,8 +103,7 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
        uint64_t range[2];
        uint64_t start, len;
        struct request_queue *q = bdev_get_queue(bdev);
-       struct address_space *mapping = bdev->bd_inode->i_mapping;
-
+       int err;
 
        if (!(mode & FMODE_WRITE))
                return -EBADF;
@@ -134,7 +124,11 @@ static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
 
        if (start + len > i_size_read(bdev->bd_inode))
                return -EINVAL;
-       truncate_inode_pages_range(mapping, start, start + len - 1);
+
+       err = truncate_bdev_range(bdev, mode, start, start + len - 1);
+       if (err)
+               return err;
+
        return blkdev_issue_discard(bdev, start >> 9, len >> 9,
                                    GFP_KERNEL, flags);
 }
@@ -143,8 +137,8 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
                unsigned long arg)
 {
        uint64_t range[2];
-       struct address_space *mapping;
        uint64_t start, end, len;
+       int err;
 
        if (!(mode & FMODE_WRITE))
                return -EBADF;
@@ -166,8 +160,9 @@ static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
                return -EINVAL;
 
        /* Invalidate the page cache, including dirty pages */
-       mapping = bdev->bd_inode->i_mapping;
-       truncate_inode_pages_range(mapping, start, end);
+       err = truncate_bdev_range(bdev, mode, start, end);
+       if (err)
+               return err;
 
        return blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
                        BLKDEV_ZERO_NOUNMAP);
@@ -215,23 +210,6 @@ static int compat_put_ulong(compat_ulong_t __user *argp, compat_ulong_t val)
 }
 #endif
 
-int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
-                       unsigned cmd, unsigned long arg)
-{
-       struct gendisk *disk = bdev->bd_disk;
-
-       if (disk->fops->ioctl)
-               return disk->fops->ioctl(bdev, mode, cmd, arg);
-
-       return -ENOTTY;
-}
-/*
- * For the record: _GPL here is only because somebody decided to slap it
- * on the previous export.  Sheer idiocy, since it wasn't copyrightable
- * at all and could be open-coded without any exports by anybody who cares.
- */
-EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
-
 #ifdef CONFIG_COMPAT
 /*
  * This is the equivalent of compat_ptr_ioctl(), to be used by block
@@ -342,38 +320,11 @@ static int blkdev_pr_clear(struct block_device *bdev,
        return ops->pr_clear(bdev, c.key);
 }
 
-/*
- * Is it an unrecognized ioctl? The correct returns are either
- * ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a
- * fallback"). ENOIOCTLCMD gets turned into ENOTTY by the ioctl
- * code before returning.
- *
- * Confused drivers sometimes return EINVAL, which is wrong. It
- * means "I understood the ioctl command, but the parameters to
- * it were wrong".
- *
- * We should aim to just fix the broken drivers, the EINVAL case
- * should go away.
- */
-static inline int is_unrecognized_ioctl(int ret)
-{
-       return  ret == -EINVAL ||
-               ret == -ENOTTY ||
-               ret == -ENOIOCTLCMD;
-}
-
 static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
                unsigned cmd, unsigned long arg)
 {
-       int ret;
-
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
-
-       ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-       if (!is_unrecognized_ioctl(ret))
-               return ret;
-
        fsync_bdev(bdev);
        invalidate_bdev(bdev);
        return 0;
@@ -387,12 +338,14 @@ static int blkdev_roset(struct block_device *bdev, fmode_t mode,
        if (!capable(CAP_SYS_ADMIN))
                return -EACCES;
 
-       ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
-       if (!is_unrecognized_ioctl(ret))
-               return ret;
        if (get_user(n, (int __user *)arg))
                return -EFAULT;
-       set_device_ro(bdev, n);
+       if (bdev->bd_disk->fops->set_read_only) {
+               ret = bdev->bd_disk->fops->set_read_only(bdev, n);
+               if (ret)
+                       return ret;
+       }
+       bdev->bd_part->policy = n;
        return 0;
 }
 
@@ -474,15 +427,14 @@ static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
        if (get_user(n, argp))
                return -EFAULT;
 
-       if (!(mode & FMODE_EXCL)) {
-               bdgrab(bdev);
-               if (blkdev_get(bdev, mode | FMODE_EXCL, &bdev) < 0)
-                       return -EBUSY;
-       }
+       if (mode & FMODE_EXCL)
+               return set_blocksize(bdev, n);
 
+       if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode | FMODE_EXCL, &bdev)))
+               return -EBUSY;
        ret = set_blocksize(bdev, n);
-       if (!(mode & FMODE_EXCL))
-               blkdev_put(bdev, mode | FMODE_EXCL);
+       blkdev_put(bdev, mode | FMODE_EXCL);
+
        return ret;
 }
 
@@ -616,10 +568,12 @@ int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
        }
 
        ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
-       if (ret == -ENOIOCTLCMD)
-               return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
+       if (ret != -ENOIOCTLCMD)
+               return ret;
 
-       return ret;
+       if (!bdev->bd_disk->fops->ioctl)
+               return -ENOTTY;
+       return bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg);
 }
 EXPORT_SYMBOL_GPL(blkdev_ioctl); /* for /dev/raw */
 
@@ -636,8 +590,7 @@ long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 {
        int ret;
        void __user *argp = compat_ptr(arg);
-       struct inode *inode = file->f_mapping->host;
-       struct block_device *bdev = inode->i_bdev;
+       struct block_device *bdev = I_BDEV(file->f_mapping->host);
        struct gendisk *disk = bdev->bd_disk;
        fmode_t mode = file->f_mode;
        loff_t size;