quota_v2.c 20 KB

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