ioctl.c 36 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378
  1. /*
  2. * ioctl.c - NILFS ioctl operations.
  3. *
  4. * Copyright (C) 2007, 2008 Nippon Telegraph and Telephone Corporation.
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * Written by Koji Sato.
  17. */
  18. #include <linux/fs.h>
  19. #include <linux/wait.h>
  20. #include <linux/slab.h>
  21. #include <linux/capability.h> /* capable() */
  22. #include <linux/uaccess.h> /* copy_from_user(), copy_to_user() */
  23. #include <linux/vmalloc.h>
  24. #include <linux/compat.h> /* compat_ptr() */
  25. #include <linux/mount.h> /* mnt_want_write_file(), mnt_drop_write_file() */
  26. #include <linux/buffer_head.h>
  27. #include "nilfs.h"
  28. #include "segment.h"
  29. #include "bmap.h"
  30. #include "cpfile.h"
  31. #include "sufile.h"
  32. #include "dat.h"
  33. /**
  34. * nilfs_ioctl_wrap_copy - wrapping function of get/set metadata info
  35. * @nilfs: nilfs object
  36. * @argv: vector of arguments from userspace
  37. * @dir: set of direction flags
  38. * @dofunc: concrete function of get/set metadata info
  39. *
  40. * Description: nilfs_ioctl_wrap_copy() gets/sets metadata info by means of
  41. * calling dofunc() function on the basis of @argv argument.
  42. *
  43. * Return Value: On success, 0 is returned and requested metadata info
  44. * is copied into userspace. On error, one of the following
  45. * negative error codes is returned.
  46. *
  47. * %-EINVAL - Invalid arguments from userspace.
  48. *
  49. * %-ENOMEM - Insufficient amount of memory available.
  50. *
  51. * %-EFAULT - Failure during execution of requested operation.
  52. */
  53. static int nilfs_ioctl_wrap_copy(struct the_nilfs *nilfs,
  54. struct nilfs_argv *argv, int dir,
  55. ssize_t (*dofunc)(struct the_nilfs *,
  56. __u64 *, int,
  57. void *, size_t, size_t))
  58. {
  59. void *buf;
  60. void __user *base = (void __user *)(unsigned long)argv->v_base;
  61. size_t maxmembs, total, n;
  62. ssize_t nr;
  63. int ret, i;
  64. __u64 pos, ppos;
  65. if (argv->v_nmembs == 0)
  66. return 0;
  67. if (argv->v_size > PAGE_SIZE)
  68. return -EINVAL;
  69. /*
  70. * Reject pairs of a start item position (argv->v_index) and a
  71. * total count (argv->v_nmembs) which leads position 'pos' to
  72. * overflow by the increment at the end of the loop.
  73. */
  74. if (argv->v_index > ~(__u64)0 - argv->v_nmembs)
  75. return -EINVAL;
  76. buf = (void *)__get_free_pages(GFP_NOFS, 0);
  77. if (unlikely(!buf))
  78. return -ENOMEM;
  79. maxmembs = PAGE_SIZE / argv->v_size;
  80. ret = 0;
  81. total = 0;
  82. pos = argv->v_index;
  83. for (i = 0; i < argv->v_nmembs; i += n) {
  84. n = (argv->v_nmembs - i < maxmembs) ?
  85. argv->v_nmembs - i : maxmembs;
  86. if ((dir & _IOC_WRITE) &&
  87. copy_from_user(buf, base + argv->v_size * i,
  88. argv->v_size * n)) {
  89. ret = -EFAULT;
  90. break;
  91. }
  92. ppos = pos;
  93. nr = dofunc(nilfs, &pos, argv->v_flags, buf, argv->v_size,
  94. n);
  95. if (nr < 0) {
  96. ret = nr;
  97. break;
  98. }
  99. if ((dir & _IOC_READ) &&
  100. copy_to_user(base + argv->v_size * i, buf,
  101. argv->v_size * nr)) {
  102. ret = -EFAULT;
  103. break;
  104. }
  105. total += nr;
  106. if ((size_t)nr < n)
  107. break;
  108. if (pos == ppos)
  109. pos += n;
  110. }
  111. argv->v_nmembs = total;
  112. free_pages((unsigned long)buf, 0);
  113. return ret;
  114. }
  115. /**
  116. * nilfs_ioctl_getflags - ioctl to support lsattr
  117. */
  118. static int nilfs_ioctl_getflags(struct inode *inode, void __user *argp)
  119. {
  120. unsigned int flags = NILFS_I(inode)->i_flags & FS_FL_USER_VISIBLE;
  121. return put_user(flags, (int __user *)argp);
  122. }
  123. /**
  124. * nilfs_ioctl_setflags - ioctl to support chattr
  125. */
  126. static int nilfs_ioctl_setflags(struct inode *inode, struct file *filp,
  127. void __user *argp)
  128. {
  129. struct nilfs_transaction_info ti;
  130. unsigned int flags, oldflags;
  131. int ret;
  132. if (!inode_owner_or_capable(inode))
  133. return -EACCES;
  134. if (get_user(flags, (int __user *)argp))
  135. return -EFAULT;
  136. ret = mnt_want_write_file(filp);
  137. if (ret)
  138. return ret;
  139. flags = nilfs_mask_flags(inode->i_mode, flags);
  140. inode_lock(inode);
  141. oldflags = NILFS_I(inode)->i_flags;
  142. /*
  143. * The IMMUTABLE and APPEND_ONLY flags can only be changed by the
  144. * relevant capability.
  145. */
  146. ret = -EPERM;
  147. if (((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) &&
  148. !capable(CAP_LINUX_IMMUTABLE))
  149. goto out;
  150. ret = nilfs_transaction_begin(inode->i_sb, &ti, 0);
  151. if (ret)
  152. goto out;
  153. NILFS_I(inode)->i_flags = (oldflags & ~FS_FL_USER_MODIFIABLE) |
  154. (flags & FS_FL_USER_MODIFIABLE);
  155. nilfs_set_inode_flags(inode);
  156. inode->i_ctime = current_time(inode);
  157. if (IS_SYNC(inode))
  158. nilfs_set_transaction_flag(NILFS_TI_SYNC);
  159. nilfs_mark_inode_dirty(inode);
  160. ret = nilfs_transaction_commit(inode->i_sb);
  161. out:
  162. inode_unlock(inode);
  163. mnt_drop_write_file(filp);
  164. return ret;
  165. }
  166. /**
  167. * nilfs_ioctl_getversion - get info about a file's version (generation number)
  168. */
  169. static int nilfs_ioctl_getversion(struct inode *inode, void __user *argp)
  170. {
  171. return put_user(inode->i_generation, (int __user *)argp);
  172. }
  173. /**
  174. * nilfs_ioctl_change_cpmode - change checkpoint mode (checkpoint/snapshot)
  175. * @inode: inode object
  176. * @filp: file object
  177. * @cmd: ioctl's request code
  178. * @argp: pointer on argument from userspace
  179. *
  180. * Description: nilfs_ioctl_change_cpmode() function changes mode of
  181. * given checkpoint between checkpoint and snapshot state. This ioctl
  182. * is used in chcp and mkcp utilities.
  183. *
  184. * Return Value: On success, 0 is returned and mode of a checkpoint is
  185. * changed. On error, one of the following negative error codes
  186. * is returned.
  187. *
  188. * %-EPERM - Operation not permitted.
  189. *
  190. * %-EFAULT - Failure during checkpoint mode changing.
  191. */
  192. static int nilfs_ioctl_change_cpmode(struct inode *inode, struct file *filp,
  193. unsigned int cmd, void __user *argp)
  194. {
  195. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  196. struct nilfs_transaction_info ti;
  197. struct nilfs_cpmode cpmode;
  198. int ret;
  199. if (!capable(CAP_SYS_ADMIN))
  200. return -EPERM;
  201. ret = mnt_want_write_file(filp);
  202. if (ret)
  203. return ret;
  204. ret = -EFAULT;
  205. if (copy_from_user(&cpmode, argp, sizeof(cpmode)))
  206. goto out;
  207. mutex_lock(&nilfs->ns_snapshot_mount_mutex);
  208. nilfs_transaction_begin(inode->i_sb, &ti, 0);
  209. ret = nilfs_cpfile_change_cpmode(
  210. nilfs->ns_cpfile, cpmode.cm_cno, cpmode.cm_mode);
  211. if (unlikely(ret < 0))
  212. nilfs_transaction_abort(inode->i_sb);
  213. else
  214. nilfs_transaction_commit(inode->i_sb); /* never fails */
  215. mutex_unlock(&nilfs->ns_snapshot_mount_mutex);
  216. out:
  217. mnt_drop_write_file(filp);
  218. return ret;
  219. }
  220. /**
  221. * nilfs_ioctl_delete_checkpoint - remove checkpoint
  222. * @inode: inode object
  223. * @filp: file object
  224. * @cmd: ioctl's request code
  225. * @argp: pointer on argument from userspace
  226. *
  227. * Description: nilfs_ioctl_delete_checkpoint() function removes
  228. * checkpoint from NILFS2 file system. This ioctl is used in rmcp
  229. * utility.
  230. *
  231. * Return Value: On success, 0 is returned and a checkpoint is
  232. * removed. On error, one of the following negative error codes
  233. * is returned.
  234. *
  235. * %-EPERM - Operation not permitted.
  236. *
  237. * %-EFAULT - Failure during checkpoint removing.
  238. */
  239. static int
  240. nilfs_ioctl_delete_checkpoint(struct inode *inode, struct file *filp,
  241. unsigned int cmd, void __user *argp)
  242. {
  243. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  244. struct nilfs_transaction_info ti;
  245. __u64 cno;
  246. int ret;
  247. if (!capable(CAP_SYS_ADMIN))
  248. return -EPERM;
  249. ret = mnt_want_write_file(filp);
  250. if (ret)
  251. return ret;
  252. ret = -EFAULT;
  253. if (copy_from_user(&cno, argp, sizeof(cno)))
  254. goto out;
  255. nilfs_transaction_begin(inode->i_sb, &ti, 0);
  256. ret = nilfs_cpfile_delete_checkpoint(nilfs->ns_cpfile, cno);
  257. if (unlikely(ret < 0))
  258. nilfs_transaction_abort(inode->i_sb);
  259. else
  260. nilfs_transaction_commit(inode->i_sb); /* never fails */
  261. out:
  262. mnt_drop_write_file(filp);
  263. return ret;
  264. }
  265. /**
  266. * nilfs_ioctl_do_get_cpinfo - callback method getting info about checkpoints
  267. * @nilfs: nilfs object
  268. * @posp: pointer on array of checkpoint's numbers
  269. * @flags: checkpoint mode (checkpoint or snapshot)
  270. * @buf: buffer for storing checkponts' info
  271. * @size: size in bytes of one checkpoint info item in array
  272. * @nmembs: number of checkpoints in array (numbers and infos)
  273. *
  274. * Description: nilfs_ioctl_do_get_cpinfo() function returns info about
  275. * requested checkpoints. The NILFS_IOCTL_GET_CPINFO ioctl is used in
  276. * lscp utility and by nilfs_cleanerd daemon.
  277. *
  278. * Return value: count of nilfs_cpinfo structures in output buffer.
  279. */
  280. static ssize_t
  281. nilfs_ioctl_do_get_cpinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
  282. void *buf, size_t size, size_t nmembs)
  283. {
  284. int ret;
  285. down_read(&nilfs->ns_segctor_sem);
  286. ret = nilfs_cpfile_get_cpinfo(nilfs->ns_cpfile, posp, flags, buf,
  287. size, nmembs);
  288. up_read(&nilfs->ns_segctor_sem);
  289. return ret;
  290. }
  291. /**
  292. * nilfs_ioctl_get_cpstat - get checkpoints statistics
  293. * @inode: inode object
  294. * @filp: file object
  295. * @cmd: ioctl's request code
  296. * @argp: pointer on argument from userspace
  297. *
  298. * Description: nilfs_ioctl_get_cpstat() returns information about checkpoints.
  299. * The NILFS_IOCTL_GET_CPSTAT ioctl is used by lscp, rmcp utilities
  300. * and by nilfs_cleanerd daemon.
  301. *
  302. * Return Value: On success, 0 is returned, and checkpoints information is
  303. * copied into userspace pointer @argp. On error, one of the following
  304. * negative error codes is returned.
  305. *
  306. * %-EIO - I/O error.
  307. *
  308. * %-ENOMEM - Insufficient amount of memory available.
  309. *
  310. * %-EFAULT - Failure during getting checkpoints statistics.
  311. */
  312. static int nilfs_ioctl_get_cpstat(struct inode *inode, struct file *filp,
  313. unsigned int cmd, void __user *argp)
  314. {
  315. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  316. struct nilfs_cpstat cpstat;
  317. int ret;
  318. down_read(&nilfs->ns_segctor_sem);
  319. ret = nilfs_cpfile_get_stat(nilfs->ns_cpfile, &cpstat);
  320. up_read(&nilfs->ns_segctor_sem);
  321. if (ret < 0)
  322. return ret;
  323. if (copy_to_user(argp, &cpstat, sizeof(cpstat)))
  324. ret = -EFAULT;
  325. return ret;
  326. }
  327. /**
  328. * nilfs_ioctl_do_get_suinfo - callback method getting segment usage info
  329. * @nilfs: nilfs object
  330. * @posp: pointer on array of segment numbers
  331. * @flags: *not used*
  332. * @buf: buffer for storing suinfo array
  333. * @size: size in bytes of one suinfo item in array
  334. * @nmembs: count of segment numbers and suinfos in array
  335. *
  336. * Description: nilfs_ioctl_do_get_suinfo() function returns segment usage
  337. * info about requested segments. The NILFS_IOCTL_GET_SUINFO ioctl is used
  338. * in lssu, nilfs_resize utilities and by nilfs_cleanerd daemon.
  339. *
  340. * Return value: count of nilfs_suinfo structures in output buffer.
  341. */
  342. static ssize_t
  343. nilfs_ioctl_do_get_suinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
  344. void *buf, size_t size, size_t nmembs)
  345. {
  346. int ret;
  347. down_read(&nilfs->ns_segctor_sem);
  348. ret = nilfs_sufile_get_suinfo(nilfs->ns_sufile, *posp, buf, size,
  349. nmembs);
  350. up_read(&nilfs->ns_segctor_sem);
  351. return ret;
  352. }
  353. /**
  354. * nilfs_ioctl_get_sustat - get segment usage statistics
  355. * @inode: inode object
  356. * @filp: file object
  357. * @cmd: ioctl's request code
  358. * @argp: pointer on argument from userspace
  359. *
  360. * Description: nilfs_ioctl_get_sustat() returns segment usage statistics.
  361. * The NILFS_IOCTL_GET_SUSTAT ioctl is used in lssu, nilfs_resize utilities
  362. * and by nilfs_cleanerd daemon.
  363. *
  364. * Return Value: On success, 0 is returned, and segment usage information is
  365. * copied into userspace pointer @argp. On error, one of the following
  366. * negative error codes is returned.
  367. *
  368. * %-EIO - I/O error.
  369. *
  370. * %-ENOMEM - Insufficient amount of memory available.
  371. *
  372. * %-EFAULT - Failure during getting segment usage statistics.
  373. */
  374. static int nilfs_ioctl_get_sustat(struct inode *inode, struct file *filp,
  375. unsigned int cmd, void __user *argp)
  376. {
  377. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  378. struct nilfs_sustat sustat;
  379. int ret;
  380. down_read(&nilfs->ns_segctor_sem);
  381. ret = nilfs_sufile_get_stat(nilfs->ns_sufile, &sustat);
  382. up_read(&nilfs->ns_segctor_sem);
  383. if (ret < 0)
  384. return ret;
  385. if (copy_to_user(argp, &sustat, sizeof(sustat)))
  386. ret = -EFAULT;
  387. return ret;
  388. }
  389. /**
  390. * nilfs_ioctl_do_get_vinfo - callback method getting virtual blocks info
  391. * @nilfs: nilfs object
  392. * @posp: *not used*
  393. * @flags: *not used*
  394. * @buf: buffer for storing array of nilfs_vinfo structures
  395. * @size: size in bytes of one vinfo item in array
  396. * @nmembs: count of vinfos in array
  397. *
  398. * Description: nilfs_ioctl_do_get_vinfo() function returns information
  399. * on virtual block addresses. The NILFS_IOCTL_GET_VINFO ioctl is used
  400. * by nilfs_cleanerd daemon.
  401. *
  402. * Return value: count of nilfs_vinfo structures in output buffer.
  403. */
  404. static ssize_t
  405. nilfs_ioctl_do_get_vinfo(struct the_nilfs *nilfs, __u64 *posp, int flags,
  406. void *buf, size_t size, size_t nmembs)
  407. {
  408. int ret;
  409. down_read(&nilfs->ns_segctor_sem);
  410. ret = nilfs_dat_get_vinfo(nilfs->ns_dat, buf, size, nmembs);
  411. up_read(&nilfs->ns_segctor_sem);
  412. return ret;
  413. }
  414. /**
  415. * nilfs_ioctl_do_get_bdescs - callback method getting disk block descriptors
  416. * @nilfs: nilfs object
  417. * @posp: *not used*
  418. * @flags: *not used*
  419. * @buf: buffer for storing array of nilfs_bdesc structures
  420. * @size: size in bytes of one bdesc item in array
  421. * @nmembs: count of bdescs in array
  422. *
  423. * Description: nilfs_ioctl_do_get_bdescs() function returns information
  424. * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
  425. * is used by nilfs_cleanerd daemon.
  426. *
  427. * Return value: count of nilfs_bdescs structures in output buffer.
  428. */
  429. static ssize_t
  430. nilfs_ioctl_do_get_bdescs(struct the_nilfs *nilfs, __u64 *posp, int flags,
  431. void *buf, size_t size, size_t nmembs)
  432. {
  433. struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
  434. struct nilfs_bdesc *bdescs = buf;
  435. int ret, i;
  436. down_read(&nilfs->ns_segctor_sem);
  437. for (i = 0; i < nmembs; i++) {
  438. ret = nilfs_bmap_lookup_at_level(bmap,
  439. bdescs[i].bd_offset,
  440. bdescs[i].bd_level + 1,
  441. &bdescs[i].bd_blocknr);
  442. if (ret < 0) {
  443. if (ret != -ENOENT) {
  444. up_read(&nilfs->ns_segctor_sem);
  445. return ret;
  446. }
  447. bdescs[i].bd_blocknr = 0;
  448. }
  449. }
  450. up_read(&nilfs->ns_segctor_sem);
  451. return nmembs;
  452. }
  453. /**
  454. * nilfs_ioctl_get_bdescs - get disk block descriptors
  455. * @inode: inode object
  456. * @filp: file object
  457. * @cmd: ioctl's request code
  458. * @argp: pointer on argument from userspace
  459. *
  460. * Description: nilfs_ioctl_do_get_bdescs() function returns information
  461. * about descriptors of disk block numbers. The NILFS_IOCTL_GET_BDESCS ioctl
  462. * is used by nilfs_cleanerd daemon.
  463. *
  464. * Return Value: On success, 0 is returned, and disk block descriptors are
  465. * copied into userspace pointer @argp. On error, one of the following
  466. * negative error codes is returned.
  467. *
  468. * %-EINVAL - Invalid arguments from userspace.
  469. *
  470. * %-EIO - I/O error.
  471. *
  472. * %-ENOMEM - Insufficient amount of memory available.
  473. *
  474. * %-EFAULT - Failure during getting disk block descriptors.
  475. */
  476. static int nilfs_ioctl_get_bdescs(struct inode *inode, struct file *filp,
  477. unsigned int cmd, void __user *argp)
  478. {
  479. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  480. struct nilfs_argv argv;
  481. int ret;
  482. if (copy_from_user(&argv, argp, sizeof(argv)))
  483. return -EFAULT;
  484. if (argv.v_size != sizeof(struct nilfs_bdesc))
  485. return -EINVAL;
  486. ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd),
  487. nilfs_ioctl_do_get_bdescs);
  488. if (ret < 0)
  489. return ret;
  490. if (copy_to_user(argp, &argv, sizeof(argv)))
  491. ret = -EFAULT;
  492. return ret;
  493. }
  494. /**
  495. * nilfs_ioctl_move_inode_block - prepare data/node block for moving by GC
  496. * @inode: inode object
  497. * @vdesc: descriptor of virtual block number
  498. * @buffers: list of moving buffers
  499. *
  500. * Description: nilfs_ioctl_move_inode_block() function registers data/node
  501. * buffer in the GC pagecache and submit read request.
  502. *
  503. * Return Value: On success, 0 is returned. On error, one of the following
  504. * negative error codes is returned.
  505. *
  506. * %-EIO - I/O error.
  507. *
  508. * %-ENOMEM - Insufficient amount of memory available.
  509. *
  510. * %-ENOENT - Requested block doesn't exist.
  511. *
  512. * %-EEXIST - Blocks conflict is detected.
  513. */
  514. static int nilfs_ioctl_move_inode_block(struct inode *inode,
  515. struct nilfs_vdesc *vdesc,
  516. struct list_head *buffers)
  517. {
  518. struct buffer_head *bh;
  519. int ret;
  520. if (vdesc->vd_flags == 0)
  521. ret = nilfs_gccache_submit_read_data(
  522. inode, vdesc->vd_offset, vdesc->vd_blocknr,
  523. vdesc->vd_vblocknr, &bh);
  524. else
  525. ret = nilfs_gccache_submit_read_node(
  526. inode, vdesc->vd_blocknr, vdesc->vd_vblocknr, &bh);
  527. if (unlikely(ret < 0)) {
  528. if (ret == -ENOENT)
  529. nilfs_msg(inode->i_sb, KERN_CRIT,
  530. "%s: invalid virtual block address (%s): ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
  531. __func__, vdesc->vd_flags ? "node" : "data",
  532. (unsigned long long)vdesc->vd_ino,
  533. (unsigned long long)vdesc->vd_cno,
  534. (unsigned long long)vdesc->vd_offset,
  535. (unsigned long long)vdesc->vd_blocknr,
  536. (unsigned long long)vdesc->vd_vblocknr);
  537. return ret;
  538. }
  539. if (unlikely(!list_empty(&bh->b_assoc_buffers))) {
  540. nilfs_msg(inode->i_sb, KERN_CRIT,
  541. "%s: conflicting %s buffer: ino=%llu, cno=%llu, offset=%llu, blocknr=%llu, vblocknr=%llu",
  542. __func__, vdesc->vd_flags ? "node" : "data",
  543. (unsigned long long)vdesc->vd_ino,
  544. (unsigned long long)vdesc->vd_cno,
  545. (unsigned long long)vdesc->vd_offset,
  546. (unsigned long long)vdesc->vd_blocknr,
  547. (unsigned long long)vdesc->vd_vblocknr);
  548. brelse(bh);
  549. return -EEXIST;
  550. }
  551. list_add_tail(&bh->b_assoc_buffers, buffers);
  552. return 0;
  553. }
  554. /**
  555. * nilfs_ioctl_move_blocks - move valid inode's blocks during garbage collection
  556. * @sb: superblock object
  557. * @argv: vector of arguments from userspace
  558. * @buf: array of nilfs_vdesc structures
  559. *
  560. * Description: nilfs_ioctl_move_blocks() function reads valid data/node
  561. * blocks that garbage collector specified with the array of nilfs_vdesc
  562. * structures and stores them into page caches of GC inodes.
  563. *
  564. * Return Value: Number of processed nilfs_vdesc structures or
  565. * error code, otherwise.
  566. */
  567. static int nilfs_ioctl_move_blocks(struct super_block *sb,
  568. struct nilfs_argv *argv, void *buf)
  569. {
  570. size_t nmembs = argv->v_nmembs;
  571. struct the_nilfs *nilfs = sb->s_fs_info;
  572. struct inode *inode;
  573. struct nilfs_vdesc *vdesc;
  574. struct buffer_head *bh, *n;
  575. LIST_HEAD(buffers);
  576. ino_t ino;
  577. __u64 cno;
  578. int i, ret;
  579. for (i = 0, vdesc = buf; i < nmembs; ) {
  580. ino = vdesc->vd_ino;
  581. cno = vdesc->vd_cno;
  582. inode = nilfs_iget_for_gc(sb, ino, cno);
  583. if (IS_ERR(inode)) {
  584. ret = PTR_ERR(inode);
  585. goto failed;
  586. }
  587. if (list_empty(&NILFS_I(inode)->i_dirty)) {
  588. /*
  589. * Add the inode to GC inode list. Garbage Collection
  590. * is serialized and no two processes manipulate the
  591. * list simultaneously.
  592. */
  593. igrab(inode);
  594. list_add(&NILFS_I(inode)->i_dirty,
  595. &nilfs->ns_gc_inodes);
  596. }
  597. do {
  598. ret = nilfs_ioctl_move_inode_block(inode, vdesc,
  599. &buffers);
  600. if (unlikely(ret < 0)) {
  601. iput(inode);
  602. goto failed;
  603. }
  604. vdesc++;
  605. } while (++i < nmembs &&
  606. vdesc->vd_ino == ino && vdesc->vd_cno == cno);
  607. iput(inode); /* The inode still remains in GC inode list */
  608. }
  609. list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
  610. ret = nilfs_gccache_wait_and_mark_dirty(bh);
  611. if (unlikely(ret < 0)) {
  612. WARN_ON(ret == -EEXIST);
  613. goto failed;
  614. }
  615. list_del_init(&bh->b_assoc_buffers);
  616. brelse(bh);
  617. }
  618. return nmembs;
  619. failed:
  620. list_for_each_entry_safe(bh, n, &buffers, b_assoc_buffers) {
  621. list_del_init(&bh->b_assoc_buffers);
  622. brelse(bh);
  623. }
  624. return ret;
  625. }
  626. /**
  627. * nilfs_ioctl_delete_checkpoints - delete checkpoints
  628. * @nilfs: nilfs object
  629. * @argv: vector of arguments from userspace
  630. * @buf: array of periods of checkpoints numbers
  631. *
  632. * Description: nilfs_ioctl_delete_checkpoints() function deletes checkpoints
  633. * in the period from p_start to p_end, excluding p_end itself. The checkpoints
  634. * which have been already deleted are ignored.
  635. *
  636. * Return Value: Number of processed nilfs_period structures or
  637. * error code, otherwise.
  638. *
  639. * %-EIO - I/O error.
  640. *
  641. * %-ENOMEM - Insufficient amount of memory available.
  642. *
  643. * %-EINVAL - invalid checkpoints.
  644. */
  645. static int nilfs_ioctl_delete_checkpoints(struct the_nilfs *nilfs,
  646. struct nilfs_argv *argv, void *buf)
  647. {
  648. size_t nmembs = argv->v_nmembs;
  649. struct inode *cpfile = nilfs->ns_cpfile;
  650. struct nilfs_period *periods = buf;
  651. int ret, i;
  652. for (i = 0; i < nmembs; i++) {
  653. ret = nilfs_cpfile_delete_checkpoints(
  654. cpfile, periods[i].p_start, periods[i].p_end);
  655. if (ret < 0)
  656. return ret;
  657. }
  658. return nmembs;
  659. }
  660. /**
  661. * nilfs_ioctl_free_vblocknrs - free virtual block numbers
  662. * @nilfs: nilfs object
  663. * @argv: vector of arguments from userspace
  664. * @buf: array of virtual block numbers
  665. *
  666. * Description: nilfs_ioctl_free_vblocknrs() function frees
  667. * the virtual block numbers specified by @buf and @argv->v_nmembs.
  668. *
  669. * Return Value: Number of processed virtual block numbers or
  670. * error code, otherwise.
  671. *
  672. * %-EIO - I/O error.
  673. *
  674. * %-ENOMEM - Insufficient amount of memory available.
  675. *
  676. * %-ENOENT - The virtual block number have not been allocated.
  677. */
  678. static int nilfs_ioctl_free_vblocknrs(struct the_nilfs *nilfs,
  679. struct nilfs_argv *argv, void *buf)
  680. {
  681. size_t nmembs = argv->v_nmembs;
  682. int ret;
  683. ret = nilfs_dat_freev(nilfs->ns_dat, buf, nmembs);
  684. return (ret < 0) ? ret : nmembs;
  685. }
  686. /**
  687. * nilfs_ioctl_mark_blocks_dirty - mark blocks dirty
  688. * @nilfs: nilfs object
  689. * @argv: vector of arguments from userspace
  690. * @buf: array of block descriptors
  691. *
  692. * Description: nilfs_ioctl_mark_blocks_dirty() function marks
  693. * metadata file or data blocks as dirty.
  694. *
  695. * Return Value: Number of processed block descriptors or
  696. * error code, otherwise.
  697. *
  698. * %-ENOMEM - Insufficient memory available.
  699. *
  700. * %-EIO - I/O error
  701. *
  702. * %-ENOENT - the specified block does not exist (hole block)
  703. */
  704. static int nilfs_ioctl_mark_blocks_dirty(struct the_nilfs *nilfs,
  705. struct nilfs_argv *argv, void *buf)
  706. {
  707. size_t nmembs = argv->v_nmembs;
  708. struct nilfs_bmap *bmap = NILFS_I(nilfs->ns_dat)->i_bmap;
  709. struct nilfs_bdesc *bdescs = buf;
  710. struct buffer_head *bh;
  711. int ret, i;
  712. for (i = 0; i < nmembs; i++) {
  713. /* XXX: use macro or inline func to check liveness */
  714. ret = nilfs_bmap_lookup_at_level(bmap,
  715. bdescs[i].bd_offset,
  716. bdescs[i].bd_level + 1,
  717. &bdescs[i].bd_blocknr);
  718. if (ret < 0) {
  719. if (ret != -ENOENT)
  720. return ret;
  721. bdescs[i].bd_blocknr = 0;
  722. }
  723. if (bdescs[i].bd_blocknr != bdescs[i].bd_oblocknr)
  724. /* skip dead block */
  725. continue;
  726. if (bdescs[i].bd_level == 0) {
  727. ret = nilfs_mdt_get_block(nilfs->ns_dat,
  728. bdescs[i].bd_offset,
  729. false, NULL, &bh);
  730. if (unlikely(ret)) {
  731. WARN_ON(ret == -ENOENT);
  732. return ret;
  733. }
  734. mark_buffer_dirty(bh);
  735. nilfs_mdt_mark_dirty(nilfs->ns_dat);
  736. put_bh(bh);
  737. } else {
  738. ret = nilfs_bmap_mark(bmap, bdescs[i].bd_offset,
  739. bdescs[i].bd_level);
  740. if (ret < 0) {
  741. WARN_ON(ret == -ENOENT);
  742. return ret;
  743. }
  744. }
  745. }
  746. return nmembs;
  747. }
  748. int nilfs_ioctl_prepare_clean_segments(struct the_nilfs *nilfs,
  749. struct nilfs_argv *argv, void **kbufs)
  750. {
  751. const char *msg;
  752. int ret;
  753. ret = nilfs_ioctl_delete_checkpoints(nilfs, &argv[1], kbufs[1]);
  754. if (ret < 0) {
  755. /*
  756. * can safely abort because checkpoints can be removed
  757. * independently.
  758. */
  759. msg = "cannot delete checkpoints";
  760. goto failed;
  761. }
  762. ret = nilfs_ioctl_free_vblocknrs(nilfs, &argv[2], kbufs[2]);
  763. if (ret < 0) {
  764. /*
  765. * can safely abort because DAT file is updated atomically
  766. * using a copy-on-write technique.
  767. */
  768. msg = "cannot delete virtual blocks from DAT file";
  769. goto failed;
  770. }
  771. ret = nilfs_ioctl_mark_blocks_dirty(nilfs, &argv[3], kbufs[3]);
  772. if (ret < 0) {
  773. /*
  774. * can safely abort because the operation is nondestructive.
  775. */
  776. msg = "cannot mark copying blocks dirty";
  777. goto failed;
  778. }
  779. return 0;
  780. failed:
  781. nilfs_msg(nilfs->ns_sb, KERN_ERR, "error %d preparing GC: %s", ret,
  782. msg);
  783. return ret;
  784. }
  785. /**
  786. * nilfs_ioctl_clean_segments - clean segments
  787. * @inode: inode object
  788. * @filp: file object
  789. * @cmd: ioctl's request code
  790. * @argp: pointer on argument from userspace
  791. *
  792. * Description: nilfs_ioctl_clean_segments() function makes garbage
  793. * collection operation in the environment of requested parameters
  794. * from userspace. The NILFS_IOCTL_CLEAN_SEGMENTS ioctl is used by
  795. * nilfs_cleanerd daemon.
  796. *
  797. * Return Value: On success, 0 is returned or error code, otherwise.
  798. */
  799. static int nilfs_ioctl_clean_segments(struct inode *inode, struct file *filp,
  800. unsigned int cmd, void __user *argp)
  801. {
  802. struct nilfs_argv argv[5];
  803. static const size_t argsz[5] = {
  804. sizeof(struct nilfs_vdesc),
  805. sizeof(struct nilfs_period),
  806. sizeof(__u64),
  807. sizeof(struct nilfs_bdesc),
  808. sizeof(__u64),
  809. };
  810. void __user *base;
  811. void *kbufs[5];
  812. struct the_nilfs *nilfs;
  813. size_t len, nsegs;
  814. int n, ret;
  815. if (!capable(CAP_SYS_ADMIN))
  816. return -EPERM;
  817. ret = mnt_want_write_file(filp);
  818. if (ret)
  819. return ret;
  820. ret = -EFAULT;
  821. if (copy_from_user(argv, argp, sizeof(argv)))
  822. goto out;
  823. ret = -EINVAL;
  824. nsegs = argv[4].v_nmembs;
  825. if (argv[4].v_size != argsz[4])
  826. goto out;
  827. if (nsegs > UINT_MAX / sizeof(__u64))
  828. goto out;
  829. /*
  830. * argv[4] points to segment numbers this ioctl cleans. We
  831. * use kmalloc() for its buffer because memory used for the
  832. * segment numbers is enough small.
  833. */
  834. kbufs[4] = memdup_user((void __user *)(unsigned long)argv[4].v_base,
  835. nsegs * sizeof(__u64));
  836. if (IS_ERR(kbufs[4])) {
  837. ret = PTR_ERR(kbufs[4]);
  838. goto out;
  839. }
  840. nilfs = inode->i_sb->s_fs_info;
  841. for (n = 0; n < 4; n++) {
  842. ret = -EINVAL;
  843. if (argv[n].v_size != argsz[n])
  844. goto out_free;
  845. if (argv[n].v_nmembs > nsegs * nilfs->ns_blocks_per_segment)
  846. goto out_free;
  847. if (argv[n].v_nmembs >= UINT_MAX / argv[n].v_size)
  848. goto out_free;
  849. len = argv[n].v_size * argv[n].v_nmembs;
  850. base = (void __user *)(unsigned long)argv[n].v_base;
  851. if (len == 0) {
  852. kbufs[n] = NULL;
  853. continue;
  854. }
  855. kbufs[n] = vmalloc(len);
  856. if (!kbufs[n]) {
  857. ret = -ENOMEM;
  858. goto out_free;
  859. }
  860. if (copy_from_user(kbufs[n], base, len)) {
  861. ret = -EFAULT;
  862. vfree(kbufs[n]);
  863. goto out_free;
  864. }
  865. }
  866. /*
  867. * nilfs_ioctl_move_blocks() will call nilfs_iget_for_gc(),
  868. * which will operates an inode list without blocking.
  869. * To protect the list from concurrent operations,
  870. * nilfs_ioctl_move_blocks should be atomic operation.
  871. */
  872. if (test_and_set_bit(THE_NILFS_GC_RUNNING, &nilfs->ns_flags)) {
  873. ret = -EBUSY;
  874. goto out_free;
  875. }
  876. ret = nilfs_ioctl_move_blocks(inode->i_sb, &argv[0], kbufs[0]);
  877. if (ret < 0) {
  878. nilfs_msg(inode->i_sb, KERN_ERR,
  879. "error %d preparing GC: cannot read source blocks",
  880. ret);
  881. } else {
  882. if (nilfs_sb_need_update(nilfs))
  883. set_nilfs_discontinued(nilfs);
  884. ret = nilfs_clean_segments(inode->i_sb, argv, kbufs);
  885. }
  886. nilfs_remove_all_gcinodes(nilfs);
  887. clear_nilfs_gc_running(nilfs);
  888. out_free:
  889. while (--n >= 0)
  890. vfree(kbufs[n]);
  891. kfree(kbufs[4]);
  892. out:
  893. mnt_drop_write_file(filp);
  894. return ret;
  895. }
  896. /**
  897. * nilfs_ioctl_sync - make a checkpoint
  898. * @inode: inode object
  899. * @filp: file object
  900. * @cmd: ioctl's request code
  901. * @argp: pointer on argument from userspace
  902. *
  903. * Description: nilfs_ioctl_sync() function constructs a logical segment
  904. * for checkpointing. This function guarantees that all modified data
  905. * and metadata are written out to the device when it successfully
  906. * returned.
  907. *
  908. * Return Value: On success, 0 is retured. On errors, one of the following
  909. * negative error code is returned.
  910. *
  911. * %-EROFS - Read only filesystem.
  912. *
  913. * %-EIO - I/O error
  914. *
  915. * %-ENOSPC - No space left on device (only in a panic state).
  916. *
  917. * %-ERESTARTSYS - Interrupted.
  918. *
  919. * %-ENOMEM - Insufficient memory available.
  920. *
  921. * %-EFAULT - Failure during execution of requested operation.
  922. */
  923. static int nilfs_ioctl_sync(struct inode *inode, struct file *filp,
  924. unsigned int cmd, void __user *argp)
  925. {
  926. __u64 cno;
  927. int ret;
  928. struct the_nilfs *nilfs;
  929. ret = nilfs_construct_segment(inode->i_sb);
  930. if (ret < 0)
  931. return ret;
  932. nilfs = inode->i_sb->s_fs_info;
  933. ret = nilfs_flush_device(nilfs);
  934. if (ret < 0)
  935. return ret;
  936. if (argp != NULL) {
  937. down_read(&nilfs->ns_segctor_sem);
  938. cno = nilfs->ns_cno - 1;
  939. up_read(&nilfs->ns_segctor_sem);
  940. if (copy_to_user(argp, &cno, sizeof(cno)))
  941. return -EFAULT;
  942. }
  943. return 0;
  944. }
  945. /**
  946. * nilfs_ioctl_resize - resize NILFS2 volume
  947. * @inode: inode object
  948. * @filp: file object
  949. * @argp: pointer on argument from userspace
  950. *
  951. * Return Value: On success, 0 is returned or error code, otherwise.
  952. */
  953. static int nilfs_ioctl_resize(struct inode *inode, struct file *filp,
  954. void __user *argp)
  955. {
  956. __u64 newsize;
  957. int ret = -EPERM;
  958. if (!capable(CAP_SYS_ADMIN))
  959. goto out;
  960. ret = mnt_want_write_file(filp);
  961. if (ret)
  962. goto out;
  963. ret = -EFAULT;
  964. if (copy_from_user(&newsize, argp, sizeof(newsize)))
  965. goto out_drop_write;
  966. ret = nilfs_resize_fs(inode->i_sb, newsize);
  967. out_drop_write:
  968. mnt_drop_write_file(filp);
  969. out:
  970. return ret;
  971. }
  972. /**
  973. * nilfs_ioctl_trim_fs() - trim ioctl handle function
  974. * @inode: inode object
  975. * @argp: pointer on argument from userspace
  976. *
  977. * Decription: nilfs_ioctl_trim_fs is the FITRIM ioctl handle function. It
  978. * checks the arguments from userspace and calls nilfs_sufile_trim_fs, which
  979. * performs the actual trim operation.
  980. *
  981. * Return Value: On success, 0 is returned or negative error code, otherwise.
  982. */
  983. static int nilfs_ioctl_trim_fs(struct inode *inode, void __user *argp)
  984. {
  985. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  986. struct request_queue *q = bdev_get_queue(nilfs->ns_bdev);
  987. struct fstrim_range range;
  988. int ret;
  989. if (!capable(CAP_SYS_ADMIN))
  990. return -EPERM;
  991. if (!blk_queue_discard(q))
  992. return -EOPNOTSUPP;
  993. if (copy_from_user(&range, argp, sizeof(range)))
  994. return -EFAULT;
  995. range.minlen = max_t(u64, range.minlen, q->limits.discard_granularity);
  996. down_read(&nilfs->ns_segctor_sem);
  997. ret = nilfs_sufile_trim_fs(nilfs->ns_sufile, &range);
  998. up_read(&nilfs->ns_segctor_sem);
  999. if (ret < 0)
  1000. return ret;
  1001. if (copy_to_user(argp, &range, sizeof(range)))
  1002. return -EFAULT;
  1003. return 0;
  1004. }
  1005. /**
  1006. * nilfs_ioctl_set_alloc_range - limit range of segments to be allocated
  1007. * @inode: inode object
  1008. * @argp: pointer on argument from userspace
  1009. *
  1010. * Decription: nilfs_ioctl_set_alloc_range() function defines lower limit
  1011. * of segments in bytes and upper limit of segments in bytes.
  1012. * The NILFS_IOCTL_SET_ALLOC_RANGE is used by nilfs_resize utility.
  1013. *
  1014. * Return Value: On success, 0 is returned or error code, otherwise.
  1015. */
  1016. static int nilfs_ioctl_set_alloc_range(struct inode *inode, void __user *argp)
  1017. {
  1018. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  1019. __u64 range[2];
  1020. __u64 minseg, maxseg;
  1021. unsigned long segbytes;
  1022. int ret = -EPERM;
  1023. if (!capable(CAP_SYS_ADMIN))
  1024. goto out;
  1025. ret = -EFAULT;
  1026. if (copy_from_user(range, argp, sizeof(__u64[2])))
  1027. goto out;
  1028. ret = -ERANGE;
  1029. if (range[1] > i_size_read(inode->i_sb->s_bdev->bd_inode))
  1030. goto out;
  1031. segbytes = nilfs->ns_blocks_per_segment * nilfs->ns_blocksize;
  1032. minseg = range[0] + segbytes - 1;
  1033. do_div(minseg, segbytes);
  1034. maxseg = NILFS_SB2_OFFSET_BYTES(range[1]);
  1035. do_div(maxseg, segbytes);
  1036. maxseg--;
  1037. ret = nilfs_sufile_set_alloc_range(nilfs->ns_sufile, minseg, maxseg);
  1038. out:
  1039. return ret;
  1040. }
  1041. /**
  1042. * nilfs_ioctl_get_info - wrapping function of get metadata info
  1043. * @inode: inode object
  1044. * @filp: file object
  1045. * @cmd: ioctl's request code
  1046. * @argp: pointer on argument from userspace
  1047. * @membsz: size of an item in bytes
  1048. * @dofunc: concrete function of getting metadata info
  1049. *
  1050. * Description: nilfs_ioctl_get_info() gets metadata info by means of
  1051. * calling dofunc() function.
  1052. *
  1053. * Return Value: On success, 0 is returned and requested metadata info
  1054. * is copied into userspace. On error, one of the following
  1055. * negative error codes is returned.
  1056. *
  1057. * %-EINVAL - Invalid arguments from userspace.
  1058. *
  1059. * %-ENOMEM - Insufficient amount of memory available.
  1060. *
  1061. * %-EFAULT - Failure during execution of requested operation.
  1062. */
  1063. static int nilfs_ioctl_get_info(struct inode *inode, struct file *filp,
  1064. unsigned int cmd, void __user *argp,
  1065. size_t membsz,
  1066. ssize_t (*dofunc)(struct the_nilfs *,
  1067. __u64 *, int,
  1068. void *, size_t, size_t))
  1069. {
  1070. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  1071. struct nilfs_argv argv;
  1072. int ret;
  1073. if (copy_from_user(&argv, argp, sizeof(argv)))
  1074. return -EFAULT;
  1075. if (argv.v_size < membsz)
  1076. return -EINVAL;
  1077. ret = nilfs_ioctl_wrap_copy(nilfs, &argv, _IOC_DIR(cmd), dofunc);
  1078. if (ret < 0)
  1079. return ret;
  1080. if (copy_to_user(argp, &argv, sizeof(argv)))
  1081. ret = -EFAULT;
  1082. return ret;
  1083. }
  1084. /**
  1085. * nilfs_ioctl_set_suinfo - set segment usage info
  1086. * @inode: inode object
  1087. * @filp: file object
  1088. * @cmd: ioctl's request code
  1089. * @argp: pointer on argument from userspace
  1090. *
  1091. * Description: Expects an array of nilfs_suinfo_update structures
  1092. * encapsulated in nilfs_argv and updates the segment usage info
  1093. * according to the flags in nilfs_suinfo_update.
  1094. *
  1095. * Return Value: On success, 0 is returned. On error, one of the
  1096. * following negative error codes is returned.
  1097. *
  1098. * %-EPERM - Not enough permissions
  1099. *
  1100. * %-EFAULT - Error copying input data
  1101. *
  1102. * %-EIO - I/O error.
  1103. *
  1104. * %-ENOMEM - Insufficient amount of memory available.
  1105. *
  1106. * %-EINVAL - Invalid values in input (segment number, flags or nblocks)
  1107. */
  1108. static int nilfs_ioctl_set_suinfo(struct inode *inode, struct file *filp,
  1109. unsigned int cmd, void __user *argp)
  1110. {
  1111. struct the_nilfs *nilfs = inode->i_sb->s_fs_info;
  1112. struct nilfs_transaction_info ti;
  1113. struct nilfs_argv argv;
  1114. size_t len;
  1115. void __user *base;
  1116. void *kbuf;
  1117. int ret;
  1118. if (!capable(CAP_SYS_ADMIN))
  1119. return -EPERM;
  1120. ret = mnt_want_write_file(filp);
  1121. if (ret)
  1122. return ret;
  1123. ret = -EFAULT;
  1124. if (copy_from_user(&argv, argp, sizeof(argv)))
  1125. goto out;
  1126. ret = -EINVAL;
  1127. if (argv.v_size < sizeof(struct nilfs_suinfo_update))
  1128. goto out;
  1129. if (argv.v_nmembs > nilfs->ns_nsegments)
  1130. goto out;
  1131. if (argv.v_nmembs >= UINT_MAX / argv.v_size)
  1132. goto out;
  1133. len = argv.v_size * argv.v_nmembs;
  1134. if (!len) {
  1135. ret = 0;
  1136. goto out;
  1137. }
  1138. base = (void __user *)(unsigned long)argv.v_base;
  1139. kbuf = vmalloc(len);
  1140. if (!kbuf) {
  1141. ret = -ENOMEM;
  1142. goto out;
  1143. }
  1144. if (copy_from_user(kbuf, base, len)) {
  1145. ret = -EFAULT;
  1146. goto out_free;
  1147. }
  1148. nilfs_transaction_begin(inode->i_sb, &ti, 0);
  1149. ret = nilfs_sufile_set_suinfo(nilfs->ns_sufile, kbuf, argv.v_size,
  1150. argv.v_nmembs);
  1151. if (unlikely(ret < 0))
  1152. nilfs_transaction_abort(inode->i_sb);
  1153. else
  1154. nilfs_transaction_commit(inode->i_sb); /* never fails */
  1155. out_free:
  1156. vfree(kbuf);
  1157. out:
  1158. mnt_drop_write_file(filp);
  1159. return ret;
  1160. }
  1161. long nilfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  1162. {
  1163. struct inode *inode = file_inode(filp);
  1164. void __user *argp = (void __user *)arg;
  1165. switch (cmd) {
  1166. case FS_IOC_GETFLAGS:
  1167. return nilfs_ioctl_getflags(inode, argp);
  1168. case FS_IOC_SETFLAGS:
  1169. return nilfs_ioctl_setflags(inode, filp, argp);
  1170. case FS_IOC_GETVERSION:
  1171. return nilfs_ioctl_getversion(inode, argp);
  1172. case NILFS_IOCTL_CHANGE_CPMODE:
  1173. return nilfs_ioctl_change_cpmode(inode, filp, cmd, argp);
  1174. case NILFS_IOCTL_DELETE_CHECKPOINT:
  1175. return nilfs_ioctl_delete_checkpoint(inode, filp, cmd, argp);
  1176. case NILFS_IOCTL_GET_CPINFO:
  1177. return nilfs_ioctl_get_info(inode, filp, cmd, argp,
  1178. sizeof(struct nilfs_cpinfo),
  1179. nilfs_ioctl_do_get_cpinfo);
  1180. case NILFS_IOCTL_GET_CPSTAT:
  1181. return nilfs_ioctl_get_cpstat(inode, filp, cmd, argp);
  1182. case NILFS_IOCTL_GET_SUINFO:
  1183. return nilfs_ioctl_get_info(inode, filp, cmd, argp,
  1184. sizeof(struct nilfs_suinfo),
  1185. nilfs_ioctl_do_get_suinfo);
  1186. case NILFS_IOCTL_SET_SUINFO:
  1187. return nilfs_ioctl_set_suinfo(inode, filp, cmd, argp);
  1188. case NILFS_IOCTL_GET_SUSTAT:
  1189. return nilfs_ioctl_get_sustat(inode, filp, cmd, argp);
  1190. case NILFS_IOCTL_GET_VINFO:
  1191. return nilfs_ioctl_get_info(inode, filp, cmd, argp,
  1192. sizeof(struct nilfs_vinfo),
  1193. nilfs_ioctl_do_get_vinfo);
  1194. case NILFS_IOCTL_GET_BDESCS:
  1195. return nilfs_ioctl_get_bdescs(inode, filp, cmd, argp);
  1196. case NILFS_IOCTL_CLEAN_SEGMENTS:
  1197. return nilfs_ioctl_clean_segments(inode, filp, cmd, argp);
  1198. case NILFS_IOCTL_SYNC:
  1199. return nilfs_ioctl_sync(inode, filp, cmd, argp);
  1200. case NILFS_IOCTL_RESIZE:
  1201. return nilfs_ioctl_resize(inode, filp, argp);
  1202. case NILFS_IOCTL_SET_ALLOC_RANGE:
  1203. return nilfs_ioctl_set_alloc_range(inode, argp);
  1204. case FITRIM:
  1205. return nilfs_ioctl_trim_fs(inode, argp);
  1206. default:
  1207. return -ENOTTY;
  1208. }
  1209. }
  1210. #ifdef CONFIG_COMPAT
  1211. long nilfs_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
  1212. {
  1213. switch (cmd) {
  1214. case FS_IOC32_GETFLAGS:
  1215. cmd = FS_IOC_GETFLAGS;
  1216. break;
  1217. case FS_IOC32_SETFLAGS:
  1218. cmd = FS_IOC_SETFLAGS;
  1219. break;
  1220. case FS_IOC32_GETVERSION:
  1221. cmd = FS_IOC_GETVERSION;
  1222. break;
  1223. case NILFS_IOCTL_CHANGE_CPMODE:
  1224. case NILFS_IOCTL_DELETE_CHECKPOINT:
  1225. case NILFS_IOCTL_GET_CPINFO:
  1226. case NILFS_IOCTL_GET_CPSTAT:
  1227. case NILFS_IOCTL_GET_SUINFO:
  1228. case NILFS_IOCTL_SET_SUINFO:
  1229. case NILFS_IOCTL_GET_SUSTAT:
  1230. case NILFS_IOCTL_GET_VINFO:
  1231. case NILFS_IOCTL_GET_BDESCS:
  1232. case NILFS_IOCTL_CLEAN_SEGMENTS:
  1233. case NILFS_IOCTL_SYNC:
  1234. case NILFS_IOCTL_RESIZE:
  1235. case NILFS_IOCTL_SET_ALLOC_RANGE:
  1236. break;
  1237. default:
  1238. return -ENOIOCTLCMD;
  1239. }
  1240. return nilfs_ioctl(filp, cmd, (unsigned long)compat_ptr(arg));
  1241. }
  1242. #endif