aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrew Perepechko <andrew.perepechko@sun.com>2010-04-12 14:16:50 -0400
committerJan Kara <jack@suse.cz>2010-04-12 15:12:36 -0400
commit08261673cb6dc638c39f44d69b76fffb57b92a8b (patch)
tree752b396f409897a4357ca29bc2f9c3384d29e07d
parent4c5e6c0e70fd6ca2fa67184fd36a261b3b7b38d0 (diff)
quota: Fix possible dq_flags corruption
dq_flags are modified non-atomically in do_set_dqblk via __set_bit calls and atomically for example in mark_dquot_dirty or clear_dquot_dirty. Hence a change done by an atomic operation can be overwritten by a change done by a non-atomic one. Fix the problem by using atomic bitops even in do_set_dqblk. Signed-off-by: Andrew Perepechko <andrew.perepechko@sun.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/quota/dquot.c12
1 files changed, 6 insertions, 6 deletions
diff --git a/fs/quota/dquot.c b/fs/quota/dquot.c
index f9a37513f24c..a0a9405b202a 100644
--- a/fs/quota/dquot.c
+++ b/fs/quota/dquot.c
@@ -2328,34 +2328,34 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
2328 if (di->dqb_valid & QIF_SPACE) { 2328 if (di->dqb_valid & QIF_SPACE) {
2329 dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; 2329 dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace;
2330 check_blim = 1; 2330 check_blim = 1;
2331 __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); 2331 set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
2332 } 2332 }
2333 if (di->dqb_valid & QIF_BLIMITS) { 2333 if (di->dqb_valid & QIF_BLIMITS) {
2334 dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); 2334 dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
2335 dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); 2335 dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
2336 check_blim = 1; 2336 check_blim = 1;
2337 __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); 2337 set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
2338 } 2338 }
2339 if (di->dqb_valid & QIF_INODES) { 2339 if (di->dqb_valid & QIF_INODES) {
2340 dm->dqb_curinodes = di->dqb_curinodes; 2340 dm->dqb_curinodes = di->dqb_curinodes;
2341 check_ilim = 1; 2341 check_ilim = 1;
2342 __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); 2342 set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
2343 } 2343 }
2344 if (di->dqb_valid & QIF_ILIMITS) { 2344 if (di->dqb_valid & QIF_ILIMITS) {
2345 dm->dqb_isoftlimit = di->dqb_isoftlimit; 2345 dm->dqb_isoftlimit = di->dqb_isoftlimit;
2346 dm->dqb_ihardlimit = di->dqb_ihardlimit; 2346 dm->dqb_ihardlimit = di->dqb_ihardlimit;
2347 check_ilim = 1; 2347 check_ilim = 1;
2348 __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); 2348 set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
2349 } 2349 }
2350 if (di->dqb_valid & QIF_BTIME) { 2350 if (di->dqb_valid & QIF_BTIME) {
2351 dm->dqb_btime = di->dqb_btime; 2351 dm->dqb_btime = di->dqb_btime;
2352 check_blim = 1; 2352 check_blim = 1;
2353 __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); 2353 set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
2354 } 2354 }
2355 if (di->dqb_valid & QIF_ITIME) { 2355 if (di->dqb_valid & QIF_ITIME) {
2356 dm->dqb_itime = di->dqb_itime; 2356 dm->dqb_itime = di->dqb_itime;
2357 check_ilim = 1; 2357 check_ilim = 1;
2358 __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); 2358 set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
2359 } 2359 }
2360 2360
2361 if (check_blim) { 2361 if (check_blim) {