ioctl.c 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377
  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