quota_tree.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * vfsv0 quota IO operations on file
  4. */
  5. #include <linux/errno.h>
  6. #include <linux/fs.h>
  7. #include <linux/mount.h>
  8. #include <linux/dqblk_v2.h>
  9. #include <linux/kernel.h>
  10. #include <linux/init.h>
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <linux/quotaops.h>
  14. #include <asm/byteorder.h>
  15. #include "quota_tree.h"
  16. MODULE_AUTHOR("Jan Kara");
  17. MODULE_DESCRIPTION("Quota trie support");
  18. MODULE_LICENSE("GPL");
  19. #define __QUOTA_QT_PARANOIA
  20. static int __get_index(struct qtree_mem_dqinfo *info, qid_t id, int depth)
  21. {
  22. unsigned int epb = info->dqi_usable_bs >> 2;
  23. depth = info->dqi_qtree_depth - depth - 1;
  24. while (depth--)
  25. id /= epb;
  26. return id % epb;
  27. }
  28. static int get_index(struct qtree_mem_dqinfo *info, struct kqid qid, int depth)
  29. {
  30. qid_t id = from_kqid(&init_user_ns, qid);
  31. return __get_index(info, id, depth);
  32. }
  33. /* Number of entries in one blocks */
  34. static int qtree_dqstr_in_blk(struct qtree_mem_dqinfo *info)
  35. {
  36. return (info->dqi_usable_bs - sizeof(struct qt_disk_dqdbheader))
  37. / info->dqi_entry_size;
  38. }
  39. static char *getdqbuf(size_t size)
  40. {
  41. char *buf = kmalloc(size, GFP_NOFS);
  42. if (!buf)
  43. printk(KERN_WARNING
  44. "VFS: Not enough memory for quota buffers.\n");
  45. return buf;
  46. }
  47. static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
  48. {
  49. struct super_block *sb = info->dqi_sb;
  50. memset(buf, 0, info->dqi_usable_bs);
  51. return sb->s_op->quota_read(sb, info->dqi_type, buf,
  52. info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
  53. }
  54. static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
  55. {
  56. struct super_block *sb = info->dqi_sb;
  57. ssize_t ret;
  58. ret = sb->s_op->quota_write(sb, info->dqi_type, buf,
  59. info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
  60. if (ret != info->dqi_usable_bs) {
  61. quota_error(sb, "dquota write failed");
  62. if (ret >= 0)
  63. ret = -EIO;
  64. }
  65. return ret;
  66. }
  67. /* Remove empty block from list and return it */
  68. static int get_free_dqblk(struct qtree_mem_dqinfo *info)
  69. {
  70. char *buf = getdqbuf(info->dqi_usable_bs);
  71. struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
  72. int ret, blk;
  73. if (!buf)
  74. return -ENOMEM;
  75. if (info->dqi_free_blk) {
  76. blk = info->dqi_free_blk;
  77. ret = read_blk(info, blk, buf);
  78. if (ret < 0)
  79. goto out_buf;
  80. info->dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
  81. }
  82. else {
  83. memset(buf, 0, info->dqi_usable_bs);
  84. /* Assure block allocation... */
  85. ret = write_blk(info, info->dqi_blocks, buf);
  86. if (ret < 0)
  87. goto out_buf;
  88. blk = info->dqi_blocks++;
  89. }
  90. mark_info_dirty(info->dqi_sb, info->dqi_type);
  91. ret = blk;
  92. out_buf:
  93. kfree(buf);
  94. return ret;
  95. }
  96. /* Insert empty block to the list */
  97. static int put_free_dqblk(struct qtree_mem_dqinfo *info, char *buf, uint blk)
  98. {
  99. struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
  100. int err;
  101. dh->dqdh_next_free = cpu_to_le32(info->dqi_free_blk);
  102. dh->dqdh_prev_free = cpu_to_le32(0);
  103. dh->dqdh_entries = cpu_to_le16(0);
  104. err = write_blk(info, blk, buf);
  105. if (err < 0)
  106. return err;
  107. info->dqi_free_blk = blk;
  108. mark_info_dirty(info->dqi_sb, info->dqi_type);
  109. return 0;
  110. }
  111. /* Remove given block from the list of blocks with free entries */
  112. static int remove_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
  113. uint blk)
  114. {
  115. char *tmpbuf = getdqbuf(info->dqi_usable_bs);
  116. struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
  117. uint nextblk = le32_to_cpu(dh->dqdh_next_free);
  118. uint prevblk = le32_to_cpu(dh->dqdh_prev_free);
  119. int err;
  120. if (!tmpbuf)
  121. return -ENOMEM;
  122. if (nextblk) {
  123. err = read_blk(info, nextblk, tmpbuf);
  124. if (err < 0)
  125. goto out_buf;
  126. ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
  127. dh->dqdh_prev_free;
  128. err = write_blk(info, nextblk, tmpbuf);
  129. if (err < 0)
  130. goto out_buf;
  131. }
  132. if (prevblk) {
  133. err = read_blk(info, prevblk, tmpbuf);
  134. if (err < 0)
  135. goto out_buf;
  136. ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_next_free =
  137. dh->dqdh_next_free;
  138. err = write_blk(info, prevblk, tmpbuf);
  139. if (err < 0)
  140. goto out_buf;
  141. } else {
  142. info->dqi_free_entry = nextblk;
  143. mark_info_dirty(info->dqi_sb, info->dqi_type);
  144. }
  145. kfree(tmpbuf);
  146. dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
  147. /* No matter whether write succeeds block is out of list */
  148. if (write_blk(info, blk, buf) < 0)
  149. quota_error(info->dqi_sb, "Can't write block (%u) "
  150. "with free entries", blk);
  151. return 0;
  152. out_buf:
  153. kfree(tmpbuf);
  154. return err;
  155. }
  156. /* Insert given block to the beginning of list with free entries */
  157. static int insert_free_dqentry(struct qtree_mem_dqinfo *info, char *buf,
  158. uint blk)
  159. {
  160. char *tmpbuf = getdqbuf(info->dqi_usable_bs);
  161. struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
  162. int err;
  163. if (!tmpbuf)
  164. return -ENOMEM;
  165. dh->dqdh_next_free = cpu_to_le32(info->dqi_free_entry);
  166. dh->dqdh_prev_free = cpu_to_le32(0);
  167. err = write_blk(info, blk, buf);
  168. if (err < 0)
  169. goto out_buf;
  170. if (info->dqi_free_entry) {
  171. err = read_blk(info, info->dqi_free_entry, tmpbuf);
  172. if (err < 0)
  173. goto out_buf;
  174. ((struct qt_disk_dqdbheader *)tmpbuf)->dqdh_prev_free =
  175. cpu_to_le32(blk);
  176. err = write_blk(info, info->dqi_free_entry, tmpbuf);
  177. if (err < 0)
  178. goto out_buf;
  179. }
  180. kfree(tmpbuf);
  181. info->dqi_free_entry = blk;
  182. mark_info_dirty(info->dqi_sb, info->dqi_type);
  183. return 0;
  184. out_buf:
  185. kfree(tmpbuf);
  186. return err;
  187. }
  188. /* Is the entry in the block free? */
  189. int qtree_entry_unused(struct qtree_mem_dqinfo *info, char *disk)
  190. {
  191. int i;
  192. for (i = 0; i < info->dqi_entry_size; i++)
  193. if (disk[i])
  194. return 0;
  195. return 1;
  196. }
  197. EXPORT_SYMBOL(qtree_entry_unused);
  198. /* Find space for dquot */
  199. static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
  200. struct dquot *dquot, int *err)
  201. {
  202. uint blk, i;
  203. struct qt_disk_dqdbheader *dh;
  204. char *buf = getdqbuf(info->dqi_usable_bs);
  205. char *ddquot;
  206. *err = 0;
  207. if (!buf) {
  208. *err = -ENOMEM;
  209. return 0;
  210. }
  211. dh = (struct qt_disk_dqdbheader *)buf;
  212. if (info->dqi_free_entry) {
  213. blk = info->dqi_free_entry;
  214. *err = read_blk(info, blk, buf);
  215. if (*err < 0)
  216. goto out_buf;
  217. } else {
  218. blk = get_free_dqblk(info);
  219. if ((int)blk < 0) {
  220. *err = blk;
  221. kfree(buf);
  222. return 0;
  223. }
  224. memset(buf, 0, info->dqi_usable_bs);
  225. /* This is enough as the block is already zeroed and the entry
  226. * list is empty... */
  227. info->dqi_free_entry = blk;
  228. mark_info_dirty(dquot->dq_sb, dquot->dq_id.type);
  229. }
  230. /* Block will be full? */
  231. if (le16_to_cpu(dh->dqdh_entries) + 1 >= qtree_dqstr_in_blk(info)) {
  232. *err = remove_free_dqentry(info, buf, blk);
  233. if (*err < 0) {
  234. quota_error(dquot->dq_sb, "Can't remove block (%u) "
  235. "from entry free list", blk);
  236. goto out_buf;
  237. }
  238. }
  239. le16_add_cpu(&dh->dqdh_entries, 1);
  240. /* Find free structure in block */
  241. ddquot = buf + sizeof(struct qt_disk_dqdbheader);
  242. for (i = 0; i < qtree_dqstr_in_blk(info); i++) {
  243. if (qtree_entry_unused(info, ddquot))
  244. break;
  245. ddquot += info->dqi_entry_size;
  246. }
  247. #ifdef __QUOTA_QT_PARANOIA
  248. if (i == qtree_dqstr_in_blk(info)) {
  249. quota_error(dquot->dq_sb, "Data block full but it shouldn't");
  250. *err = -EIO;
  251. goto out_buf;
  252. }
  253. #endif
  254. *err = write_blk(info, blk, buf);
  255. if (*err < 0) {
  256. quota_error(dquot->dq_sb, "Can't write quota data block %u",
  257. blk);
  258. goto out_buf;
  259. }
  260. dquot->dq_off = ((loff_t)blk << info->dqi_blocksize_bits) +
  261. sizeof(struct qt_disk_dqdbheader) +
  262. i * info->dqi_entry_size;
  263. kfree(buf);
  264. return blk;
  265. out_buf:
  266. kfree(buf);
  267. return 0;
  268. }
  269. /* Insert reference to structure into the trie */
  270. static int do_insert_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
  271. uint *treeblk, int depth)
  272. {
  273. char *buf = getdqbuf(info->dqi_usable_bs);
  274. int ret = 0, newson = 0, newact = 0;
  275. __le32 *ref;
  276. uint newblk;
  277. if (!buf)
  278. return -ENOMEM;
  279. if (!*treeblk) {
  280. ret = get_free_dqblk(info);
  281. if (ret < 0)
  282. goto out_buf;
  283. *treeblk = ret;
  284. memset(buf, 0, info->dqi_usable_bs);
  285. newact = 1;
  286. } else {
  287. ret = read_blk(info, *treeblk, buf);
  288. if (ret < 0) {
  289. quota_error(dquot->dq_sb, "Can't read tree quota "
  290. "block %u", *treeblk);
  291. goto out_buf;
  292. }
  293. }
  294. ref = (__le32 *)buf;
  295. newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
  296. if (!newblk)
  297. newson = 1;
  298. if (depth == info->dqi_qtree_depth - 1) {
  299. #ifdef __QUOTA_QT_PARANOIA
  300. if (newblk) {
  301. quota_error(dquot->dq_sb, "Inserting already present "
  302. "quota entry (block %u)",
  303. le32_to_cpu(ref[get_index(info,
  304. dquot->dq_id, depth)]));
  305. ret = -EIO;
  306. goto out_buf;
  307. }
  308. #endif
  309. newblk = find_free_dqentry(info, dquot, &ret);
  310. } else {
  311. ret = do_insert_tree(info, dquot, &newblk, depth+1);
  312. }
  313. if (newson && ret >= 0) {
  314. ref[get_index(info, dquot->dq_id, depth)] =
  315. cpu_to_le32(newblk);
  316. ret = write_blk(info, *treeblk, buf);
  317. } else if (newact && ret < 0) {
  318. put_free_dqblk(info, buf, *treeblk);
  319. }
  320. out_buf:
  321. kfree(buf);
  322. return ret;
  323. }
  324. /* Wrapper for inserting quota structure into tree */
  325. static inline int dq_insert_tree(struct qtree_mem_dqinfo *info,
  326. struct dquot *dquot)
  327. {
  328. int tmp = QT_TREEOFF;
  329. #ifdef __QUOTA_QT_PARANOIA
  330. if (info->dqi_blocks <= QT_TREEOFF) {
  331. quota_error(dquot->dq_sb, "Quota tree root isn't allocated!");
  332. return -EIO;
  333. }
  334. #endif
  335. return do_insert_tree(info, dquot, &tmp, 0);
  336. }
  337. /*
  338. * We don't have to be afraid of deadlocks as we never have quotas on quota
  339. * files...
  340. */
  341. int qtree_write_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
  342. {
  343. int type = dquot->dq_id.type;
  344. struct super_block *sb = dquot->dq_sb;
  345. ssize_t ret;
  346. char *ddquot = getdqbuf(info->dqi_entry_size);
  347. if (!ddquot)
  348. return -ENOMEM;
  349. /* dq_off is guarded by dqio_sem */
  350. if (!dquot->dq_off) {
  351. ret = dq_insert_tree(info, dquot);
  352. if (ret < 0) {
  353. quota_error(sb, "Error %zd occurred while creating "
  354. "quota", ret);
  355. kfree(ddquot);
  356. return ret;
  357. }
  358. }
  359. spin_lock(&dquot->dq_dqb_lock);
  360. info->dqi_ops->mem2disk_dqblk(ddquot, dquot);
  361. spin_unlock(&dquot->dq_dqb_lock);
  362. ret = sb->s_op->quota_write(sb, type, ddquot, info->dqi_entry_size,
  363. dquot->dq_off);
  364. if (ret != info->dqi_entry_size) {
  365. quota_error(sb, "dquota write failed");
  366. if (ret >= 0)
  367. ret = -ENOSPC;
  368. } else {
  369. ret = 0;
  370. }
  371. dqstats_inc(DQST_WRITES);
  372. kfree(ddquot);
  373. return ret;
  374. }
  375. EXPORT_SYMBOL(qtree_write_dquot);
  376. /* Free dquot entry in data block */
  377. static int free_dqentry(struct qtree_mem_dqinfo *info, struct dquot *dquot,
  378. uint blk)
  379. {
  380. struct qt_disk_dqdbheader *dh;
  381. char *buf = getdqbuf(info->dqi_usable_bs);
  382. int ret = 0;
  383. if (!buf)
  384. return -ENOMEM;
  385. if (dquot->dq_off >> info->dqi_blocksize_bits != blk) {
  386. quota_error(dquot->dq_sb, "Quota structure has offset to "
  387. "other block (%u) than it should (%u)", blk,
  388. (uint)(dquot->dq_off >> info->dqi_blocksize_bits));
  389. ret = -EIO;
  390. goto out_buf;
  391. }
  392. ret = read_blk(info, blk, buf);
  393. if (ret < 0) {
  394. quota_error(dquot->dq_sb, "Can't read quota data block %u",
  395. blk);
  396. goto out_buf;
  397. }
  398. dh = (struct qt_disk_dqdbheader *)buf;
  399. le16_add_cpu(&dh->dqdh_entries, -1);
  400. if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
  401. ret = remove_free_dqentry(info, buf, blk);
  402. if (ret >= 0)
  403. ret = put_free_dqblk(info, buf, blk);
  404. if (ret < 0) {
  405. quota_error(dquot->dq_sb, "Can't move quota data block "
  406. "(%u) to free list", blk);
  407. goto out_buf;
  408. }
  409. } else {
  410. memset(buf +
  411. (dquot->dq_off & ((1 << info->dqi_blocksize_bits) - 1)),
  412. 0, info->dqi_entry_size);
  413. if (le16_to_cpu(dh->dqdh_entries) ==
  414. qtree_dqstr_in_blk(info) - 1) {
  415. /* Insert will write block itself */
  416. ret = insert_free_dqentry(info, buf, blk);
  417. if (ret < 0) {
  418. quota_error(dquot->dq_sb, "Can't insert quota "
  419. "data block (%u) to free entry list", blk);
  420. goto out_buf;
  421. }
  422. } else {
  423. ret = write_blk(info, blk, buf);
  424. if (ret < 0) {
  425. quota_error(dquot->dq_sb, "Can't write quota "
  426. "data block %u", blk);
  427. goto out_buf;
  428. }
  429. }
  430. }
  431. dquot->dq_off = 0; /* Quota is now unattached */
  432. out_buf:
  433. kfree(buf);
  434. return ret;
  435. }
  436. /* Remove reference to dquot from tree */
  437. static int remove_tree(struct qtree_mem_dqinfo *info, struct dquot *dquot,
  438. uint *blk, int depth)
  439. {
  440. char *buf = getdqbuf(info->dqi_usable_bs);
  441. int ret = 0;
  442. uint newblk;
  443. __le32 *ref = (__le32 *)buf;
  444. if (!buf)
  445. return -ENOMEM;
  446. ret = read_blk(info, *blk, buf);
  447. if (ret < 0) {
  448. quota_error(dquot->dq_sb, "Can't read quota data block %u",
  449. *blk);
  450. goto out_buf;
  451. }
  452. newblk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
  453. if (newblk < QT_TREEOFF || newblk >= info->dqi_blocks) {
  454. quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)",
  455. newblk, info->dqi_blocks);
  456. ret = -EUCLEAN;
  457. goto out_buf;
  458. }
  459. if (depth == info->dqi_qtree_depth - 1) {
  460. ret = free_dqentry(info, dquot, newblk);
  461. newblk = 0;
  462. } else {
  463. ret = remove_tree(info, dquot, &newblk, depth+1);
  464. }
  465. if (ret >= 0 && !newblk) {
  466. int i;
  467. ref[get_index(info, dquot->dq_id, depth)] = cpu_to_le32(0);
  468. /* Block got empty? */
  469. for (i = 0; i < (info->dqi_usable_bs >> 2) && !ref[i]; i++)
  470. ;
  471. /* Don't put the root block into the free block list */
  472. if (i == (info->dqi_usable_bs >> 2)
  473. && *blk != QT_TREEOFF) {
  474. put_free_dqblk(info, buf, *blk);
  475. *blk = 0;
  476. } else {
  477. ret = write_blk(info, *blk, buf);
  478. if (ret < 0)
  479. quota_error(dquot->dq_sb,
  480. "Can't write quota tree block %u",
  481. *blk);
  482. }
  483. }
  484. out_buf:
  485. kfree(buf);
  486. return ret;
  487. }
  488. /* Delete dquot from tree */
  489. int qtree_delete_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
  490. {
  491. uint tmp = QT_TREEOFF;
  492. if (!dquot->dq_off) /* Even not allocated? */
  493. return 0;
  494. return remove_tree(info, dquot, &tmp, 0);
  495. }
  496. EXPORT_SYMBOL(qtree_delete_dquot);
  497. /* Find entry in block */
  498. static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
  499. struct dquot *dquot, uint blk)
  500. {
  501. char *buf = getdqbuf(info->dqi_usable_bs);
  502. loff_t ret = 0;
  503. int i;
  504. char *ddquot;
  505. if (!buf)
  506. return -ENOMEM;
  507. ret = read_blk(info, blk, buf);
  508. if (ret < 0) {
  509. quota_error(dquot->dq_sb, "Can't read quota tree "
  510. "block %u", blk);
  511. goto out_buf;
  512. }
  513. ddquot = buf + sizeof(struct qt_disk_dqdbheader);
  514. for (i = 0; i < qtree_dqstr_in_blk(info); i++) {
  515. if (info->dqi_ops->is_id(ddquot, dquot))
  516. break;
  517. ddquot += info->dqi_entry_size;
  518. }
  519. if (i == qtree_dqstr_in_blk(info)) {
  520. quota_error(dquot->dq_sb,
  521. "Quota for id %u referenced but not present",
  522. from_kqid(&init_user_ns, dquot->dq_id));
  523. ret = -EIO;
  524. goto out_buf;
  525. } else {
  526. ret = ((loff_t)blk << info->dqi_blocksize_bits) + sizeof(struct
  527. qt_disk_dqdbheader) + i * info->dqi_entry_size;
  528. }
  529. out_buf:
  530. kfree(buf);
  531. return ret;
  532. }
  533. /* Find entry for given id in the tree */
  534. static loff_t find_tree_dqentry(struct qtree_mem_dqinfo *info,
  535. struct dquot *dquot, uint blk, int depth)
  536. {
  537. char *buf = getdqbuf(info->dqi_usable_bs);
  538. loff_t ret = 0;
  539. __le32 *ref = (__le32 *)buf;
  540. if (!buf)
  541. return -ENOMEM;
  542. ret = read_blk(info, blk, buf);
  543. if (ret < 0) {
  544. quota_error(dquot->dq_sb, "Can't read quota tree block %u",
  545. blk);
  546. goto out_buf;
  547. }
  548. ret = 0;
  549. blk = le32_to_cpu(ref[get_index(info, dquot->dq_id, depth)]);
  550. if (!blk) /* No reference? */
  551. goto out_buf;
  552. if (blk < QT_TREEOFF || blk >= info->dqi_blocks) {
  553. quota_error(dquot->dq_sb, "Getting block too big (%u >= %u)",
  554. blk, info->dqi_blocks);
  555. ret = -EUCLEAN;
  556. goto out_buf;
  557. }
  558. if (depth < info->dqi_qtree_depth - 1)
  559. ret = find_tree_dqentry(info, dquot, blk, depth+1);
  560. else
  561. ret = find_block_dqentry(info, dquot, blk);
  562. out_buf:
  563. kfree(buf);
  564. return ret;
  565. }
  566. /* Find entry for given id in the tree - wrapper function */
  567. static inline loff_t find_dqentry(struct qtree_mem_dqinfo *info,
  568. struct dquot *dquot)
  569. {
  570. return find_tree_dqentry(info, dquot, QT_TREEOFF, 0);
  571. }
  572. int qtree_read_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
  573. {
  574. int type = dquot->dq_id.type;
  575. struct super_block *sb = dquot->dq_sb;
  576. loff_t offset;
  577. char *ddquot;
  578. int ret = 0;
  579. #ifdef __QUOTA_QT_PARANOIA
  580. /* Invalidated quota? */
  581. if (!sb_dqopt(dquot->dq_sb)->files[type]) {
  582. quota_error(sb, "Quota invalidated while reading!");
  583. return -EIO;
  584. }
  585. #endif
  586. /* Do we know offset of the dquot entry in the quota file? */
  587. if (!dquot->dq_off) {
  588. offset = find_dqentry(info, dquot);
  589. if (offset <= 0) { /* Entry not present? */
  590. if (offset < 0)
  591. quota_error(sb,"Can't read quota structure "
  592. "for id %u",
  593. from_kqid(&init_user_ns,
  594. dquot->dq_id));
  595. dquot->dq_off = 0;
  596. set_bit(DQ_FAKE_B, &dquot->dq_flags);
  597. memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
  598. ret = offset;
  599. goto out;
  600. }
  601. dquot->dq_off = offset;
  602. }
  603. ddquot = getdqbuf(info->dqi_entry_size);
  604. if (!ddquot)
  605. return -ENOMEM;
  606. ret = sb->s_op->quota_read(sb, type, ddquot, info->dqi_entry_size,
  607. dquot->dq_off);
  608. if (ret != info->dqi_entry_size) {
  609. if (ret >= 0)
  610. ret = -EIO;
  611. quota_error(sb, "Error while reading quota structure for id %u",
  612. from_kqid(&init_user_ns, dquot->dq_id));
  613. set_bit(DQ_FAKE_B, &dquot->dq_flags);
  614. memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
  615. kfree(ddquot);
  616. goto out;
  617. }
  618. spin_lock(&dquot->dq_dqb_lock);
  619. info->dqi_ops->disk2mem_dqblk(dquot, ddquot);
  620. if (!dquot->dq_dqb.dqb_bhardlimit &&
  621. !dquot->dq_dqb.dqb_bsoftlimit &&
  622. !dquot->dq_dqb.dqb_ihardlimit &&
  623. !dquot->dq_dqb.dqb_isoftlimit)
  624. set_bit(DQ_FAKE_B, &dquot->dq_flags);
  625. spin_unlock(&dquot->dq_dqb_lock);
  626. kfree(ddquot);
  627. out:
  628. dqstats_inc(DQST_READS);
  629. return ret;
  630. }
  631. EXPORT_SYMBOL(qtree_read_dquot);
  632. /* Check whether dquot should not be deleted. We know we are
  633. * the only one operating on dquot (thanks to dq_lock) */
  634. int qtree_release_dquot(struct qtree_mem_dqinfo *info, struct dquot *dquot)
  635. {
  636. if (test_bit(DQ_FAKE_B, &dquot->dq_flags) &&
  637. !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
  638. return qtree_delete_dquot(info, dquot);
  639. return 0;
  640. }
  641. EXPORT_SYMBOL(qtree_release_dquot);
  642. static int find_next_id(struct qtree_mem_dqinfo *info, qid_t *id,
  643. unsigned int blk, int depth)
  644. {
  645. char *buf = getdqbuf(info->dqi_usable_bs);
  646. __le32 *ref = (__le32 *)buf;
  647. ssize_t ret;
  648. unsigned int epb = info->dqi_usable_bs >> 2;
  649. unsigned int level_inc = 1;
  650. int i;
  651. if (!buf)
  652. return -ENOMEM;
  653. for (i = depth; i < info->dqi_qtree_depth - 1; i++)
  654. level_inc *= epb;
  655. ret = read_blk(info, blk, buf);
  656. if (ret < 0) {
  657. quota_error(info->dqi_sb,
  658. "Can't read quota tree block %u", blk);
  659. goto out_buf;
  660. }
  661. for (i = __get_index(info, *id, depth); i < epb; i++) {
  662. if (ref[i] == cpu_to_le32(0)) {
  663. *id += level_inc;
  664. continue;
  665. }
  666. if (depth == info->dqi_qtree_depth - 1) {
  667. ret = 0;
  668. goto out_buf;
  669. }
  670. ret = find_next_id(info, id, le32_to_cpu(ref[i]), depth + 1);
  671. if (ret != -ENOENT)
  672. break;
  673. }
  674. if (i == epb) {
  675. ret = -ENOENT;
  676. goto out_buf;
  677. }
  678. out_buf:
  679. kfree(buf);
  680. return ret;
  681. }
  682. int qtree_get_next_id(struct qtree_mem_dqinfo *info, struct kqid *qid)
  683. {
  684. qid_t id = from_kqid(&init_user_ns, *qid);
  685. int ret;
  686. ret = find_next_id(info, &id, QT_TREEOFF, 0);
  687. if (ret < 0)
  688. return ret;
  689. *qid = make_kqid(&init_user_ns, qid->type, id);
  690. return 0;
  691. }
  692. EXPORT_SYMBOL(qtree_get_next_id);