]>
Commit | Line | Data |
---|---|---|
6f934964 GKH |
1 | From 08261673cb6dc638c39f44d69b76fffb57b92a8b Mon Sep 17 00:00:00 2001 |
2 | From: Andrew Perepechko <andrew.perepechko@sun.com> | |
3 | Date: Mon, 12 Apr 2010 22:16:50 +0400 | |
4 | Subject: quota: Fix possible dq_flags corruption | |
5 | ||
6 | From: Andrew Perepechko <andrew.perepechko@sun.com> | |
7 | ||
8 | commit 08261673cb6dc638c39f44d69b76fffb57b92a8b upstream. | |
9 | ||
10 | dq_flags are modified non-atomically in do_set_dqblk via __set_bit calls and | |
11 | atomically for example in mark_dquot_dirty or clear_dquot_dirty. Hence a | |
12 | change done by an atomic operation can be overwritten by a change done by a | |
13 | non-atomic one. Fix the problem by using atomic bitops even in do_set_dqblk. | |
14 | ||
15 | Signed-off-by: Andrew Perepechko <andrew.perepechko@sun.com> | |
16 | Signed-off-by: Jan Kara <jack@suse.cz> | |
17 | Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> | |
18 | ||
19 | --- | |
20 | fs/quota/dquot.c | 12 ++++++------ | |
21 | 1 file changed, 6 insertions(+), 6 deletions(-) | |
22 | ||
23 | --- a/fs/quota/dquot.c | |
24 | +++ b/fs/quota/dquot.c | |
25 | @@ -2389,34 +2389,34 @@ static int do_set_dqblk(struct dquot *dq | |
26 | if (di->dqb_valid & QIF_SPACE) { | |
27 | dm->dqb_curspace = di->dqb_curspace - dm->dqb_rsvspace; | |
28 | check_blim = 1; | |
29 | - __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | |
30 | + set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | |
31 | } | |
32 | if (di->dqb_valid & QIF_BLIMITS) { | |
33 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); | |
34 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); | |
35 | check_blim = 1; | |
36 | - __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | |
37 | + set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | |
38 | } | |
39 | if (di->dqb_valid & QIF_INODES) { | |
40 | dm->dqb_curinodes = di->dqb_curinodes; | |
41 | check_ilim = 1; | |
42 | - __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | |
43 | + set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | |
44 | } | |
45 | if (di->dqb_valid & QIF_ILIMITS) { | |
46 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | |
47 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | |
48 | check_ilim = 1; | |
49 | - __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | |
50 | + set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | |
51 | } | |
52 | if (di->dqb_valid & QIF_BTIME) { | |
53 | dm->dqb_btime = di->dqb_btime; | |
54 | check_blim = 1; | |
55 | - __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | |
56 | + set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); | |
57 | } | |
58 | if (di->dqb_valid & QIF_ITIME) { | |
59 | dm->dqb_itime = di->dqb_itime; | |
60 | check_ilim = 1; | |
61 | - __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | |
62 | + set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | |
63 | } | |
64 | ||
65 | if (check_blim) { |