]> git.hungrycats.org Git - linux/commitdiff
[PATCH] quota: fix writing of quota info
authorAndrew Morton <akpm@osdl.org>
Thu, 3 Jun 2004 01:03:41 +0000 (18:03 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Thu, 3 Jun 2004 01:03:41 +0000 (18:03 -0700)
From: Jan Kara <jack@ucw.cz>

Fixes a problem with some quota operations not writing the quota info they
changed which could later cause that some transaction to use more buffers
than it had reserved or it could cause corrupted quota files when the
system was rebooted at the right time.

Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
fs/dquot.c

index df4280050e6989ccbc6baf5663d90a40b09e24a4..70280bc2fd4f09a975822f96da464861496efc52 100644 (file)
@@ -306,7 +306,7 @@ EXPORT_SYMBOL(mark_info_dirty);
 
 int dquot_acquire(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dquot->dq_lock);
@@ -319,8 +319,15 @@ int dquot_acquire(struct dquot *dquot)
        /* Instantiate dquot if needed */
        if (!test_bit(DQ_ACTIVE_B, &dquot->dq_flags) && !dquot->dq_off) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+               /* Write the info if needed */
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
                if (ret < 0)
                        goto out_iolock;
+               if (ret2 < 0) {
+                       ret = ret2;
+                       goto out_iolock;
+               }
        }
        set_bit(DQ_ACTIVE_B, &dquot->dq_flags);
 out_iolock:
@@ -334,7 +341,7 @@ out_iolock:
  */
 int dquot_commit(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dqopt->dqio_sem);
@@ -346,12 +353,15 @@ int dquot_commit(struct dquot *dquot)
        spin_unlock(&dq_list_lock);
        /* Inactive dquot can be only if there was error during read/init
         * => we have better not writing it */
-       if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags))
+       if (test_bit(DQ_ACTIVE_B, &dquot->dq_flags)) {
                ret = dqopt->ops[dquot->dq_type]->commit_dqblk(dquot);
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (ret >= 0)
+                       ret = ret2;
+       }
 out_sem:
        up(&dqopt->dqio_sem);
-       if (info_dirty(&dqopt->info[dquot->dq_type]))
-               dquot->dq_sb->dq_op->write_info(dquot->dq_sb, dquot->dq_type);
        return ret;
 }
 
@@ -360,7 +370,7 @@ out_sem:
  */
 int dquot_release(struct dquot *dquot)
 {
-       int ret = 0;
+       int ret = 0, ret2 = 0;
        struct quota_info *dqopt = sb_dqopt(dquot->dq_sb);
 
        down(&dquot->dq_lock);
@@ -368,8 +378,14 @@ int dquot_release(struct dquot *dquot)
        if (atomic_read(&dquot->dq_count) > 1)
                goto out_dqlock;
        down(&dqopt->dqio_sem);
-       if (dqopt->ops[dquot->dq_type]->release_dqblk)
+       if (dqopt->ops[dquot->dq_type]->release_dqblk) {
                ret = dqopt->ops[dquot->dq_type]->release_dqblk(dquot);
+               /* Write the info */
+               if (info_dirty(&dqopt->info[dquot->dq_type]))
+                       ret2 = dqopt->ops[dquot->dq_type]->write_file_info(dquot->dq_sb, dquot->dq_type);
+               if (ret >= 0)
+                       ret = ret2;
+       }
        clear_bit(DQ_ACTIVE_B, &dquot->dq_flags);
        up(&dqopt->dqio_sem);
 out_dqlock: