linux/block/ioctl.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/capability.h>
   3#include <linux/compat.h>
   4#include <linux/blkdev.h>
   5#include <linux/export.h>
   6#include <linux/gfp.h>
   7#include <linux/blkpg.h>
   8#include <linux/hdreg.h>
   9#include <linux/backing-dev.h>
  10#include <linux/fs.h>
  11#include <linux/blktrace_api.h>
  12#include <linux/pr.h>
  13#include <linux/uaccess.h>
  14#include "blk.h"
  15
  16static int blkpg_do_ioctl(struct block_device *bdev,
  17                          struct blkpg_partition __user *upart, int op)
  18{
  19        struct gendisk *disk = bdev->bd_disk;
  20        struct blkpg_partition p;
  21        long long start, length;
  22
  23        if (disk->flags & GENHD_FL_NO_PART)
  24                return -EINVAL;
  25        if (!capable(CAP_SYS_ADMIN))
  26                return -EACCES;
  27        if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
  28                return -EFAULT;
  29        if (bdev_is_partition(bdev))
  30                return -EINVAL;
  31
  32        if (p.pno <= 0)
  33                return -EINVAL;
  34
  35        if (op == BLKPG_DEL_PARTITION)
  36                return bdev_del_partition(disk, p.pno);
  37
  38        start = p.start >> SECTOR_SHIFT;
  39        length = p.length >> SECTOR_SHIFT;
  40
  41        switch (op) {
  42        case BLKPG_ADD_PARTITION:
  43                /* check if partition is aligned to blocksize */
  44                if (p.start & (bdev_logical_block_size(bdev) - 1))
  45                        return -EINVAL;
  46                return bdev_add_partition(disk, p.pno, start, length);
  47        case BLKPG_RESIZE_PARTITION:
  48                return bdev_resize_partition(disk, p.pno, start, length);
  49        default:
  50                return -EINVAL;
  51        }
  52}
  53
  54static int blkpg_ioctl(struct block_device *bdev,
  55                       struct blkpg_ioctl_arg __user *arg)
  56{
  57        struct blkpg_partition __user *udata;
  58        int op;
  59
  60        if (get_user(op, &arg->op) || get_user(udata, &arg->data))
  61                return -EFAULT;
  62
  63        return blkpg_do_ioctl(bdev, udata, op);
  64}
  65
  66#ifdef CONFIG_COMPAT
  67struct compat_blkpg_ioctl_arg {
  68        compat_int_t op;
  69        compat_int_t flags;
  70        compat_int_t datalen;
  71        compat_caddr_t data;
  72};
  73
  74static int compat_blkpg_ioctl(struct block_device *bdev,
  75                              struct compat_blkpg_ioctl_arg __user *arg)
  76{
  77        compat_caddr_t udata;
  78        int op;
  79
  80        if (get_user(op, &arg->op) || get_user(udata, &arg->data))
  81                return -EFAULT;
  82
  83        return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
  84}
  85#endif
  86
  87static int blk_ioctl_discard(struct block_device *bdev, blk_mode_t mode,
  88                unsigned long arg)
  89{
  90        uint64_t range[2];
  91        uint64_t start, len;
  92        struct inode *inode = bdev->bd_inode;
  93        int err;
  94
  95        if (!(mode & BLK_OPEN_WRITE))
  96                return -EBADF;
  97
  98        if (!bdev_max_discard_sectors(bdev))
  99                return -EOPNOTSUPP;
 100
 101        if (copy_from_user(range, (void __user *)arg, sizeof(range)))
 102                return -EFAULT;
 103
 104        start = range[0];
 105        len = range[1];
 106
 107        if (start & 511)
 108                return -EINVAL;
 109        if (len & 511)
 110                return -EINVAL;
 111
 112        if (start + len > bdev_nr_bytes(bdev))
 113                return -EINVAL;
 114
 115        filemap_invalidate_lock(inode->i_mapping);
 116        err = truncate_bdev_range(bdev, mode, start, start + len - 1);
 117        if (err)
 118                goto fail;
 119        err = blkdev_issue_discard(bdev, start >> 9, len >> 9, GFP_KERNEL);
 120fail:
 121        filemap_invalidate_unlock(inode->i_mapping);
 122        return err;
 123}
 124
 125static int blk_ioctl_secure_erase(struct block_device *bdev, blk_mode_t mode,
 126                void __user *argp)
 127{
 128        uint64_t start, len;
 129        uint64_t range[2];
 130        int err;
 131
 132        if (!(mode & BLK_OPEN_WRITE))
 133                return -EBADF;
 134        if (!bdev_max_secure_erase_sectors(bdev))
 135                return -EOPNOTSUPP;
 136        if (copy_from_user(range, argp, sizeof(range)))
 137                return -EFAULT;
 138
 139        start = range[0];
 140        len = range[1];
 141        if ((start & 511) || (len & 511))
 142                return -EINVAL;
 143        if (start + len > bdev_nr_bytes(bdev))
 144                return -EINVAL;
 145
 146        filemap_invalidate_lock(bdev->bd_inode->i_mapping);
 147        err = truncate_bdev_range(bdev, mode, start, start + len - 1);
 148        if (!err)
 149                err = blkdev_issue_secure_erase(bdev, start >> 9, len >> 9,
 150                                                GFP_KERNEL);
 151        filemap_invalidate_unlock(bdev->bd_inode->i_mapping);
 152        return err;
 153}
 154
 155
 156static int blk_ioctl_zeroout(struct block_device *bdev, blk_mode_t mode,
 157                unsigned long arg)
 158{
 159        uint64_t range[2];
 160        uint64_t start, end, len;
 161        struct inode *inode = bdev->bd_inode;
 162        int err;
 163
 164        if (!(mode & BLK_OPEN_WRITE))
 165                return -EBADF;
 166
 167        if (copy_from_user(range, (void __user *)arg, sizeof(range)))
 168                return -EFAULT;
 169
 170        start = range[0];
 171        len = range[1];
 172        end = start + len - 1;
 173
 174        if (start & 511)
 175                return -EINVAL;
 176        if (len & 511)
 177                return -EINVAL;
 178        if (end >= (uint64_t)bdev_nr_bytes(bdev))
 179                return -EINVAL;
 180        if (end < start)
 181                return -EINVAL;
 182
 183        /* Invalidate the page cache, including dirty pages */
 184        filemap_invalidate_lock(inode->i_mapping);
 185        err = truncate_bdev_range(bdev, mode, start, end);
 186        if (err)
 187                goto fail;
 188
 189        err = blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
 190                                   BLKDEV_ZERO_NOUNMAP);
 191
 192fail:
 193        filemap_invalidate_unlock(inode->i_mapping);
 194        return err;
 195}
 196
 197static int put_ushort(unsigned short __user *argp, unsigned short val)
 198{
 199        return put_user(val, argp);
 200}
 201
 202static int put_int(int __user *argp, int val)
 203{
 204        return put_user(val, argp);
 205}
 206
 207static int put_uint(unsigned int __user *argp, unsigned int val)
 208{
 209        return put_user(val, argp);
 210}
 211
 212static int put_long(long __user *argp, long val)
 213{
 214        return put_user(val, argp);
 215}
 216
 217static int put_ulong(unsigned long __user *argp, unsigned long val)
 218{
 219        return put_user(val, argp);
 220}
 221
 222static int put_u64(u64 __user *argp, u64 val)
 223{
 224        return put_user(val, argp);
 225}
 226
 227#ifdef CONFIG_COMPAT
 228static int compat_put_long(compat_long_t __user *argp, long val)
 229{
 230        return put_user(val, argp);
 231}
 232
 233static int compat_put_ulong(compat_ulong_t __user *argp, compat_ulong_t val)
 234{
 235        return put_user(val, argp);
 236}
 237#endif
 238
 239#ifdef CONFIG_COMPAT
 240/*
 241 * This is the equivalent of compat_ptr_ioctl(), to be used by block
 242 * drivers that implement only commands that are completely compatible
 243 * between 32-bit and 64-bit user space
 244 */
 245int blkdev_compat_ptr_ioctl(struct block_device *bdev, blk_mode_t mode,
 246                        unsigned cmd, unsigned long arg)
 247{
 248        struct gendisk *disk = bdev->bd_disk;
 249
 250        if (disk->fops->ioctl)
 251                return disk->fops->ioctl(bdev, mode, cmd,
 252                                         (unsigned long)compat_ptr(arg));
 253
 254        return -ENOIOCTLCMD;
 255}
 256EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
 257#endif
 258
 259static bool blkdev_pr_allowed(struct block_device *bdev, blk_mode_t mode)
 260{
 261        /* no sense to make reservations for partitions */
 262        if (bdev_is_partition(bdev))
 263                return false;
 264
 265        if (capable(CAP_SYS_ADMIN))
 266                return true;
 267        /*
 268         * Only allow unprivileged reservations if the file descriptor is open
 269         * for writing.
 270         */
 271        return mode & BLK_OPEN_WRITE;
 272}
 273
 274static int blkdev_pr_register(struct block_device *bdev, blk_mode_t mode,
 275                struct pr_registration __user *arg)
 276{
 277        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
 278        struct pr_registration reg;
 279
 280        if (!blkdev_pr_allowed(bdev, mode))
 281                return -EPERM;
 282        if (!ops || !ops->pr_register)
 283                return -EOPNOTSUPP;
 284        if (copy_from_user(&reg, arg, sizeof(reg)))
 285                return -EFAULT;
 286
 287        if (reg.flags & ~PR_FL_IGNORE_KEY)
 288                return -EOPNOTSUPP;
 289        return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags);
 290}
 291
 292static int blkdev_pr_reserve(struct block_device *bdev, blk_mode_t mode,
 293                struct pr_reservation __user *arg)
 294{
 295        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
 296        struct pr_reservation rsv;
 297
 298        if (!blkdev_pr_allowed(bdev, mode))
 299                return -EPERM;
 300        if (!ops || !ops->pr_reserve)
 301                return -EOPNOTSUPP;
 302        if (copy_from_user(&rsv, arg, sizeof(rsv)))
 303                return -EFAULT;
 304
 305        if (rsv.flags & ~PR_FL_IGNORE_KEY)
 306                return -EOPNOTSUPP;
 307        return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags);
 308}
 309
 310static int blkdev_pr_release(struct block_device *bdev, blk_mode_t mode,
 311                struct pr_reservation __user *arg)
 312{
 313        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
 314        struct pr_reservation rsv;
 315
 316        if (!blkdev_pr_allowed(bdev, mode))
 317                return -EPERM;
 318        if (!ops || !ops->pr_release)
 319                return -EOPNOTSUPP;
 320        if (copy_from_user(&rsv, arg, sizeof(rsv)))
 321                return -EFAULT;
 322
 323        if (rsv.flags)
 324                return -EOPNOTSUPP;
 325        return ops->pr_release(bdev, rsv.key, rsv.type);
 326}
 327
 328static int blkdev_pr_preempt(struct block_device *bdev, blk_mode_t mode,
 329                struct pr_preempt __user *arg, bool abort)
 330{
 331        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
 332        struct pr_preempt p;
 333
 334        if (!blkdev_pr_allowed(bdev, mode))
 335                return -EPERM;
 336        if (!ops || !ops->pr_preempt)
 337                return -EOPNOTSUPP;
 338        if (copy_from_user(&p, arg, sizeof(p)))
 339                return -EFAULT;
 340
 341        if (p.flags)
 342                return -EOPNOTSUPP;
 343        return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort);
 344}
 345
 346static int blkdev_pr_clear(struct block_device *bdev, blk_mode_t mode,
 347                struct pr_clear __user *arg)
 348{
 349        const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
 350        struct pr_clear c;
 351
 352        if (!blkdev_pr_allowed(bdev, mode))
 353                return -EPERM;
 354        if (!ops || !ops->pr_clear)
 355                return -EOPNOTSUPP;
 356        if (copy_from_user(&c, arg, sizeof(c)))
 357                return -EFAULT;
 358
 359        if (c.flags)
 360                return -EOPNOTSUPP;
 361        return ops->pr_clear(bdev, c.key);
 362}
 363
 364static int blkdev_flushbuf(struct block_device *bdev, unsigned cmd,
 365                unsigned long arg)
 366{
 367        if (!capable(CAP_SYS_ADMIN))
 368                return -EACCES;
 369
 370        mutex_lock(&bdev->bd_holder_lock);
 371        if (bdev->bd_holder_ops && bdev->bd_holder_ops->sync)
 372                bdev->bd_holder_ops->sync(bdev);
 373        else {
 374                mutex_unlock(&bdev->bd_holder_lock);
 375                sync_blockdev(bdev);
 376        }
 377
 378        invalidate_bdev(bdev);
 379        return 0;
 380}
 381
 382static int blkdev_roset(struct block_device *bdev, unsigned cmd,
 383                unsigned long arg)
 384{
 385        int ret, n;
 386
 387        if (!capable(CAP_SYS_ADMIN))
 388                return -EACCES;
 389
 390        if (get_user(n, (int __user *)arg))
 391                return -EFAULT;
 392        if (bdev->bd_disk->fops->set_read_only) {
 393                ret = bdev->bd_disk->fops->set_read_only(bdev, n);
 394                if (ret)
 395                        return ret;
 396        }
 397        bdev->bd_read_only = n;
 398        return 0;
 399}
 400
 401static int blkdev_getgeo(struct block_device *bdev,
 402                struct hd_geometry __user *argp)
 403{
 404        struct gendisk *disk = bdev->bd_disk;
 405        struct hd_geometry geo;
 406        int ret;
 407
 408        if (!argp)
 409                return -EINVAL;
 410        if (!disk->fops->getgeo)
 411                return -ENOTTY;
 412
 413        /*
 414         * We need to set the startsect first, the driver may
 415         * want to override it.
 416         */
 417        memset(&geo, 0, sizeof(geo));
 418        geo.start = get_start_sect(bdev);
 419        ret = disk->fops->getgeo(bdev, &geo);
 420        if (ret)
 421                return ret;
 422        if (copy_to_user(argp, &geo, sizeof(geo)))
 423                return -EFAULT;
 424        return 0;
 425}
 426
 427#ifdef CONFIG_COMPAT
 428struct compat_hd_geometry {
 429        unsigned char heads;
 430        unsigned char sectors;
 431        unsigned short cylinders;
 432        u32 start;
 433};
 434
 435static int compat_hdio_getgeo(struct block_device *bdev,
 436                              struct compat_hd_geometry __user *ugeo)
 437{
 438        struct gendisk *disk = bdev->bd_disk;
 439        struct hd_geometry geo;
 440        int ret;
 441
 442        if (!ugeo)
 443                return -EINVAL;
 444        if (!disk->fops->getgeo)
 445                return -ENOTTY;
 446
 447        memset(&geo, 0, sizeof(geo));
 448        /*
 449         * We need to set the startsect first, the driver may
 450         * want to override it.
 451         */
 452        geo.start = get_start_sect(bdev);
 453        ret = disk->fops->getgeo(bdev, &geo);
 454        if (ret)
 455                return ret;
 456
 457        ret = copy_to_user(ugeo, &geo, 4);
 458        ret |= put_user(geo.start, &ugeo->start);
 459        if (ret)
 460                ret = -EFAULT;
 461
 462        return ret;
 463}
 464#endif
 465
 466/* set the logical block size */
 467static int blkdev_bszset(struct block_device *bdev, blk_mode_t mode,
 468                int __user *argp)
 469{
 470        int ret, n;
 471        struct bdev_handle *handle;
 472
 473        if (!capable(CAP_SYS_ADMIN))
 474                return -EACCES;
 475        if (!argp)
 476                return -EINVAL;
 477        if (get_user(n, argp))
 478                return -EFAULT;
 479
 480        if (mode & BLK_OPEN_EXCL)
 481                return set_blocksize(bdev, n);
 482
 483        handle = bdev_open_by_dev(bdev->bd_dev, mode, &bdev, NULL);
 484        if (IS_ERR(handle))
 485                return -EBUSY;
 486        ret = set_blocksize(bdev, n);
 487        bdev_release(handle);
 488
 489        return ret;
 490}
 491
 492/*
 493 * Common commands that are handled the same way on native and compat
 494 * user space. Note the separate arg/argp parameters that are needed
 495 * to deal with the compat_ptr() conversion.
 496 */
 497static int blkdev_common_ioctl(struct block_device *bdev, blk_mode_t mode,
 498                               unsigned int cmd, unsigned long arg,
 499                               void __user *argp)
 500{
 501        unsigned int max_sectors;
 502
 503        switch (cmd) {
 504        case BLKFLSBUF:
 505                return blkdev_flushbuf(bdev, cmd, arg);
 506        case BLKROSET:
 507                return blkdev_roset(bdev, cmd, arg);
 508        case BLKDISCARD:
 509                return blk_ioctl_discard(bdev, mode, arg);
 510        case BLKSECDISCARD:
 511                return blk_ioctl_secure_erase(bdev, mode, argp);
 512        case BLKZEROOUT:
 513                return blk_ioctl_zeroout(bdev, mode, arg);
 514        case BLKGETDISKSEQ:
 515                return put_u64(argp, bdev->bd_disk->diskseq);
 516        case BLKREPORTZONE:
 517                return blkdev_report_zones_ioctl(bdev, cmd, arg);
 518        case BLKRESETZONE:
 519        case BLKOPENZONE:
 520        case BLKCLOSEZONE:
 521        case BLKFINISHZONE:
 522                return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg);
 523        case BLKGETZONESZ:
 524                return put_uint(argp, bdev_zone_sectors(bdev));
 525        case BLKGETNRZONES:
 526                return put_uint(argp, bdev_nr_zones(bdev));
 527        case BLKROGET:
 528                return put_int(argp, bdev_read_only(bdev) != 0);
 529        case BLKSSZGET: /* get block device logical block size */
 530                return put_int(argp, bdev_logical_block_size(bdev));
 531        case BLKPBSZGET: /* get block device physical block size */
 532                return put_uint(argp, bdev_physical_block_size(bdev));
 533        case BLKIOMIN:
 534                return put_uint(argp, bdev_io_min(bdev));
 535        case BLKIOOPT:
 536                return put_uint(argp, bdev_io_opt(bdev));
 537        case BLKALIGNOFF:
 538                return put_int(argp, bdev_alignment_offset(bdev));
 539        case BLKDISCARDZEROES:
 540                return put_uint(argp, 0);
 541        case BLKSECTGET:
 542                max_sectors = min_t(unsigned int, USHRT_MAX,
 543                                    queue_max_sectors(bdev_get_queue(bdev)));
 544                return put_ushort(argp, max_sectors);
 545        case BLKROTATIONAL:
 546                return put_ushort(argp, !bdev_nonrot(bdev));
 547        case BLKRASET:
 548        case BLKFRASET:
 549                if(!capable(CAP_SYS_ADMIN))
 550                        return -EACCES;
 551                bdev->bd_disk->bdi->ra_pages = (arg * 512) / PAGE_SIZE;
 552                return 0;
 553        case BLKRRPART:
 554                if (!capable(CAP_SYS_ADMIN))
 555                        return -EACCES;
 556                if (bdev_is_partition(bdev))
 557                        return -EINVAL;
 558                return disk_scan_partitions(bdev->bd_disk, mode);
 559        case BLKTRACESTART:
 560        case BLKTRACESTOP:
 561        case BLKTRACETEARDOWN:
 562                return blk_trace_ioctl(bdev, cmd, argp);
 563        case IOC_PR_REGISTER:
 564                return blkdev_pr_register(bdev, mode, argp);
 565        case IOC_PR_RESERVE:
 566                return blkdev_pr_reserve(bdev, mode, argp);
 567        case IOC_PR_RELEASE:
 568                return blkdev_pr_release(bdev, mode, argp);
 569        case IOC_PR_PREEMPT:
 570                return blkdev_pr_preempt(bdev, mode, argp, false);
 571        case IOC_PR_PREEMPT_ABORT:
 572                return blkdev_pr_preempt(bdev, mode, argp, true);
 573        case IOC_PR_CLEAR:
 574                return blkdev_pr_clear(bdev, mode, argp);
 575        default:
 576                return -ENOIOCTLCMD;
 577        }
 578}
 579
 580/*
 581 * Always keep this in sync with compat_blkdev_ioctl()
 582 * to handle all incompatible commands in both functions.
 583 *
 584 * New commands must be compatible and go into blkdev_common_ioctl
 585 */
 586long blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 587{
 588        struct block_device *bdev = I_BDEV(file->f_mapping->host);
 589        void __user *argp = (void __user *)arg;
 590        blk_mode_t mode = file_to_blk_mode(file);
 591        int ret;
 592
 593        switch (cmd) {
 594        /* These need separate implementations for the data structure */
 595        case HDIO_GETGEO:
 596                return blkdev_getgeo(bdev, argp);
 597        case BLKPG:
 598                return blkpg_ioctl(bdev, argp);
 599
 600        /* Compat mode returns 32-bit data instead of 'long' */
 601        case BLKRAGET:
 602        case BLKFRAGET:
 603                if (!argp)
 604                        return -EINVAL;
 605                return put_long(argp,
 606                        (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512);
 607        case BLKGETSIZE:
 608                if (bdev_nr_sectors(bdev) > ~0UL)
 609                        return -EFBIG;
 610                return put_ulong(argp, bdev_nr_sectors(bdev));
 611
 612        /* The data is compatible, but the command number is different */
 613        case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
 614                return put_int(argp, block_size(bdev));
 615        case BLKBSZSET:
 616                return blkdev_bszset(bdev, mode, argp);
 617        case BLKGETSIZE64:
 618                return put_u64(argp, bdev_nr_bytes(bdev));
 619
 620        /* Incompatible alignment on i386 */
 621        case BLKTRACESETUP:
 622                return blk_trace_ioctl(bdev, cmd, argp);
 623        default:
 624                break;
 625        }
 626
 627        ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
 628        if (ret != -ENOIOCTLCMD)
 629                return ret;
 630
 631        if (!bdev->bd_disk->fops->ioctl)
 632                return -ENOTTY;
 633        return bdev->bd_disk->fops->ioctl(bdev, mode, cmd, arg);
 634}
 635
 636#ifdef CONFIG_COMPAT
 637
 638#define BLKBSZGET_32            _IOR(0x12, 112, int)
 639#define BLKBSZSET_32            _IOW(0x12, 113, int)
 640#define BLKGETSIZE64_32         _IOR(0x12, 114, int)
 641
 642/* Most of the generic ioctls are handled in the normal fallback path.
 643   This assumes the blkdev's low level compat_ioctl always returns
 644   ENOIOCTLCMD for unknown ioctls. */
 645long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
 646{
 647        int ret;
 648        void __user *argp = compat_ptr(arg);
 649        struct block_device *bdev = I_BDEV(file->f_mapping->host);
 650        struct gendisk *disk = bdev->bd_disk;
 651        blk_mode_t mode = file_to_blk_mode(file);
 652
 653        switch (cmd) {
 654        /* These need separate implementations for the data structure */
 655        case HDIO_GETGEO:
 656                return compat_hdio_getgeo(bdev, argp);
 657        case BLKPG:
 658                return compat_blkpg_ioctl(bdev, argp);
 659
 660        /* Compat mode returns 32-bit data instead of 'long' */
 661        case BLKRAGET:
 662        case BLKFRAGET:
 663                if (!argp)
 664                        return -EINVAL;
 665                return compat_put_long(argp,
 666                        (bdev->bd_disk->bdi->ra_pages * PAGE_SIZE) / 512);
 667        case BLKGETSIZE:
 668                if (bdev_nr_sectors(bdev) > ~(compat_ulong_t)0)
 669                        return -EFBIG;
 670                return compat_put_ulong(argp, bdev_nr_sectors(bdev));
 671
 672        /* The data is compatible, but the command number is different */
 673        case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
 674                return put_int(argp, bdev_logical_block_size(bdev));
 675        case BLKBSZSET_32:
 676                return blkdev_bszset(bdev, mode, argp);
 677        case BLKGETSIZE64_32:
 678                return put_u64(argp, bdev_nr_bytes(bdev));
 679
 680        /* Incompatible alignment on i386 */
 681        case BLKTRACESETUP32:
 682                return blk_trace_ioctl(bdev, cmd, argp);
 683        default:
 684                break;
 685        }
 686
 687        ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
 688        if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
 689                ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
 690
 691        return ret;
 692}
 693#endif
 694