X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=fs%2Fquota_v2.c;h=e12ca82cee113051ddc8cfc80b2bfa0c0a678515;hb=c7b5ebbddf7bcd3651947760f423e3783bbe6573;hp=e5098413a1b43e917a90cf5505854b8b5adfd80b;hpb=5273a3df6485dc2ad6aa7ddd441b9a21970f003b;p=linux-2.6.git diff --git a/fs/quota_v2.c b/fs/quota_v2.c index e5098413a..e12ca82ce 100644 --- a/fs/quota_v2.c +++ b/fs/quota_v2.c @@ -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 &&