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