Commit bd9e2585 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] quota: fix writing of quota info

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: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 56b32457
......@@ -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 @@ int dquot_acquire(struct dquot *dquot)
*/
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 @@ int dquot_commit(struct dquot *dquot)
*/
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:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment