Blame view

block/compat_ioctl.c 11.2 KB
b24413180   Greg Kroah-Hartman   License cleanup: ...
1
  // SPDX-License-Identifier: GPL-2.0
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
2
3
4
5
6
7
  #include <linux/blkdev.h>
  #include <linux/blkpg.h>
  #include <linux/blktrace_api.h>
  #include <linux/cdrom.h>
  #include <linux/compat.h>
  #include <linux/elevator.h>
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
8
  #include <linux/hdreg.h>
755d02fcf   Arnd Bergmann   compat_ioctl: blo...
9
  #include <linux/pr.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
10
  #include <linux/slab.h>
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
11
  #include <linux/syscalls.h>
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
12
13
14
15
16
17
18
19
20
21
22
23
  #include <linux/types.h>
  #include <linux/uaccess.h>
  
  static int compat_put_ushort(unsigned long arg, unsigned short val)
  {
  	return put_user(val, (unsigned short __user *)compat_ptr(arg));
  }
  
  static int compat_put_int(unsigned long arg, int val)
  {
  	return put_user(val, (compat_int_t __user *)compat_ptr(arg));
  }
ac481c20e   Martin K. Petersen   block: Topology i...
24
25
26
27
  static int compat_put_uint(unsigned long arg, unsigned int val)
  {
  	return put_user(val, (compat_uint_t __user *)compat_ptr(arg));
  }
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
28
29
30
31
32
33
34
35
36
37
38
39
40
41
  static int compat_put_long(unsigned long arg, long val)
  {
  	return put_user(val, (compat_long_t __user *)compat_ptr(arg));
  }
  
  static int compat_put_ulong(unsigned long arg, compat_ulong_t val)
  {
  	return put_user(val, (compat_ulong_t __user *)compat_ptr(arg));
  }
  
  static int compat_put_u64(unsigned long arg, u64 val)
  {
  	return put_user(val, (compat_u64 __user *)compat_ptr(arg));
  }
9617db085   Arnd Bergmann   compat_ioctl: mov...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
  struct compat_hd_geometry {
  	unsigned char heads;
  	unsigned char sectors;
  	unsigned short cylinders;
  	u32 start;
  };
  
  static int compat_hdio_getgeo(struct gendisk *disk, struct block_device *bdev,
  			struct compat_hd_geometry __user *ugeo)
  {
  	struct hd_geometry geo;
  	int ret;
  
  	if (!ugeo)
  		return -EINVAL;
  	if (!disk->fops->getgeo)
  		return -ENOTTY;
8b0d77f13   Cong Wang   block/compat_ioct...
59
  	memset(&geo, 0, sizeof(geo));
9617db085   Arnd Bergmann   compat_ioctl: mov...
60
61
62
63
64
65
66
67
68
69
  	/*
  	 * We need to set the startsect first, the driver may
  	 * want to override it.
  	 */
  	geo.start = get_start_sect(bdev);
  	ret = disk->fops->getgeo(bdev, &geo);
  	if (ret)
  		return ret;
  
  	ret = copy_to_user(ugeo, &geo, 4);
3ddc5b46a   Mathieu Desnoyers   kernel-wide: fix ...
70
  	ret |= put_user(geo.start, &ugeo->start);
9617db085   Arnd Bergmann   compat_ioctl: mov...
71
72
73
74
75
  	if (ret)
  		ret = -EFAULT;
  
  	return ret;
  }
33c2dca49   Al Viro   [PATCH] trim file...
76
77
  static int compat_hdio_ioctl(struct block_device *bdev, fmode_t mode,
  		unsigned int cmd, unsigned long arg)
9617db085   Arnd Bergmann   compat_ioctl: mov...
78
  {
8363dae23   Bart Van Assche   compat_hdio_ioctl...
79
  	unsigned long __user *p;
9617db085   Arnd Bergmann   compat_ioctl: mov...
80
  	int error;
30138384d   Al Viro   compat_hdio_ioctl...
81
  	p = compat_alloc_user_space(sizeof(unsigned long));
33c2dca49   Al Viro   [PATCH] trim file...
82
  	error = __blkdev_driver_ioctl(bdev, mode,
30138384d   Al Viro   compat_hdio_ioctl...
83
  				cmd, (unsigned long)p);
9617db085   Arnd Bergmann   compat_ioctl: mov...
84
  	if (error == 0) {
30138384d   Al Viro   compat_hdio_ioctl...
85
86
87
  		unsigned int __user *uvp = compat_ptr(arg);
  		unsigned long v;
  		if (get_user(v, p) || put_user(v, uvp))
9617db085   Arnd Bergmann   compat_ioctl: mov...
88
89
90
91
  			error = -EFAULT;
  	}
  	return error;
  }
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
  struct compat_cdrom_read_audio {
  	union cdrom_addr	addr;
  	u8			addr_format;
  	compat_int_t		nframes;
  	compat_caddr_t		buf;
  };
  
  struct compat_cdrom_generic_command {
  	unsigned char	cmd[CDROM_PACKET_SIZE];
  	compat_caddr_t	buffer;
  	compat_uint_t	buflen;
  	compat_int_t	stat;
  	compat_caddr_t	sense;
  	unsigned char	data_direction;
  	compat_int_t	quiet;
  	compat_int_t	timeout;
  	compat_caddr_t	reserved[1];
  };
33c2dca49   Al Viro   [PATCH] trim file...
110
111
  static int compat_cdrom_read_audio(struct block_device *bdev, fmode_t mode,
  		unsigned int cmd, unsigned long arg)
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
  {
  	struct cdrom_read_audio __user *cdread_audio;
  	struct compat_cdrom_read_audio __user *cdread_audio32;
  	__u32 data;
  	void __user *datap;
  
  	cdread_audio = compat_alloc_user_space(sizeof(*cdread_audio));
  	cdread_audio32 = compat_ptr(arg);
  
  	if (copy_in_user(&cdread_audio->addr,
  			 &cdread_audio32->addr,
  			 (sizeof(*cdread_audio32) -
  			  sizeof(compat_caddr_t))))
  		return -EFAULT;
  
  	if (get_user(data, &cdread_audio32->buf))
  		return -EFAULT;
  	datap = compat_ptr(data);
  	if (put_user(datap, &cdread_audio->buf))
  		return -EFAULT;
33c2dca49   Al Viro   [PATCH] trim file...
132
  	return __blkdev_driver_ioctl(bdev, mode, cmd,
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
133
134
  			(unsigned long)cdread_audio);
  }
33c2dca49   Al Viro   [PATCH] trim file...
135
136
  static int compat_cdrom_generic_command(struct block_device *bdev, fmode_t mode,
  		unsigned int cmd, unsigned long arg)
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
  {
  	struct cdrom_generic_command __user *cgc;
  	struct compat_cdrom_generic_command __user *cgc32;
  	u32 data;
  	unsigned char dir;
  	int itmp;
  
  	cgc = compat_alloc_user_space(sizeof(*cgc));
  	cgc32 = compat_ptr(arg);
  
  	if (copy_in_user(&cgc->cmd, &cgc32->cmd, sizeof(cgc->cmd)) ||
  	    get_user(data, &cgc32->buffer) ||
  	    put_user(compat_ptr(data), &cgc->buffer) ||
  	    copy_in_user(&cgc->buflen, &cgc32->buflen,
  			 (sizeof(unsigned int) + sizeof(int))) ||
  	    get_user(data, &cgc32->sense) ||
  	    put_user(compat_ptr(data), &cgc->sense) ||
  	    get_user(dir, &cgc32->data_direction) ||
  	    put_user(dir, &cgc->data_direction) ||
  	    get_user(itmp, &cgc32->quiet) ||
  	    put_user(itmp, &cgc->quiet) ||
  	    get_user(itmp, &cgc32->timeout) ||
  	    put_user(itmp, &cgc->timeout) ||
  	    get_user(data, &cgc32->reserved[0]) ||
  	    put_user(compat_ptr(data), &cgc->reserved[0]))
  		return -EFAULT;
33c2dca49   Al Viro   [PATCH] trim file...
163
  	return __blkdev_driver_ioctl(bdev, mode, cmd, (unsigned long)cgc);
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
164
  }
18cf7f872   Arnd Bergmann   compat_ioctl: mov...
165
166
167
168
169
170
  struct compat_blkpg_ioctl_arg {
  	compat_int_t op;
  	compat_int_t flags;
  	compat_int_t datalen;
  	compat_caddr_t data;
  };
56b26add0   Al Viro   [PATCH] kill the ...
171
  static int compat_blkpg_ioctl(struct block_device *bdev, fmode_t mode,
18cf7f872   Arnd Bergmann   compat_ioctl: mov...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
  		unsigned int cmd, struct compat_blkpg_ioctl_arg __user *ua32)
  {
  	struct blkpg_ioctl_arg __user *a = compat_alloc_user_space(sizeof(*a));
  	compat_caddr_t udata;
  	compat_int_t n;
  	int err;
  
  	err = get_user(n, &ua32->op);
  	err |= put_user(n, &a->op);
  	err |= get_user(n, &ua32->flags);
  	err |= put_user(n, &a->flags);
  	err |= get_user(n, &ua32->datalen);
  	err |= put_user(n, &a->datalen);
  	err |= get_user(udata, &ua32->data);
  	err |= put_user(compat_ptr(udata), &a->data);
  	if (err)
  		return err;
56b26add0   Al Viro   [PATCH] kill the ...
189
  	return blkdev_ioctl(bdev, mode, cmd, (unsigned long)a);
18cf7f872   Arnd Bergmann   compat_ioctl: mov...
190
  }
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
191
192
193
  #define BLKBSZGET_32		_IOR(0x12, 112, int)
  #define BLKBSZSET_32		_IOW(0x12, 113, int)
  #define BLKGETSIZE64_32		_IOR(0x12, 114, int)
33c2dca49   Al Viro   [PATCH] trim file...
194
195
  static int compat_blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
  			unsigned cmd, unsigned long arg)
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
196
  {
33013a881   Philip Langdale   compat_ioctl: fix...
197
  	switch (cmd) {
9617db085   Arnd Bergmann   compat_ioctl: mov...
198
199
200
201
202
203
204
205
206
207
208
  	case HDIO_GET_UNMASKINTR:
  	case HDIO_GET_MULTCOUNT:
  	case HDIO_GET_KEEPSETTINGS:
  	case HDIO_GET_32BIT:
  	case HDIO_GET_NOWERR:
  	case HDIO_GET_DMA:
  	case HDIO_GET_NICE:
  	case HDIO_GET_WCACHE:
  	case HDIO_GET_ACOUSTIC:
  	case HDIO_GET_ADDRESS:
  	case HDIO_GET_BUSSTATE:
33c2dca49   Al Viro   [PATCH] trim file...
209
  		return compat_hdio_ioctl(bdev, mode, cmd, arg);
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
210
  	case CDROMREADAUDIO:
33c2dca49   Al Viro   [PATCH] trim file...
211
  		return compat_cdrom_read_audio(bdev, mode, cmd, arg);
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
212
  	case CDROM_SEND_PACKET:
33c2dca49   Al Viro   [PATCH] trim file...
213
  		return compat_cdrom_generic_command(bdev, mode, cmd, arg);
b3087cc4f   Arnd Bergmann   compat_ioctl: mov...
214

7199d4cdd   Arnd Bergmann   compat_ioctl: add...
215
216
217
218
219
220
221
222
223
224
225
226
  	/*
  	 * No handler required for the ones below, we just need to
  	 * convert arg to a 64 bit pointer.
  	 */
  	case BLKSECTSET:
  	/*
  	 * 0x03 -- HD/IDE ioctl's used by hdparm and friends.
  	 *         Some need translations, these do not.
  	 */
  	case HDIO_GET_IDENTITY:
  	case HDIO_DRIVE_TASK:
  	case HDIO_DRIVE_CMD:
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
227
228
  	/* 0x330 is reserved -- it used to be HDIO_GETGEO_BIG */
  	case 0x330:
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
  	/* CDROM stuff */
  	case CDROMPAUSE:
  	case CDROMRESUME:
  	case CDROMPLAYMSF:
  	case CDROMPLAYTRKIND:
  	case CDROMREADTOCHDR:
  	case CDROMREADTOCENTRY:
  	case CDROMSTOP:
  	case CDROMSTART:
  	case CDROMEJECT:
  	case CDROMVOLCTRL:
  	case CDROMSUBCHNL:
  	case CDROMMULTISESSION:
  	case CDROM_GET_MCN:
  	case CDROMRESET:
  	case CDROMVOLREAD:
  	case CDROMSEEK:
  	case CDROMPLAYBLK:
  	case CDROMCLOSETRAY:
  	case CDROM_DISC_STATUS:
  	case CDROM_CHANGER_NSLOTS:
  	case CDROM_GET_CAPABILITY:
  	/* Ignore cdrom.h about these next 5 ioctls, they absolutely do
  	 * not take a struct cdrom_read, instead they take a struct cdrom_msf
  	 * which is compatible.
  	 */
  	case CDROMREADMODE2:
  	case CDROMREADMODE1:
  	case CDROMREADRAW:
  	case CDROMREADCOOKED:
  	case CDROMREADALL:
  	/* DVD ioctls */
  	case DVD_READ_STRUCT:
  	case DVD_WRITE_STRUCT:
  	case DVD_AUTH:
  		arg = (unsigned long)compat_ptr(arg);
1c925604e   Andreas Schwab   [PATCH] Fix block...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
  	/* These intepret arg as an unsigned long, not as a pointer,
  	 * so we must not do compat_ptr() conversion. */
  	case HDIO_SET_MULTCOUNT:
  	case HDIO_SET_UNMASKINTR:
  	case HDIO_SET_KEEPSETTINGS:
  	case HDIO_SET_32BIT:
  	case HDIO_SET_NOWERR:
  	case HDIO_SET_DMA:
  	case HDIO_SET_PIO_MODE:
  	case HDIO_SET_NICE:
  	case HDIO_SET_WCACHE:
  	case HDIO_SET_ACOUSTIC:
  	case HDIO_SET_BUSSTATE:
  	case HDIO_SET_ADDRESS:
  	case CDROMEJECT_SW:
  	case CDROM_SET_OPTIONS:
  	case CDROM_CLEAR_OPTIONS:
  	case CDROM_SELECT_SPEED:
  	case CDROM_SELECT_DISC:
  	case CDROM_MEDIA_CHANGED:
  	case CDROM_DRIVE_STATUS:
  	case CDROM_LOCKDOOR:
  	case CDROM_DEBUG:
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
288
289
290
291
292
  		break;
  	default:
  		/* unknown ioctl number */
  		return -ENOIOCTLCMD;
  	}
33c2dca49   Al Viro   [PATCH] trim file...
293
  	return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
294
  }
45048d096   Al Viro   [PATCH] get rid o...
295
296
297
298
  /* Most of the generic ioctls are handled in the normal fallback path.
     This assumes the blkdev's low level compat_ioctl always returns
     ENOIOCTLCMD for unknown ioctls. */
  long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
299
  {
45048d096   Al Viro   [PATCH] get rid o...
300
301
302
303
304
  	int ret = -ENOIOCTLCMD;
  	struct inode *inode = file->f_mapping->host;
  	struct block_device *bdev = inode->i_bdev;
  	struct gendisk *disk = bdev->bd_disk;
  	fmode_t mode = file->f_mode;
45048d096   Al Viro   [PATCH] get rid o...
305
  	loff_t size;
63f264965   Akinobu Mita   block: fix BLKSEC...
306
  	unsigned int max_sectors;
45048d096   Al Viro   [PATCH] get rid o...
307

fd4ce1acd   Christoph Hellwig   [PATCH 1/2] kill ...
308
309
310
311
  	/*
  	 * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
  	 * to updated it before every ioctl.
  	 */
45048d096   Al Viro   [PATCH] get rid o...
312
  	if (file->f_flags & O_NDELAY)
fd4ce1acd   Christoph Hellwig   [PATCH 1/2] kill ...
313
314
315
  		mode |= FMODE_NDELAY;
  	else
  		mode &= ~FMODE_NDELAY;
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
316
317
  
  	switch (cmd) {
45048d096   Al Viro   [PATCH] get rid o...
318
319
  	case HDIO_GETGEO:
  		return compat_hdio_getgeo(disk, bdev, compat_ptr(arg));
ac481c20e   Martin K. Petersen   block: Topology i...
320
321
322
323
324
325
326
327
  	case BLKPBSZGET:
  		return compat_put_uint(arg, bdev_physical_block_size(bdev));
  	case BLKIOMIN:
  		return compat_put_uint(arg, bdev_io_min(bdev));
  	case BLKIOOPT:
  		return compat_put_uint(arg, bdev_io_opt(bdev));
  	case BLKALIGNOFF:
  		return compat_put_int(arg, bdev_alignment_offset(bdev));
98262f276   Martin K. Petersen   block: Allow devi...
328
  	case BLKDISCARDZEROES:
48920ff2a   Christoph Hellwig   block: remove the...
329
  		return compat_put_uint(arg, 0);
45048d096   Al Viro   [PATCH] get rid o...
330
331
332
  	case BLKFLSBUF:
  	case BLKROSET:
  	case BLKDISCARD:
8d57a98cc   Adrian Hunter   block: add secure...
333
  	case BLKSECDISCARD:
3b3a1814d   Mikulas Patocka   block: provide co...
334
  	case BLKZEROOUT:
45048d096   Al Viro   [PATCH] get rid o...
335
336
337
338
339
  	/*
  	 * the ones below are implemented in blkdev_locked_ioctl,
  	 * but we call blkdev_ioctl, which gets the lock for us
  	 */
  	case BLKRRPART:
17d3c07aa   Arnd Bergmann   compat_ioctl: blo...
340
341
  	case BLKREPORTZONE:
  	case BLKRESETZONE:
247aca0b6   Arnd Bergmann   compat_ioctl: blo...
342
343
  	case BLKGETZONESZ:
  	case BLKGETNRZONES:
56b26add0   Al Viro   [PATCH] kill the ...
344
  		return blkdev_ioctl(bdev, mode, cmd,
45048d096   Al Viro   [PATCH] get rid o...
345
346
  				(unsigned long)compat_ptr(arg));
  	case BLKBSZSET_32:
56b26add0   Al Viro   [PATCH] kill the ...
347
  		return blkdev_ioctl(bdev, mode, BLKBSZSET,
45048d096   Al Viro   [PATCH] get rid o...
348
349
  				(unsigned long)compat_ptr(arg));
  	case BLKPG:
56b26add0   Al Viro   [PATCH] kill the ...
350
  		return compat_blkpg_ioctl(bdev, mode, cmd, compat_ptr(arg));
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
351
352
353
354
  	case BLKRAGET:
  	case BLKFRAGET:
  		if (!arg)
  			return -EINVAL;
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
355
  		return compat_put_long(arg,
efa7c9f97   Jan Kara   block: Get rid of...
356
  			       (bdev->bd_bdi->ra_pages * PAGE_SIZE) / 512);
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
357
358
359
360
361
  	case BLKROGET: /* compatible */
  		return compat_put_int(arg, bdev_read_only(bdev) != 0);
  	case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
  		return compat_put_int(arg, block_size(bdev));
  	case BLKSSZGET: /* get block device hardware sector size */
e1defc4ff   Martin K. Petersen   block: Do away wi...
362
  		return compat_put_int(arg, bdev_logical_block_size(bdev));
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
363
  	case BLKSECTGET:
63f264965   Akinobu Mita   block: fix BLKSEC...
364
365
366
  		max_sectors = min_t(unsigned int, USHRT_MAX,
  				    queue_max_sectors(bdev_get_queue(bdev)));
  		return compat_put_ushort(arg, max_sectors);
ef00f59c9   Martin K. Petersen   block: Add BLKROT...
367
368
369
  	case BLKROTATIONAL:
  		return compat_put_ushort(arg,
  					 !blk_queue_nonrot(bdev_get_queue(bdev)));
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
370
371
372
373
  	case BLKRASET: /* compatible, but no compat_ptr (!) */
  	case BLKFRASET:
  		if (!capable(CAP_SYS_ADMIN))
  			return -EACCES;
efa7c9f97   Jan Kara   block: Get rid of...
374
  		bdev->bd_bdi->ra_pages = (arg * 512) / PAGE_SIZE;
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
375
376
  		return 0;
  	case BLKGETSIZE:
77304d2ab   Mike Snitzer   block: read i_siz...
377
  		size = i_size_read(bdev->bd_inode);
45048d096   Al Viro   [PATCH] get rid o...
378
  		if ((size >> 9) > ~0UL)
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
379
  			return -EFBIG;
45048d096   Al Viro   [PATCH] get rid o...
380
  		return compat_put_ulong(arg, size >> 9);
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
381
382
  
  	case BLKGETSIZE64_32:
77304d2ab   Mike Snitzer   block: read i_siz...
383
  		return compat_put_u64(arg, i_size_read(bdev->bd_inode));
171044d44   Arnd Bergmann   compat_ioctl: han...
384
385
  
  	case BLKTRACESETUP32:
171044d44   Arnd Bergmann   compat_ioctl: han...
386
387
388
  	case BLKTRACESTART: /* compatible */
  	case BLKTRACESTOP:  /* compatible */
  	case BLKTRACETEARDOWN: /* compatible */
45048d096   Al Viro   [PATCH] get rid o...
389
  		ret = blk_trace_ioctl(bdev, cmd, compat_ptr(arg));
7199d4cdd   Arnd Bergmann   compat_ioctl: add...
390
  		return ret;
755d02fcf   Arnd Bergmann   compat_ioctl: blo...
391
392
393
394
395
396
397
398
  	case IOC_PR_REGISTER:
  	case IOC_PR_RESERVE:
  	case IOC_PR_RELEASE:
  	case IOC_PR_PREEMPT:
  	case IOC_PR_PREEMPT_ABORT:
  	case IOC_PR_CLEAR:
  		return blkdev_ioctl(bdev, mode, cmd,
  				(unsigned long)compat_ptr(arg));
45048d096   Al Viro   [PATCH] get rid o...
399
400
401
402
403
404
405
  	default:
  		if (disk->fops->compat_ioctl)
  			ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
  		if (ret == -ENOIOCTLCMD)
  			ret = compat_blkdev_driver_ioctl(bdev, mode, cmd, arg);
  		return ret;
  	}
f58c4c0a1   Arnd Bergmann   compat_ioctl: mov...
406
  }