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