diff options
author | Jan Kara <jack@suse.cz> | 2010-05-13 12:05:15 -0400 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2010-05-21 13:30:48 -0400 |
commit | 741e128933448e589a85286e535078b24f4cf568 (patch) | |
tree | 40a069e5c7484673529f0747a9995cc7d2a85f00 /fs/ocfs2/quota_global.c | |
parent | 832d09cf1438bd172f69478bde74f20f05ec0115 (diff) |
ocfs2: Fix NULL pointer deref when writing local dquot
commit_dqblk() can write quota info to global file. That is actually a bad
thing to do because if we are just modifying local quota file, we are not
prepared (do not hold proper locks, do not have transaction credits) to do
a modification of the global quota file. So do not use commit_dqblk() and
instead call our writing function directly.
Acked-by: Joel Becker <Joel.Becker@oracle.com>
Signed-off-by: Jan Kara <jack@suse.cz>
Diffstat (limited to 'fs/ocfs2/quota_global.c')
-rw-r--r-- | fs/ocfs2/quota_global.c | 20 |
1 files changed, 10 insertions, 10 deletions
diff --git a/fs/ocfs2/quota_global.c b/fs/ocfs2/quota_global.c index 734995823740..2bb35fe00511 100644 --- a/fs/ocfs2/quota_global.c +++ b/fs/ocfs2/quota_global.c | |||
@@ -612,14 +612,13 @@ static int ocfs2_sync_dquot_helper(struct dquot *dquot, unsigned long type) | |||
612 | } | 612 | } |
613 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | 613 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); |
614 | status = ocfs2_sync_dquot(dquot); | 614 | status = ocfs2_sync_dquot(dquot); |
615 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | ||
616 | if (status < 0) | 615 | if (status < 0) |
617 | mlog_errno(status); | 616 | mlog_errno(status); |
618 | /* We have to write local structure as well... */ | 617 | /* We have to write local structure as well... */ |
619 | dquot_mark_dquot_dirty(dquot); | 618 | status = ocfs2_local_write_dquot(dquot); |
620 | status = dquot_commit(dquot); | ||
621 | if (status < 0) | 619 | if (status < 0) |
622 | mlog_errno(status); | 620 | mlog_errno(status); |
621 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | ||
623 | ocfs2_commit_trans(osb, handle); | 622 | ocfs2_commit_trans(osb, handle); |
624 | out_ilock: | 623 | out_ilock: |
625 | ocfs2_unlock_global_qf(oinfo, 1); | 624 | ocfs2_unlock_global_qf(oinfo, 1); |
@@ -658,7 +657,9 @@ static int ocfs2_write_dquot(struct dquot *dquot) | |||
658 | mlog_errno(status); | 657 | mlog_errno(status); |
659 | goto out; | 658 | goto out; |
660 | } | 659 | } |
661 | status = dquot_commit(dquot); | 660 | mutex_lock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); |
661 | status = ocfs2_local_write_dquot(dquot); | ||
662 | mutex_unlock(&sb_dqopt(dquot->dq_sb)->dqio_mutex); | ||
662 | ocfs2_commit_trans(osb, handle); | 663 | ocfs2_commit_trans(osb, handle); |
663 | out: | 664 | out: |
664 | mlog_exit(status); | 665 | mlog_exit(status); |
@@ -831,7 +832,6 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
831 | struct ocfs2_super *osb = OCFS2_SB(sb); | 832 | struct ocfs2_super *osb = OCFS2_SB(sb); |
832 | 833 | ||
833 | mlog_entry("id=%u, type=%d", dquot->dq_id, type); | 834 | mlog_entry("id=%u, type=%d", dquot->dq_id, type); |
834 | dquot_mark_dquot_dirty(dquot); | ||
835 | 835 | ||
836 | /* In case user set some limits, sync dquot immediately to global | 836 | /* In case user set some limits, sync dquot immediately to global |
837 | * quota file so that information propagates quicker */ | 837 | * quota file so that information propagates quicker */ |
@@ -856,14 +856,14 @@ static int ocfs2_mark_dquot_dirty(struct dquot *dquot) | |||
856 | } | 856 | } |
857 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); | 857 | mutex_lock(&sb_dqopt(sb)->dqio_mutex); |
858 | status = ocfs2_sync_dquot(dquot); | 858 | status = ocfs2_sync_dquot(dquot); |
859 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | ||
860 | if (status < 0) { | 859 | if (status < 0) { |
861 | mlog_errno(status); | 860 | mlog_errno(status); |
862 | goto out_trans; | 861 | goto out_dlock; |
863 | } | 862 | } |
864 | /* Now write updated local dquot structure */ | 863 | /* Now write updated local dquot structure */ |
865 | status = dquot_commit(dquot); | 864 | status = ocfs2_local_write_dquot(dquot); |
866 | out_trans: | 865 | out_dlock: |
866 | mutex_unlock(&sb_dqopt(sb)->dqio_mutex); | ||
867 | ocfs2_commit_trans(osb, handle); | 867 | ocfs2_commit_trans(osb, handle); |
868 | out_ilock: | 868 | out_ilock: |
869 | ocfs2_unlock_global_qf(oinfo, 1); | 869 | ocfs2_unlock_global_qf(oinfo, 1); |
@@ -915,7 +915,7 @@ static void ocfs2_destroy_dquot(struct dquot *dquot) | |||
915 | } | 915 | } |
916 | 916 | ||
917 | const struct dquot_operations ocfs2_quota_operations = { | 917 | const struct dquot_operations ocfs2_quota_operations = { |
918 | .write_dquot = ocfs2_write_dquot, | 918 | /* We never make dquot dirty so .write_dquot is never called */ |
919 | .acquire_dquot = ocfs2_acquire_dquot, | 919 | .acquire_dquot = ocfs2_acquire_dquot, |
920 | .release_dquot = ocfs2_release_dquot, | 920 | .release_dquot = ocfs2_release_dquot, |
921 | .mark_dirty = ocfs2_mark_dquot_dirty, | 921 | .mark_dirty = ocfs2_mark_dquot_dirty, |