ioctl.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707
  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. static int blkpg_do_ioctl(struct block_device *bdev,
  16. struct blkpg_partition __user *upart, int op)
  17. {
  18. struct blkpg_partition p;
  19. long long start, length;
  20. if (!capable(CAP_SYS_ADMIN))
  21. return -EACCES;
  22. if (copy_from_user(&p, upart, sizeof(struct blkpg_partition)))
  23. return -EFAULT;
  24. if (bdev_is_partition(bdev))
  25. return -EINVAL;
  26. if (p.pno <= 0)
  27. return -EINVAL;
  28. if (op == BLKPG_DEL_PARTITION)
  29. return bdev_del_partition(bdev, p.pno);
  30. start = p.start >> SECTOR_SHIFT;
  31. length = p.length >> SECTOR_SHIFT;
  32. /* check for fit in a hd_struct */
  33. if (sizeof(sector_t) < sizeof(long long)) {
  34. long pstart = start, plength = length;
  35. if (pstart != start || plength != length || pstart < 0 ||
  36. plength < 0 || p.pno > 65535)
  37. return -EINVAL;
  38. }
  39. switch (op) {
  40. case BLKPG_ADD_PARTITION:
  41. /* check if partition is aligned to blocksize */
  42. if (p.start & (bdev_logical_block_size(bdev) - 1))
  43. return -EINVAL;
  44. return bdev_add_partition(bdev, p.pno, start, length);
  45. case BLKPG_RESIZE_PARTITION:
  46. return bdev_resize_partition(bdev, p.pno, start, length);
  47. default:
  48. return -EINVAL;
  49. }
  50. }
  51. static int blkpg_ioctl(struct block_device *bdev,
  52. struct blkpg_ioctl_arg __user *arg)
  53. {
  54. struct blkpg_partition __user *udata;
  55. int op;
  56. if (get_user(op, &arg->op) || get_user(udata, &arg->data))
  57. return -EFAULT;
  58. return blkpg_do_ioctl(bdev, udata, op);
  59. }
  60. #ifdef CONFIG_COMPAT
  61. struct compat_blkpg_ioctl_arg {
  62. compat_int_t op;
  63. compat_int_t flags;
  64. compat_int_t datalen;
  65. compat_caddr_t data;
  66. };
  67. static int compat_blkpg_ioctl(struct block_device *bdev,
  68. struct compat_blkpg_ioctl_arg __user *arg)
  69. {
  70. compat_caddr_t udata;
  71. int op;
  72. if (get_user(op, &arg->op) || get_user(udata, &arg->data))
  73. return -EFAULT;
  74. return blkpg_do_ioctl(bdev, compat_ptr(udata), op);
  75. }
  76. #endif
  77. static int blkdev_reread_part(struct block_device *bdev, fmode_t mode)
  78. {
  79. struct block_device *tmp;
  80. if (!disk_part_scan_enabled(bdev->bd_disk) || bdev_is_partition(bdev))
  81. return -EINVAL;
  82. if (!capable(CAP_SYS_ADMIN))
  83. return -EACCES;
  84. if (bdev->bd_part_count)
  85. return -EBUSY;
  86. /*
  87. * Reopen the device to revalidate the driver state and force a
  88. * partition rescan.
  89. */
  90. mode &= ~FMODE_EXCL;
  91. set_bit(GD_NEED_PART_SCAN, &bdev->bd_disk->state);
  92. tmp = blkdev_get_by_dev(bdev->bd_dev, mode, NULL);
  93. if (IS_ERR(tmp))
  94. return PTR_ERR(tmp);
  95. blkdev_put(tmp, mode);
  96. return 0;
  97. }
  98. static int blk_ioctl_discard(struct block_device *bdev, fmode_t mode,
  99. unsigned long arg, unsigned long flags)
  100. {
  101. uint64_t range[2];
  102. uint64_t start, len;
  103. struct request_queue *q = bdev_get_queue(bdev);
  104. int err;
  105. if (!(mode & FMODE_WRITE))
  106. return -EBADF;
  107. if (!blk_queue_discard(q))
  108. return -EOPNOTSUPP;
  109. if (copy_from_user(range, (void __user *)arg, sizeof(range)))
  110. return -EFAULT;
  111. start = range[0];
  112. len = range[1];
  113. if (start & 511)
  114. return -EINVAL;
  115. if (len & 511)
  116. return -EINVAL;
  117. if (start + len > i_size_read(bdev->bd_inode))
  118. return -EINVAL;
  119. err = truncate_bdev_range(bdev, mode, start, start + len - 1);
  120. if (err)
  121. return err;
  122. return blkdev_issue_discard(bdev, start >> 9, len >> 9,
  123. GFP_KERNEL, flags);
  124. }
  125. static int blk_ioctl_zeroout(struct block_device *bdev, fmode_t mode,
  126. unsigned long arg)
  127. {
  128. uint64_t range[2];
  129. uint64_t start, end, len;
  130. int err;
  131. if (!(mode & FMODE_WRITE))
  132. return -EBADF;
  133. if (copy_from_user(range, (void __user *)arg, sizeof(range)))
  134. return -EFAULT;
  135. start = range[0];
  136. len = range[1];
  137. end = start + len - 1;
  138. if (start & 511)
  139. return -EINVAL;
  140. if (len & 511)
  141. return -EINVAL;
  142. if (end >= (uint64_t)i_size_read(bdev->bd_inode))
  143. return -EINVAL;
  144. if (end < start)
  145. return -EINVAL;
  146. /* Invalidate the page cache, including dirty pages */
  147. err = truncate_bdev_range(bdev, mode, start, end);
  148. if (err)
  149. return err;
  150. return blkdev_issue_zeroout(bdev, start >> 9, len >> 9, GFP_KERNEL,
  151. BLKDEV_ZERO_NOUNMAP);
  152. }
  153. static int put_ushort(unsigned short __user *argp, unsigned short val)
  154. {
  155. return put_user(val, argp);
  156. }
  157. static int put_int(int __user *argp, int val)
  158. {
  159. return put_user(val, argp);
  160. }
  161. static int put_uint(unsigned int __user *argp, unsigned int val)
  162. {
  163. return put_user(val, argp);
  164. }
  165. static int put_long(long __user *argp, long val)
  166. {
  167. return put_user(val, argp);
  168. }
  169. static int put_ulong(unsigned long __user *argp, unsigned long val)
  170. {
  171. return put_user(val, argp);
  172. }
  173. static int put_u64(u64 __user *argp, u64 val)
  174. {
  175. return put_user(val, argp);
  176. }
  177. #ifdef CONFIG_COMPAT
  178. static int compat_put_long(compat_long_t __user *argp, long val)
  179. {
  180. return put_user(val, argp);
  181. }
  182. static int compat_put_ulong(compat_ulong_t __user *argp, compat_ulong_t val)
  183. {
  184. return put_user(val, argp);
  185. }
  186. #endif
  187. int __blkdev_driver_ioctl(struct block_device *bdev, fmode_t mode,
  188. unsigned cmd, unsigned long arg)
  189. {
  190. struct gendisk *disk = bdev->bd_disk;
  191. if (disk->fops->ioctl)
  192. return disk->fops->ioctl(bdev, mode, cmd, arg);
  193. return -ENOTTY;
  194. }
  195. /*
  196. * For the record: _GPL here is only because somebody decided to slap it
  197. * on the previous export. Sheer idiocy, since it wasn't copyrightable
  198. * at all and could be open-coded without any exports by anybody who cares.
  199. */
  200. EXPORT_SYMBOL_GPL(__blkdev_driver_ioctl);
  201. #ifdef CONFIG_COMPAT
  202. /*
  203. * This is the equivalent of compat_ptr_ioctl(), to be used by block
  204. * drivers that implement only commands that are completely compatible
  205. * between 32-bit and 64-bit user space
  206. */
  207. int blkdev_compat_ptr_ioctl(struct block_device *bdev, fmode_t mode,
  208. unsigned cmd, unsigned long arg)
  209. {
  210. struct gendisk *disk = bdev->bd_disk;
  211. if (disk->fops->ioctl)
  212. return disk->fops->ioctl(bdev, mode, cmd,
  213. (unsigned long)compat_ptr(arg));
  214. return -ENOIOCTLCMD;
  215. }
  216. EXPORT_SYMBOL(blkdev_compat_ptr_ioctl);
  217. #endif
  218. static int blkdev_pr_register(struct block_device *bdev,
  219. struct pr_registration __user *arg)
  220. {
  221. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  222. struct pr_registration reg;
  223. if (!capable(CAP_SYS_ADMIN))
  224. return -EPERM;
  225. if (!ops || !ops->pr_register)
  226. return -EOPNOTSUPP;
  227. if (copy_from_user(&reg, arg, sizeof(reg)))
  228. return -EFAULT;
  229. if (reg.flags & ~PR_FL_IGNORE_KEY)
  230. return -EOPNOTSUPP;
  231. return ops->pr_register(bdev, reg.old_key, reg.new_key, reg.flags);
  232. }
  233. static int blkdev_pr_reserve(struct block_device *bdev,
  234. struct pr_reservation __user *arg)
  235. {
  236. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  237. struct pr_reservation rsv;
  238. if (!capable(CAP_SYS_ADMIN))
  239. return -EPERM;
  240. if (!ops || !ops->pr_reserve)
  241. return -EOPNOTSUPP;
  242. if (copy_from_user(&rsv, arg, sizeof(rsv)))
  243. return -EFAULT;
  244. if (rsv.flags & ~PR_FL_IGNORE_KEY)
  245. return -EOPNOTSUPP;
  246. return ops->pr_reserve(bdev, rsv.key, rsv.type, rsv.flags);
  247. }
  248. static int blkdev_pr_release(struct block_device *bdev,
  249. struct pr_reservation __user *arg)
  250. {
  251. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  252. struct pr_reservation rsv;
  253. if (!capable(CAP_SYS_ADMIN))
  254. return -EPERM;
  255. if (!ops || !ops->pr_release)
  256. return -EOPNOTSUPP;
  257. if (copy_from_user(&rsv, arg, sizeof(rsv)))
  258. return -EFAULT;
  259. if (rsv.flags)
  260. return -EOPNOTSUPP;
  261. return ops->pr_release(bdev, rsv.key, rsv.type);
  262. }
  263. static int blkdev_pr_preempt(struct block_device *bdev,
  264. struct pr_preempt __user *arg, bool abort)
  265. {
  266. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  267. struct pr_preempt p;
  268. if (!capable(CAP_SYS_ADMIN))
  269. return -EPERM;
  270. if (!ops || !ops->pr_preempt)
  271. return -EOPNOTSUPP;
  272. if (copy_from_user(&p, arg, sizeof(p)))
  273. return -EFAULT;
  274. if (p.flags)
  275. return -EOPNOTSUPP;
  276. return ops->pr_preempt(bdev, p.old_key, p.new_key, p.type, abort);
  277. }
  278. static int blkdev_pr_clear(struct block_device *bdev,
  279. struct pr_clear __user *arg)
  280. {
  281. const struct pr_ops *ops = bdev->bd_disk->fops->pr_ops;
  282. struct pr_clear c;
  283. if (!capable(CAP_SYS_ADMIN))
  284. return -EPERM;
  285. if (!ops || !ops->pr_clear)
  286. return -EOPNOTSUPP;
  287. if (copy_from_user(&c, arg, sizeof(c)))
  288. return -EFAULT;
  289. if (c.flags)
  290. return -EOPNOTSUPP;
  291. return ops->pr_clear(bdev, c.key);
  292. }
  293. /*
  294. * Is it an unrecognized ioctl? The correct returns are either
  295. * ENOTTY (final) or ENOIOCTLCMD ("I don't know this one, try a
  296. * fallback"). ENOIOCTLCMD gets turned into ENOTTY by the ioctl
  297. * code before returning.
  298. *
  299. * Confused drivers sometimes return EINVAL, which is wrong. It
  300. * means "I understood the ioctl command, but the parameters to
  301. * it were wrong".
  302. *
  303. * We should aim to just fix the broken drivers, the EINVAL case
  304. * should go away.
  305. */
  306. static inline int is_unrecognized_ioctl(int ret)
  307. {
  308. return ret == -EINVAL ||
  309. ret == -ENOTTY ||
  310. ret == -ENOIOCTLCMD;
  311. }
  312. static int blkdev_flushbuf(struct block_device *bdev, fmode_t mode,
  313. unsigned cmd, unsigned long arg)
  314. {
  315. int ret;
  316. if (!capable(CAP_SYS_ADMIN))
  317. return -EACCES;
  318. ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
  319. if (!is_unrecognized_ioctl(ret))
  320. return ret;
  321. fsync_bdev(bdev);
  322. invalidate_bdev(bdev);
  323. return 0;
  324. }
  325. static int blkdev_roset(struct block_device *bdev, fmode_t mode,
  326. unsigned cmd, unsigned long arg)
  327. {
  328. int ret, n;
  329. if (!capable(CAP_SYS_ADMIN))
  330. return -EACCES;
  331. ret = __blkdev_driver_ioctl(bdev, mode, cmd, arg);
  332. if (!is_unrecognized_ioctl(ret))
  333. return ret;
  334. if (get_user(n, (int __user *)arg))
  335. return -EFAULT;
  336. set_device_ro(bdev, n);
  337. return 0;
  338. }
  339. static int blkdev_getgeo(struct block_device *bdev,
  340. struct hd_geometry __user *argp)
  341. {
  342. struct gendisk *disk = bdev->bd_disk;
  343. struct hd_geometry geo;
  344. int ret;
  345. if (!argp)
  346. return -EINVAL;
  347. if (!disk->fops->getgeo)
  348. return -ENOTTY;
  349. /*
  350. * We need to set the startsect first, the driver may
  351. * want to override it.
  352. */
  353. memset(&geo, 0, sizeof(geo));
  354. geo.start = get_start_sect(bdev);
  355. ret = disk->fops->getgeo(bdev, &geo);
  356. if (ret)
  357. return ret;
  358. if (copy_to_user(argp, &geo, sizeof(geo)))
  359. return -EFAULT;
  360. return 0;
  361. }
  362. #ifdef CONFIG_COMPAT
  363. struct compat_hd_geometry {
  364. unsigned char heads;
  365. unsigned char sectors;
  366. unsigned short cylinders;
  367. u32 start;
  368. };
  369. static int compat_hdio_getgeo(struct block_device *bdev,
  370. struct compat_hd_geometry __user *ugeo)
  371. {
  372. struct gendisk *disk = bdev->bd_disk;
  373. struct hd_geometry geo;
  374. int ret;
  375. if (!ugeo)
  376. return -EINVAL;
  377. if (!disk->fops->getgeo)
  378. return -ENOTTY;
  379. memset(&geo, 0, sizeof(geo));
  380. /*
  381. * We need to set the startsect first, the driver may
  382. * want to override it.
  383. */
  384. geo.start = get_start_sect(bdev);
  385. ret = disk->fops->getgeo(bdev, &geo);
  386. if (ret)
  387. return ret;
  388. ret = copy_to_user(ugeo, &geo, 4);
  389. ret |= put_user(geo.start, &ugeo->start);
  390. if (ret)
  391. ret = -EFAULT;
  392. return ret;
  393. }
  394. #endif
  395. /* set the logical block size */
  396. static int blkdev_bszset(struct block_device *bdev, fmode_t mode,
  397. int __user *argp)
  398. {
  399. int ret, n;
  400. if (!capable(CAP_SYS_ADMIN))
  401. return -EACCES;
  402. if (!argp)
  403. return -EINVAL;
  404. if (get_user(n, argp))
  405. return -EFAULT;
  406. if (mode & FMODE_EXCL)
  407. return set_blocksize(bdev, n);
  408. if (IS_ERR(blkdev_get_by_dev(bdev->bd_dev, mode | FMODE_EXCL, &bdev)))
  409. return -EBUSY;
  410. ret = set_blocksize(bdev, n);
  411. blkdev_put(bdev, mode | FMODE_EXCL);
  412. return ret;
  413. }
  414. /*
  415. * Common commands that are handled the same way on native and compat
  416. * user space. Note the separate arg/argp parameters that are needed
  417. * to deal with the compat_ptr() conversion.
  418. */
  419. static int blkdev_common_ioctl(struct block_device *bdev, fmode_t mode,
  420. unsigned cmd, unsigned long arg, void __user *argp)
  421. {
  422. unsigned int max_sectors;
  423. switch (cmd) {
  424. case BLKFLSBUF:
  425. return blkdev_flushbuf(bdev, mode, cmd, arg);
  426. case BLKROSET:
  427. return blkdev_roset(bdev, mode, cmd, arg);
  428. case BLKDISCARD:
  429. return blk_ioctl_discard(bdev, mode, arg, 0);
  430. case BLKSECDISCARD:
  431. return blk_ioctl_discard(bdev, mode, arg,
  432. BLKDEV_DISCARD_SECURE);
  433. case BLKZEROOUT:
  434. return blk_ioctl_zeroout(bdev, mode, arg);
  435. case BLKREPORTZONE:
  436. return blkdev_report_zones_ioctl(bdev, mode, cmd, arg);
  437. case BLKRESETZONE:
  438. case BLKOPENZONE:
  439. case BLKCLOSEZONE:
  440. case BLKFINISHZONE:
  441. return blkdev_zone_mgmt_ioctl(bdev, mode, cmd, arg);
  442. case BLKGETZONESZ:
  443. return put_uint(argp, bdev_zone_sectors(bdev));
  444. case BLKGETNRZONES:
  445. return put_uint(argp, blkdev_nr_zones(bdev->bd_disk));
  446. case BLKROGET:
  447. return put_int(argp, bdev_read_only(bdev) != 0);
  448. case BLKSSZGET: /* get block device logical block size */
  449. return put_int(argp, bdev_logical_block_size(bdev));
  450. case BLKPBSZGET: /* get block device physical block size */
  451. return put_uint(argp, bdev_physical_block_size(bdev));
  452. case BLKIOMIN:
  453. return put_uint(argp, bdev_io_min(bdev));
  454. case BLKIOOPT:
  455. return put_uint(argp, bdev_io_opt(bdev));
  456. case BLKALIGNOFF:
  457. return put_int(argp, bdev_alignment_offset(bdev));
  458. case BLKDISCARDZEROES:
  459. return put_uint(argp, 0);
  460. case BLKSECTGET:
  461. max_sectors = min_t(unsigned int, USHRT_MAX,
  462. queue_max_sectors(bdev_get_queue(bdev)));
  463. return put_ushort(argp, max_sectors);
  464. case BLKROTATIONAL:
  465. return put_ushort(argp, !blk_queue_nonrot(bdev_get_queue(bdev)));
  466. case BLKRASET:
  467. case BLKFRASET:
  468. if(!capable(CAP_SYS_ADMIN))
  469. return -EACCES;
  470. bdev->bd_bdi->ra_pages = (arg * 512) / PAGE_SIZE;
  471. return 0;
  472. case BLKRRPART:
  473. return blkdev_reread_part(bdev, mode);
  474. case BLKTRACESTART:
  475. case BLKTRACESTOP:
  476. case BLKTRACETEARDOWN:
  477. return blk_trace_ioctl(bdev, cmd, argp);
  478. case IOC_PR_REGISTER:
  479. return blkdev_pr_register(bdev, argp);
  480. case IOC_PR_RESERVE:
  481. return blkdev_pr_reserve(bdev, argp);
  482. case IOC_PR_RELEASE:
  483. return blkdev_pr_release(bdev, argp);
  484. case IOC_PR_PREEMPT:
  485. return blkdev_pr_preempt(bdev, argp, false);
  486. case IOC_PR_PREEMPT_ABORT:
  487. return blkdev_pr_preempt(bdev, argp, true);
  488. case IOC_PR_CLEAR:
  489. return blkdev_pr_clear(bdev, argp);
  490. default:
  491. return -ENOIOCTLCMD;
  492. }
  493. }
  494. /*
  495. * Always keep this in sync with compat_blkdev_ioctl()
  496. * to handle all incompatible commands in both functions.
  497. *
  498. * New commands must be compatible and go into blkdev_common_ioctl
  499. */
  500. int blkdev_ioctl(struct block_device *bdev, fmode_t mode, unsigned cmd,
  501. unsigned long arg)
  502. {
  503. int ret;
  504. loff_t size;
  505. void __user *argp = (void __user *)arg;
  506. switch (cmd) {
  507. /* These need separate implementations for the data structure */
  508. case HDIO_GETGEO:
  509. return blkdev_getgeo(bdev, argp);
  510. case BLKPG:
  511. return blkpg_ioctl(bdev, argp);
  512. /* Compat mode returns 32-bit data instead of 'long' */
  513. case BLKRAGET:
  514. case BLKFRAGET:
  515. if (!argp)
  516. return -EINVAL;
  517. return put_long(argp, (bdev->bd_bdi->ra_pages*PAGE_SIZE) / 512);
  518. case BLKGETSIZE:
  519. size = i_size_read(bdev->bd_inode);
  520. if ((size >> 9) > ~0UL)
  521. return -EFBIG;
  522. return put_ulong(argp, size >> 9);
  523. /* The data is compatible, but the command number is different */
  524. case BLKBSZGET: /* get block device soft block size (cf. BLKSSZGET) */
  525. return put_int(argp, block_size(bdev));
  526. case BLKBSZSET:
  527. return blkdev_bszset(bdev, mode, argp);
  528. case BLKGETSIZE64:
  529. return put_u64(argp, i_size_read(bdev->bd_inode));
  530. /* Incompatible alignment on i386 */
  531. case BLKTRACESETUP:
  532. return blk_trace_ioctl(bdev, cmd, argp);
  533. default:
  534. break;
  535. }
  536. ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
  537. if (ret == -ENOIOCTLCMD)
  538. return __blkdev_driver_ioctl(bdev, mode, cmd, arg);
  539. return ret;
  540. }
  541. EXPORT_SYMBOL_GPL(blkdev_ioctl); /* for /dev/raw */
  542. #ifdef CONFIG_COMPAT
  543. #define BLKBSZGET_32 _IOR(0x12, 112, int)
  544. #define BLKBSZSET_32 _IOW(0x12, 113, int)
  545. #define BLKGETSIZE64_32 _IOR(0x12, 114, int)
  546. /* Most of the generic ioctls are handled in the normal fallback path.
  547. This assumes the blkdev's low level compat_ioctl always returns
  548. ENOIOCTLCMD for unknown ioctls. */
  549. long compat_blkdev_ioctl(struct file *file, unsigned cmd, unsigned long arg)
  550. {
  551. int ret;
  552. void __user *argp = compat_ptr(arg);
  553. struct inode *inode = file->f_mapping->host;
  554. struct block_device *bdev = inode->i_bdev;
  555. struct gendisk *disk = bdev->bd_disk;
  556. fmode_t mode = file->f_mode;
  557. loff_t size;
  558. /*
  559. * O_NDELAY can be altered using fcntl(.., F_SETFL, ..), so we have
  560. * to updated it before every ioctl.
  561. */
  562. if (file->f_flags & O_NDELAY)
  563. mode |= FMODE_NDELAY;
  564. else
  565. mode &= ~FMODE_NDELAY;
  566. switch (cmd) {
  567. /* These need separate implementations for the data structure */
  568. case HDIO_GETGEO:
  569. return compat_hdio_getgeo(bdev, argp);
  570. case BLKPG:
  571. return compat_blkpg_ioctl(bdev, argp);
  572. /* Compat mode returns 32-bit data instead of 'long' */
  573. case BLKRAGET:
  574. case BLKFRAGET:
  575. if (!argp)
  576. return -EINVAL;
  577. return compat_put_long(argp,
  578. (bdev->bd_bdi->ra_pages * PAGE_SIZE) / 512);
  579. case BLKGETSIZE:
  580. size = i_size_read(bdev->bd_inode);
  581. if ((size >> 9) > ~(compat_ulong_t)0)
  582. return -EFBIG;
  583. return compat_put_ulong(argp, size >> 9);
  584. /* The data is compatible, but the command number is different */
  585. case BLKBSZGET_32: /* get the logical block size (cf. BLKSSZGET) */
  586. return put_int(argp, bdev_logical_block_size(bdev));
  587. case BLKBSZSET_32:
  588. return blkdev_bszset(bdev, mode, argp);
  589. case BLKGETSIZE64_32:
  590. return put_u64(argp, i_size_read(bdev->bd_inode));
  591. /* Incompatible alignment on i386 */
  592. case BLKTRACESETUP32:
  593. return blk_trace_ioctl(bdev, cmd, argp);
  594. default:
  595. break;
  596. }
  597. ret = blkdev_common_ioctl(bdev, mode, cmd, arg, argp);
  598. if (ret == -ENOIOCTLCMD && disk->fops->compat_ioctl)
  599. ret = disk->fops->compat_ioctl(bdev, mode, cmd, arg);
  600. return ret;
  601. }
  602. #endif