quota_v2.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694
  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/quotaio_v2.h>
  9. #include <linux/kernel.h>
  10. #include <linux/init.h>
  11. #include <linux/module.h>
  12. #include <linux/slab.h>
  13. #include <asm/byteorder.h>
  14. MODULE_AUTHOR("Jan Kara");
  15. MODULE_DESCRIPTION("Quota format v2 support");
  16. MODULE_LICENSE("GPL");
  17. #define __QUOTA_V2_PARANOIA
  18. typedef char *dqbuf_t;
  19. #define GETIDINDEX(id, depth) (((id) >> ((V2_DQTREEDEPTH-(depth)-1)*8)) & 0xff)
  20. #define GETENTRIES(buf) ((struct v2_disk_dqblk *)(((char *)buf)+sizeof(struct v2_disk_dqdbheader)))
  21. /* Check whether given file is really vfsv0 quotafile */
  22. static int v2_check_quota_file(struct super_block *sb, int type)
  23. {
  24. struct v2_disk_dqheader dqhead;
  25. ssize_t size;
  26. static const uint quota_magics[] = V2_INITQMAGICS;
  27. static const uint quota_versions[] = V2_INITQVERSIONS;
  28. size = sb->s_op->quota_read(sb, type, (char *)&dqhead, sizeof(struct v2_disk_dqheader), 0);
  29. if (size != sizeof(struct v2_disk_dqheader)) {
  30. printk("failed read\n");
  31. return 0;
  32. }
  33. if (le32_to_cpu(dqhead.dqh_magic) != quota_magics[type] ||
  34. le32_to_cpu(dqhead.dqh_version) != quota_versions[type])
  35. return 0;
  36. return 1;
  37. }
  38. /* Read information header from quota file */
  39. static int v2_read_file_info(struct super_block *sb, int type)
  40. {
  41. struct v2_disk_dqinfo dinfo;
  42. struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
  43. ssize_t size;
  44. size = sb->s_op->quota_read(sb, type, (char *)&dinfo,
  45. sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
  46. if (size != sizeof(struct v2_disk_dqinfo)) {
  47. printk(KERN_WARNING "Can't read info structure on device %s.\n",
  48. sb->s_id);
  49. return -1;
  50. }
  51. info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
  52. info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);
  53. info->dqi_flags = le32_to_cpu(dinfo.dqi_flags);
  54. info->u.v2_i.dqi_blocks = le32_to_cpu(dinfo.dqi_blocks);
  55. info->u.v2_i.dqi_free_blk = le32_to_cpu(dinfo.dqi_free_blk);
  56. info->u.v2_i.dqi_free_entry = le32_to_cpu(dinfo.dqi_free_entry);
  57. return 0;
  58. }
  59. /* Write information header to quota file */
  60. static int v2_write_file_info(struct super_block *sb, int type)
  61. {
  62. struct v2_disk_dqinfo dinfo;
  63. struct mem_dqinfo *info = sb_dqopt(sb)->info+type;
  64. ssize_t size;
  65. spin_lock(&dq_data_lock);
  66. info->dqi_flags &= ~DQF_INFO_DIRTY;
  67. dinfo.dqi_bgrace = cpu_to_le32(info->dqi_bgrace);
  68. dinfo.dqi_igrace = cpu_to_le32(info->dqi_igrace);
  69. dinfo.dqi_flags = cpu_to_le32(info->dqi_flags & DQF_MASK);
  70. spin_unlock(&dq_data_lock);
  71. dinfo.dqi_blocks = cpu_to_le32(info->u.v2_i.dqi_blocks);
  72. dinfo.dqi_free_blk = cpu_to_le32(info->u.v2_i.dqi_free_blk);
  73. dinfo.dqi_free_entry = cpu_to_le32(info->u.v2_i.dqi_free_entry);
  74. size = sb->s_op->quota_write(sb, type, (char *)&dinfo,
  75. sizeof(struct v2_disk_dqinfo), V2_DQINFOOFF);
  76. if (size != sizeof(struct v2_disk_dqinfo)) {
  77. printk(KERN_WARNING "Can't write info structure on device %s.\n",
  78. sb->s_id);
  79. return -1;
  80. }
  81. return 0;
  82. }
  83. static void disk2memdqb(struct mem_dqblk *m, struct v2_disk_dqblk *d)
  84. {
  85. m->dqb_ihardlimit = le32_to_cpu(d->dqb_ihardlimit);
  86. m->dqb_isoftlimit = le32_to_cpu(d->dqb_isoftlimit);
  87. m->dqb_curinodes = le32_to_cpu(d->dqb_curinodes);
  88. m->dqb_itime = le64_to_cpu(d->dqb_itime);
  89. m->dqb_bhardlimit = le32_to_cpu(d->dqb_bhardlimit);
  90. m->dqb_bsoftlimit = le32_to_cpu(d->dqb_bsoftlimit);
  91. m->dqb_curspace = le64_to_cpu(d->dqb_curspace);
  92. m->dqb_btime = le64_to_cpu(d->dqb_btime);
  93. }
  94. static void mem2diskdqb(struct v2_disk_dqblk *d, struct mem_dqblk *m, qid_t id)
  95. {
  96. d->dqb_ihardlimit = cpu_to_le32(m->dqb_ihardlimit);
  97. d->dqb_isoftlimit = cpu_to_le32(m->dqb_isoftlimit);
  98. d->dqb_curinodes = cpu_to_le32(m->dqb_curinodes);
  99. d->dqb_itime = cpu_to_le64(m->dqb_itime);
  100. d->dqb_bhardlimit = cpu_to_le32(m->dqb_bhardlimit);
  101. d->dqb_bsoftlimit = cpu_to_le32(m->dqb_bsoftlimit);
  102. d->dqb_curspace = cpu_to_le64(m->dqb_curspace);
  103. d->dqb_btime = cpu_to_le64(m->dqb_btime);
  104. d->dqb_id = cpu_to_le32(id);
  105. }
  106. static dqbuf_t getdqbuf(void)
  107. {
  108. dqbuf_t buf = kmalloc(V2_DQBLKSIZE, GFP_NOFS);
  109. if (!buf)
  110. printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
  111. return buf;
  112. }
  113. static inline void freedqbuf(dqbuf_t buf)
  114. {
  115. kfree(buf);
  116. }
  117. static inline ssize_t read_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
  118. {
  119. memset(buf, 0, V2_DQBLKSIZE);
  120. return sb->s_op->quota_read(sb, type, (char *)buf,
  121. V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
  122. }
  123. static inline ssize_t write_blk(struct super_block *sb, int type, uint blk, dqbuf_t buf)
  124. {
  125. return sb->s_op->quota_write(sb, type, (char *)buf,
  126. V2_DQBLKSIZE, blk << V2_DQBLKSIZE_BITS);
  127. }
  128. /* Remove empty block from list and return it */
  129. static int get_free_dqblk(struct super_block *sb, int type)
  130. {
  131. dqbuf_t buf = getdqbuf();
  132. struct mem_dqinfo *info = sb_dqinfo(sb, type);
  133. struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
  134. int ret, blk;
  135. if (!buf)
  136. return -ENOMEM;
  137. if (info->u.v2_i.dqi_free_blk) {
  138. blk = info->u.v2_i.dqi_free_blk;
  139. if ((ret = read_blk(sb, type, blk, buf)) < 0)
  140. goto out_buf;
  141. info->u.v2_i.dqi_free_blk = le32_to_cpu(dh->dqdh_next_free);
  142. }
  143. else {
  144. memset(buf, 0, V2_DQBLKSIZE);
  145. /* Assure block allocation... */
  146. if ((ret = write_blk(sb, type, info->u.v2_i.dqi_blocks, buf)) < 0)
  147. goto out_buf;
  148. blk = info->u.v2_i.dqi_blocks++;
  149. }
  150. mark_info_dirty(sb, type);
  151. ret = blk;
  152. out_buf:
  153. freedqbuf(buf);
  154. return ret;
  155. }
  156. /* Insert empty block to the list */
  157. static int put_free_dqblk(struct super_block *sb, int type, dqbuf_t buf, uint blk)
  158. {
  159. struct mem_dqinfo *info = sb_dqinfo(sb, type);
  160. struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
  161. int err;
  162. dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_blk);
  163. dh->dqdh_prev_free = cpu_to_le32(0);
  164. dh->dqdh_entries = cpu_to_le16(0);
  165. info->u.v2_i.dqi_free_blk = blk;
  166. mark_info_dirty(sb, type);
  167. /* Some strange block. We had better leave it... */
  168. if ((err = write_blk(sb, type, blk, buf)) < 0)
  169. return err;
  170. return 0;
  171. }
  172. /* Remove given block from the list of blocks with free entries */
  173. static int remove_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
  174. {
  175. dqbuf_t tmpbuf = getdqbuf();
  176. struct mem_dqinfo *info = sb_dqinfo(sb, type);
  177. struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
  178. uint nextblk = le32_to_cpu(dh->dqdh_next_free), prevblk = le32_to_cpu(dh->dqdh_prev_free);
  179. int err;
  180. if (!tmpbuf)
  181. return -ENOMEM;
  182. if (nextblk) {
  183. if ((err = read_blk(sb, type, nextblk, tmpbuf)) < 0)
  184. goto out_buf;
  185. ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = dh->dqdh_prev_free;
  186. if ((err = write_blk(sb, type, nextblk, tmpbuf)) < 0)
  187. goto out_buf;
  188. }
  189. if (prevblk) {
  190. if ((err = read_blk(sb, type, prevblk, tmpbuf)) < 0)
  191. goto out_buf;
  192. ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_next_free = dh->dqdh_next_free;
  193. if ((err = write_blk(sb, type, prevblk, tmpbuf)) < 0)
  194. goto out_buf;
  195. }
  196. else {
  197. info->u.v2_i.dqi_free_entry = nextblk;
  198. mark_info_dirty(sb, type);
  199. }
  200. freedqbuf(tmpbuf);
  201. dh->dqdh_next_free = dh->dqdh_prev_free = cpu_to_le32(0);
  202. /* No matter whether write succeeds block is out of list */
  203. if (write_blk(sb, type, blk, buf) < 0)
  204. printk(KERN_ERR "VFS: Can't write block (%u) with free entries.\n", blk);
  205. return 0;
  206. out_buf:
  207. freedqbuf(tmpbuf);
  208. return err;
  209. }
  210. /* Insert given block to the beginning of list with free entries */
  211. static int insert_free_dqentry(struct super_block *sb, int type, dqbuf_t buf, uint blk)
  212. {
  213. dqbuf_t tmpbuf = getdqbuf();
  214. struct mem_dqinfo *info = sb_dqinfo(sb, type);
  215. struct v2_disk_dqdbheader *dh = (struct v2_disk_dqdbheader *)buf;
  216. int err;
  217. if (!tmpbuf)
  218. return -ENOMEM;
  219. dh->dqdh_next_free = cpu_to_le32(info->u.v2_i.dqi_free_entry);
  220. dh->dqdh_prev_free = cpu_to_le32(0);
  221. if ((err = write_blk(sb, type, blk, buf)) < 0)
  222. goto out_buf;
  223. if (info->u.v2_i.dqi_free_entry) {
  224. if ((err = read_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
  225. goto out_buf;
  226. ((struct v2_disk_dqdbheader *)tmpbuf)->dqdh_prev_free = cpu_to_le32(blk);
  227. if ((err = write_blk(sb, type, info->u.v2_i.dqi_free_entry, tmpbuf)) < 0)
  228. goto out_buf;
  229. }
  230. freedqbuf(tmpbuf);
  231. info->u.v2_i.dqi_free_entry = blk;
  232. mark_info_dirty(sb, type);
  233. return 0;
  234. out_buf:
  235. freedqbuf(tmpbuf);
  236. return err;
  237. }
  238. /* Find space for dquot */
  239. static uint find_free_dqentry(struct dquot *dquot, int *err)
  240. {
  241. struct super_block *sb = dquot->dq_sb;
  242. struct mem_dqinfo *info = sb_dqopt(sb)->info+dquot->dq_type;
  243. uint blk, i;
  244. struct v2_disk_dqdbheader *dh;
  245. struct v2_disk_dqblk *ddquot;
  246. struct v2_disk_dqblk fakedquot;
  247. dqbuf_t buf;
  248. *err = 0;
  249. if (!(buf = getdqbuf())) {
  250. *err = -ENOMEM;
  251. return 0;
  252. }
  253. dh = (struct v2_disk_dqdbheader *)buf;
  254. ddquot = GETENTRIES(buf);
  255. if (info->u.v2_i.dqi_free_entry) {
  256. blk = info->u.v2_i.dqi_free_entry;
  257. if ((*err = read_blk(sb, dquot->dq_type, blk, buf)) < 0)
  258. goto out_buf;
  259. }
  260. else {
  261. blk = get_free_dqblk(sb, dquot->dq_type);
  262. if ((int)blk < 0) {
  263. *err = blk;
  264. freedqbuf(buf);
  265. return 0;
  266. }
  267. memset(buf, 0, V2_DQBLKSIZE);
  268. /* This is enough as block is already zeroed and entry list is empty... */
  269. info->u.v2_i.dqi_free_entry = blk;
  270. mark_info_dirty(sb, dquot->dq_type);
  271. }
  272. if (le16_to_cpu(dh->dqdh_entries)+1 >= V2_DQSTRINBLK) /* Block will be full? */
  273. if ((*err = remove_free_dqentry(sb, dquot->dq_type, buf, blk)) < 0) {
  274. printk(KERN_ERR "VFS: find_free_dqentry(): Can't remove block (%u) from entry free list.\n", blk);
  275. goto out_buf;
  276. }
  277. dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)+1);
  278. memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
  279. /* Find free structure in block */
  280. for (i = 0; i < V2_DQSTRINBLK && memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)); i++);
  281. #ifdef __QUOTA_V2_PARANOIA
  282. if (i == V2_DQSTRINBLK) {
  283. printk(KERN_ERR "VFS: find_free_dqentry(): Data block full but it shouldn't.\n");
  284. *err = -EIO;
  285. goto out_buf;
  286. }
  287. #endif
  288. if ((*err = write_blk(sb, dquot->dq_type, blk, buf)) < 0) {
  289. printk(KERN_ERR "VFS: find_free_dqentry(): Can't write quota data block %u.\n", blk);
  290. goto out_buf;
  291. }
  292. dquot->dq_off = (blk<<V2_DQBLKSIZE_BITS)+sizeof(struct v2_disk_dqdbheader)+i*sizeof(struct v2_disk_dqblk);
  293. freedqbuf(buf);
  294. return blk;
  295. out_buf:
  296. freedqbuf(buf);
  297. return 0;
  298. }
  299. /* Insert reference to structure into the trie */
  300. static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
  301. {
  302. struct super_block *sb = dquot->dq_sb;
  303. dqbuf_t buf;
  304. int ret = 0, newson = 0, newact = 0;
  305. __le32 *ref;
  306. uint newblk;
  307. if (!(buf = getdqbuf()))
  308. return -ENOMEM;
  309. if (!*treeblk) {
  310. ret = get_free_dqblk(sb, dquot->dq_type);
  311. if (ret < 0)
  312. goto out_buf;
  313. *treeblk = ret;
  314. memset(buf, 0, V2_DQBLKSIZE);
  315. newact = 1;
  316. }
  317. else {
  318. if ((ret = read_blk(sb, dquot->dq_type, *treeblk, buf)) < 0) {
  319. printk(KERN_ERR "VFS: Can't read tree quota block %u.\n", *treeblk);
  320. goto out_buf;
  321. }
  322. }
  323. ref = (__le32 *)buf;
  324. newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
  325. if (!newblk)
  326. newson = 1;
  327. if (depth == V2_DQTREEDEPTH-1) {
  328. #ifdef __QUOTA_V2_PARANOIA
  329. if (newblk) {
  330. printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]));
  331. ret = -EIO;
  332. goto out_buf;
  333. }
  334. #endif
  335. newblk = find_free_dqentry(dquot, &ret);
  336. }
  337. else
  338. ret = do_insert_tree(dquot, &newblk, depth+1);
  339. if (newson && ret >= 0) {
  340. ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(newblk);
  341. ret = write_blk(sb, dquot->dq_type, *treeblk, buf);
  342. }
  343. else if (newact && ret < 0)
  344. put_free_dqblk(sb, dquot->dq_type, buf, *treeblk);
  345. out_buf:
  346. freedqbuf(buf);
  347. return ret;
  348. }
  349. /* Wrapper for inserting quota structure into tree */
  350. static inline int dq_insert_tree(struct dquot *dquot)
  351. {
  352. int tmp = V2_DQTREEOFF;
  353. return do_insert_tree(dquot, &tmp, 0);
  354. }
  355. /*
  356. * We don't have to be afraid of deadlocks as we never have quotas on quota files...
  357. */
  358. static int v2_write_dquot(struct dquot *dquot)
  359. {
  360. int type = dquot->dq_type;
  361. ssize_t ret;
  362. struct v2_disk_dqblk ddquot, empty;
  363. /* dq_off is guarded by dqio_sem */
  364. if (!dquot->dq_off)
  365. if ((ret = dq_insert_tree(dquot)) < 0) {
  366. printk(KERN_ERR "VFS: Error %zd occurred while creating quota.\n", ret);
  367. return ret;
  368. }
  369. spin_lock(&dq_data_lock);
  370. mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
  371. /* Argh... We may need to write structure full of zeroes but that would be
  372. * treated as an empty place by the rest of the code. Format change would
  373. * be definitely cleaner but the problems probably are not worth it */
  374. memset(&empty, 0, sizeof(struct v2_disk_dqblk));
  375. if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
  376. ddquot.dqb_itime = cpu_to_le64(1);
  377. spin_unlock(&dq_data_lock);
  378. ret = dquot->dq_sb->s_op->quota_write(dquot->dq_sb, type,
  379. (char *)&ddquot, sizeof(struct v2_disk_dqblk), dquot->dq_off);
  380. if (ret != sizeof(struct v2_disk_dqblk)) {
  381. printk(KERN_WARNING "VFS: dquota write failed on dev %s\n", dquot->dq_sb->s_id);
  382. if (ret >= 0)
  383. ret = -ENOSPC;
  384. }
  385. else
  386. ret = 0;
  387. dqstats.writes++;
  388. return ret;
  389. }
  390. /* Free dquot entry in data block */
  391. static int free_dqentry(struct dquot *dquot, uint blk)
  392. {
  393. struct super_block *sb = dquot->dq_sb;
  394. int type = dquot->dq_type;
  395. struct v2_disk_dqdbheader *dh;
  396. dqbuf_t buf = getdqbuf();
  397. int ret = 0;
  398. if (!buf)
  399. return -ENOMEM;
  400. if (dquot->dq_off >> V2_DQBLKSIZE_BITS != blk) {
  401. printk(KERN_ERR "VFS: Quota structure has offset to other "
  402. "block (%u) than it should (%u).\n", blk,
  403. (uint)(dquot->dq_off >> V2_DQBLKSIZE_BITS));
  404. goto out_buf;
  405. }
  406. if ((ret = read_blk(sb, type, blk, buf)) < 0) {
  407. printk(KERN_ERR "VFS: Can't read quota data block %u\n", blk);
  408. goto out_buf;
  409. }
  410. dh = (struct v2_disk_dqdbheader *)buf;
  411. dh->dqdh_entries = cpu_to_le16(le16_to_cpu(dh->dqdh_entries)-1);
  412. if (!le16_to_cpu(dh->dqdh_entries)) { /* Block got free? */
  413. if ((ret = remove_free_dqentry(sb, type, buf, blk)) < 0 ||
  414. (ret = put_free_dqblk(sb, type, buf, blk)) < 0) {
  415. printk(KERN_ERR "VFS: Can't move quota data block (%u) "
  416. "to free list.\n", blk);
  417. goto out_buf;
  418. }
  419. }
  420. else {
  421. memset(buf+(dquot->dq_off & ((1 << V2_DQBLKSIZE_BITS)-1)), 0,
  422. sizeof(struct v2_disk_dqblk));
  423. if (le16_to_cpu(dh->dqdh_entries) == V2_DQSTRINBLK-1) {
  424. /* Insert will write block itself */
  425. if ((ret = insert_free_dqentry(sb, type, buf, blk)) < 0) {
  426. printk(KERN_ERR "VFS: Can't insert quota data block (%u) to free entry list.\n", blk);
  427. goto out_buf;
  428. }
  429. }
  430. else
  431. if ((ret = write_blk(sb, type, blk, buf)) < 0) {
  432. printk(KERN_ERR "VFS: Can't write quota data "
  433. "block %u\n", blk);
  434. goto out_buf;
  435. }
  436. }
  437. dquot->dq_off = 0; /* Quota is now unattached */
  438. out_buf:
  439. freedqbuf(buf);
  440. return ret;
  441. }
  442. /* Remove reference to dquot from tree */
  443. static int remove_tree(struct dquot *dquot, uint *blk, int depth)
  444. {
  445. struct super_block *sb = dquot->dq_sb;
  446. int type = dquot->dq_type;
  447. dqbuf_t buf = getdqbuf();
  448. int ret = 0;
  449. uint newblk;
  450. __le32 *ref = (__le32 *)buf;
  451. if (!buf)
  452. return -ENOMEM;
  453. if ((ret = read_blk(sb, type, *blk, buf)) < 0) {
  454. printk(KERN_ERR "VFS: Can't read quota data block %u\n", *blk);
  455. goto out_buf;
  456. }
  457. newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
  458. if (depth == V2_DQTREEDEPTH-1) {
  459. ret = free_dqentry(dquot, newblk);
  460. newblk = 0;
  461. }
  462. else
  463. ret = remove_tree(dquot, &newblk, depth+1);
  464. if (ret >= 0 && !newblk) {
  465. int i;
  466. ref[GETIDINDEX(dquot->dq_id, depth)] = cpu_to_le32(0);
  467. for (i = 0; i < V2_DQBLKSIZE && !buf[i]; i++); /* Block got empty? */
  468. /* Don't put the root block into the free block list */
  469. if (i == V2_DQBLKSIZE && *blk != V2_DQTREEOFF) {
  470. put_free_dqblk(sb, type, buf, *blk);
  471. *blk = 0;
  472. }
  473. else
  474. if ((ret = write_blk(sb, type, *blk, buf)) < 0)
  475. printk(KERN_ERR "VFS: Can't write quota tree "
  476. "block %u.\n", *blk);
  477. }
  478. out_buf:
  479. freedqbuf(buf);
  480. return ret;
  481. }
  482. /* Delete dquot from tree */
  483. static int v2_delete_dquot(struct dquot *dquot)
  484. {
  485. uint tmp = V2_DQTREEOFF;
  486. if (!dquot->dq_off) /* Even not allocated? */
  487. return 0;
  488. return remove_tree(dquot, &tmp, 0);
  489. }
  490. /* Find entry in block */
  491. static loff_t find_block_dqentry(struct dquot *dquot, uint blk)
  492. {
  493. dqbuf_t buf = getdqbuf();
  494. loff_t ret = 0;
  495. int i;
  496. struct v2_disk_dqblk *ddquot = GETENTRIES(buf);
  497. if (!buf)
  498. return -ENOMEM;
  499. if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
  500. printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
  501. goto out_buf;
  502. }
  503. if (dquot->dq_id)
  504. for (i = 0; i < V2_DQSTRINBLK &&
  505. le32_to_cpu(ddquot[i].dqb_id) != dquot->dq_id; i++);
  506. else { /* ID 0 as a bit more complicated searching... */
  507. struct v2_disk_dqblk fakedquot;
  508. memset(&fakedquot, 0, sizeof(struct v2_disk_dqblk));
  509. for (i = 0; i < V2_DQSTRINBLK; i++)
  510. if (!le32_to_cpu(ddquot[i].dqb_id) &&
  511. memcmp(&fakedquot, ddquot+i, sizeof(struct v2_disk_dqblk)))
  512. break;
  513. }
  514. if (i == V2_DQSTRINBLK) {
  515. printk(KERN_ERR "VFS: Quota for id %u referenced "
  516. "but not present.\n", dquot->dq_id);
  517. ret = -EIO;
  518. goto out_buf;
  519. }
  520. else
  521. ret = (blk << V2_DQBLKSIZE_BITS) + sizeof(struct
  522. v2_disk_dqdbheader) + i * sizeof(struct v2_disk_dqblk);
  523. out_buf:
  524. freedqbuf(buf);
  525. return ret;
  526. }
  527. /* Find entry for given id in the tree */
  528. static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
  529. {
  530. dqbuf_t buf = getdqbuf();
  531. loff_t ret = 0;
  532. __le32 *ref = (__le32 *)buf;
  533. if (!buf)
  534. return -ENOMEM;
  535. if ((ret = read_blk(dquot->dq_sb, dquot->dq_type, blk, buf)) < 0) {
  536. printk(KERN_ERR "VFS: Can't read quota tree block %u.\n", blk);
  537. goto out_buf;
  538. }
  539. ret = 0;
  540. blk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
  541. if (!blk) /* No reference? */
  542. goto out_buf;
  543. if (depth < V2_DQTREEDEPTH-1)
  544. ret = find_tree_dqentry(dquot, blk, depth+1);
  545. else
  546. ret = find_block_dqentry(dquot, blk);
  547. out_buf:
  548. freedqbuf(buf);
  549. return ret;
  550. }
  551. /* Find entry for given id in the tree - wrapper function */
  552. static inline loff_t find_dqentry(struct dquot *dquot)
  553. {
  554. return find_tree_dqentry(dquot, V2_DQTREEOFF, 0);
  555. }
  556. static int v2_read_dquot(struct dquot *dquot)
  557. {
  558. int type = dquot->dq_type;
  559. loff_t offset;
  560. struct v2_disk_dqblk ddquot, empty;
  561. int ret = 0;
  562. #ifdef __QUOTA_V2_PARANOIA
  563. /* Invalidated quota? */
  564. if (!dquot->dq_sb || !sb_dqopt(dquot->dq_sb)->files[type]) {
  565. printk(KERN_ERR "VFS: Quota invalidated while reading!\n");
  566. return -EIO;
  567. }
  568. #endif
  569. offset = find_dqentry(dquot);
  570. if (offset <= 0) { /* Entry not present? */
  571. if (offset < 0)
  572. printk(KERN_ERR "VFS: Can't read quota "
  573. "structure for id %u.\n", dquot->dq_id);
  574. dquot->dq_off = 0;
  575. set_bit(DQ_FAKE_B, &dquot->dq_flags);
  576. memset(&dquot->dq_dqb, 0, sizeof(struct mem_dqblk));
  577. ret = offset;
  578. }
  579. else {
  580. dquot->dq_off = offset;
  581. if ((ret = dquot->dq_sb->s_op->quota_read(dquot->dq_sb, type,
  582. (char *)&ddquot, sizeof(struct v2_disk_dqblk), offset))
  583. != sizeof(struct v2_disk_dqblk)) {
  584. if (ret >= 0)
  585. ret = -EIO;
  586. printk(KERN_ERR "VFS: Error while reading quota "
  587. "structure for id %u.\n", dquot->dq_id);
  588. memset(&ddquot, 0, sizeof(struct v2_disk_dqblk));
  589. }
  590. else {
  591. ret = 0;
  592. /* We need to escape back all-zero structure */
  593. memset(&empty, 0, sizeof(struct v2_disk_dqblk));
  594. empty.dqb_itime = cpu_to_le64(1);
  595. if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
  596. ddquot.dqb_itime = 0;
  597. }
  598. disk2memdqb(&dquot->dq_dqb, &ddquot);
  599. if (!dquot->dq_dqb.dqb_bhardlimit &&
  600. !dquot->dq_dqb.dqb_bsoftlimit &&
  601. !dquot->dq_dqb.dqb_ihardlimit &&
  602. !dquot->dq_dqb.dqb_isoftlimit)
  603. set_bit(DQ_FAKE_B, &dquot->dq_flags);
  604. }
  605. dqstats.reads++;
  606. return ret;
  607. }
  608. /* Check whether dquot should not be deleted. We know we are
  609. * the only one operating on dquot (thanks to dq_lock) */
  610. static int v2_release_dquot(struct dquot *dquot)
  611. {
  612. if (test_bit(DQ_FAKE_B, &dquot->dq_flags) && !(dquot->dq_dqb.dqb_curinodes | dquot->dq_dqb.dqb_curspace))
  613. return v2_delete_dquot(dquot);
  614. return 0;
  615. }
  616. static struct quota_format_ops v2_format_ops = {
  617. .check_quota_file = v2_check_quota_file,
  618. .read_file_info = v2_read_file_info,
  619. .write_file_info = v2_write_file_info,
  620. .free_file_info = NULL,
  621. .read_dqblk = v2_read_dquot,
  622. .commit_dqblk = v2_write_dquot,
  623. .release_dqblk = v2_release_dquot,
  624. };
  625. static struct quota_format_type v2_quota_format = {
  626. .qf_fmt_id = QFMT_VFS_V0,
  627. .qf_ops = &v2_format_ops,
  628. .qf_owner = THIS_MODULE
  629. };
  630. static int __init init_v2_quota_format(void)
  631. {
  632. return register_quota_format(&v2_quota_format);
  633. }
  634. static void __exit exit_v2_quota_format(void)
  635. {
  636. unregister_quota_format(&v2_quota_format);
  637. }
  638. module_init(init_v2_quota_format);
  639. module_exit(exit_v2_quota_format);