quota_tree.c 17 KB

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