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