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