vserver 1.9.3
[linux-2.6.git] / fs / quota_v2.c
index e509841..e12ca82 100644 (file)
@@ -135,7 +135,7 @@ static void mem2diskdqb(struct v2_disk_dqblk *d, struct mem_dqblk *m, qid_t id)
 
 static dqbuf_t getdqbuf(void)
 {
-       dqbuf_t buf = kmalloc(V2_DQBLKSIZE, GFP_KERNEL);
+       dqbuf_t buf = kmalloc(V2_DQBLKSIZE, GFP_NOFS);
        if (!buf)
                printk(KERN_WARNING "VFS: Not enough memory for quota buffers.\n");
        return buf;
@@ -357,7 +357,7 @@ static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
        struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
        dqbuf_t buf;
        int ret = 0, newson = 0, newact = 0;
-       u32 *ref;
+       __le32 *ref;
        uint newblk;
 
        if (!(buf = getdqbuf()))
@@ -376,14 +376,14 @@ static int do_insert_tree(struct dquot *dquot, uint *treeblk, int depth)
                        goto out_buf;
                }
        }
-       ref = (u32 *)buf;
+       ref = (__le32 *)buf;
        newblk = le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]);
        if (!newblk)
                newson = 1;
        if (depth == V2_DQTREEDEPTH-1) {
 #ifdef __QUOTA_V2_PARANOIA
                if (newblk) {
-                       printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", ref[GETIDINDEX(dquot->dq_id, depth)]);
+                       printk(KERN_ERR "VFS: Inserting already present quota entry (block %u).\n", le32_to_cpu(ref[GETIDINDEX(dquot->dq_id, depth)]));
                        ret = -EIO;
                        goto out_buf;
                }
@@ -420,7 +420,7 @@ static int v2_write_dquot(struct dquot *dquot)
        mm_segment_t fs;
        loff_t offset;
        ssize_t ret;
-       struct v2_disk_dqblk ddquot;
+       struct v2_disk_dqblk ddquot, empty;
 
        /* dq_off is guarded by dqio_sem */
        if (!dquot->dq_off)
@@ -432,6 +432,12 @@ static int v2_write_dquot(struct dquot *dquot)
        offset = dquot->dq_off;
        spin_lock(&dq_data_lock);
        mem2diskdqb(&ddquot, &dquot->dq_dqb, dquot->dq_id);
+       /* Argh... We may need to write structure full of zeroes but that would be
+        * treated as an empty place by the rest of the code. Format change would
+        * be definitely cleaner but the problems probably are not worth it */
+       memset(&empty, 0, sizeof(struct v2_disk_dqblk));
+       if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
+               ddquot.dqb_itime = cpu_to_le64(1);
        spin_unlock(&dq_data_lock);
        fs = get_fs();
        set_fs(KERNEL_DS);
@@ -504,7 +510,7 @@ static int remove_tree(struct dquot *dquot, uint *blk, int depth)
        dqbuf_t buf = getdqbuf();
        int ret = 0;
        uint newblk;
-       u32 *ref = (u32 *)buf;
+       __le32 *ref = (__le32 *)buf;
        
        if (!buf)
                return -ENOMEM;
@@ -589,7 +595,7 @@ static loff_t find_tree_dqentry(struct dquot *dquot, uint blk, int depth)
        struct file *filp = sb_dqopt(dquot->dq_sb)->files[dquot->dq_type];
        dqbuf_t buf = getdqbuf();
        loff_t ret = 0;
-       u32 *ref = (u32 *)buf;
+       __le32 *ref = (__le32 *)buf;
 
        if (!buf)
                return -ENOMEM;
@@ -622,7 +628,7 @@ static int v2_read_dquot(struct dquot *dquot)
        struct file *filp;
        mm_segment_t fs;
        loff_t offset;
-       struct v2_disk_dqblk ddquot;
+       struct v2_disk_dqblk ddquot, empty;
        int ret = 0;
 
        filp = sb_dqopt(dquot->dq_sb)->files[type];
@@ -652,8 +658,14 @@ static int v2_read_dquot(struct dquot *dquot)
                        printk(KERN_ERR "VFS: Error while reading quota structure for id %u.\n", dquot->dq_id);
                        memset(&ddquot, 0, sizeof(struct v2_disk_dqblk));
                }
-               else
+               else {
                        ret = 0;
+                       /* We need to escape back all-zero structure */
+                       memset(&empty, 0, sizeof(struct v2_disk_dqblk));
+                       empty.dqb_itime = cpu_to_le64(1);
+                       if (!memcmp(&empty, &ddquot, sizeof(struct v2_disk_dqblk)))
+                               ddquot.dqb_itime = 0;
+               }
                set_fs(fs);
                disk2memdqb(&dquot->dq_dqb, &ddquot);
                if (!dquot->dq_dqb.dqb_bhardlimit &&