diff options
author | Jan Kara <jack@suse.cz> | 2008-10-02 10:48:10 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2009-01-05 11:40:22 -0500 |
commit | 4d59bce4f9eaf26d6d9046b56a2f1c0c7f20981d (patch) | |
tree | 8acb07cd2bf0ab360e6397dfa816feb009fc49af | |
parent | db49d2df489f727096438706a5428115e84a3f0d (diff) |
quota: Keep which entries were set by SETQUOTA quotactl
Quota in a clustered environment needs to synchronize quota information
among cluster nodes. This means we have to occasionally update some
information in dquot from disk / network. On the other hand we have to
be careful not to overwrite changes administrator did via SETQUOTA.
So indicate in dquot->dq_flags which entries have been set by SETQUOTA
and quota format can clear these flags when it properly propagated
the changes.
Signed-off-by: Jan Kara <jack@suse.cz>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r-- | fs/dquot.c | 12 | ||||
-rw-r--r-- | include/linux/quota.h | 26 |
2 files changed, 30 insertions, 8 deletions
diff --git a/fs/dquot.c b/fs/dquot.c index 9c78ffe1aad2..89226726daa8 100644 --- a/fs/dquot.c +++ b/fs/dquot.c | |||
@@ -2010,25 +2010,33 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di) | |||
2010 | if (di->dqb_valid & QIF_SPACE) { | 2010 | if (di->dqb_valid & QIF_SPACE) { |
2011 | dm->dqb_curspace = di->dqb_curspace; | 2011 | dm->dqb_curspace = di->dqb_curspace; |
2012 | check_blim = 1; | 2012 | check_blim = 1; |
2013 | __set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags); | ||
2013 | } | 2014 | } |
2014 | if (di->dqb_valid & QIF_BLIMITS) { | 2015 | if (di->dqb_valid & QIF_BLIMITS) { |
2015 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); | 2016 | dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit); |
2016 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); | 2017 | dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit); |
2017 | check_blim = 1; | 2018 | check_blim = 1; |
2019 | __set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags); | ||
2018 | } | 2020 | } |
2019 | if (di->dqb_valid & QIF_INODES) { | 2021 | if (di->dqb_valid & QIF_INODES) { |
2020 | dm->dqb_curinodes = di->dqb_curinodes; | 2022 | dm->dqb_curinodes = di->dqb_curinodes; |
2021 | check_ilim = 1; | 2023 | check_ilim = 1; |
2024 | __set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags); | ||
2022 | } | 2025 | } |
2023 | if (di->dqb_valid & QIF_ILIMITS) { | 2026 | if (di->dqb_valid & QIF_ILIMITS) { |
2024 | dm->dqb_isoftlimit = di->dqb_isoftlimit; | 2027 | dm->dqb_isoftlimit = di->dqb_isoftlimit; |
2025 | dm->dqb_ihardlimit = di->dqb_ihardlimit; | 2028 | dm->dqb_ihardlimit = di->dqb_ihardlimit; |
2026 | check_ilim = 1; | 2029 | check_ilim = 1; |
2030 | __set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags); | ||
2027 | } | 2031 | } |
2028 | if (di->dqb_valid & QIF_BTIME) | 2032 | if (di->dqb_valid & QIF_BTIME) { |
2029 | dm->dqb_btime = di->dqb_btime; | 2033 | dm->dqb_btime = di->dqb_btime; |
2030 | if (di->dqb_valid & QIF_ITIME) | 2034 | __set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags); |
2035 | } | ||
2036 | if (di->dqb_valid & QIF_ITIME) { | ||
2031 | dm->dqb_itime = di->dqb_itime; | 2037 | dm->dqb_itime = di->dqb_itime; |
2038 | __set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags); | ||
2039 | } | ||
2032 | 2040 | ||
2033 | if (check_blim) { | 2041 | if (check_blim) { |
2034 | if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { | 2042 | if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) { |
diff --git a/include/linux/quota.h b/include/linux/quota.h index 75bf761caef2..6d98885c16da 100644 --- a/include/linux/quota.h +++ b/include/linux/quota.h | |||
@@ -80,12 +80,21 @@ | |||
80 | * Quota structure used for communication with userspace via quotactl | 80 | * Quota structure used for communication with userspace via quotactl |
81 | * Following flags are used to specify which fields are valid | 81 | * Following flags are used to specify which fields are valid |
82 | */ | 82 | */ |
83 | #define QIF_BLIMITS 1 | 83 | enum { |
84 | #define QIF_SPACE 2 | 84 | QIF_BLIMITS_B = 0, |
85 | #define QIF_ILIMITS 4 | 85 | QIF_SPACE_B, |
86 | #define QIF_INODES 8 | 86 | QIF_ILIMITS_B, |
87 | #define QIF_BTIME 16 | 87 | QIF_INODES_B, |
88 | #define QIF_ITIME 32 | 88 | QIF_BTIME_B, |
89 | QIF_ITIME_B, | ||
90 | }; | ||
91 | |||
92 | #define QIF_BLIMITS (1 << QIF_BLIMITS_B) | ||
93 | #define QIF_SPACE (1 << QIF_SPACE_B) | ||
94 | #define QIF_ILIMITS (1 << QIF_ILIMITS_B) | ||
95 | #define QIF_INODES (1 << QIF_INODES_B) | ||
96 | #define QIF_BTIME (1 << QIF_BTIME_B) | ||
97 | #define QIF_ITIME (1 << QIF_ITIME_B) | ||
89 | #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) | 98 | #define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS) |
90 | #define QIF_USAGE (QIF_SPACE | QIF_INODES) | 99 | #define QIF_USAGE (QIF_SPACE | QIF_INODES) |
91 | #define QIF_TIMES (QIF_BTIME | QIF_ITIME) | 100 | #define QIF_TIMES (QIF_BTIME | QIF_ITIME) |
@@ -242,6 +251,11 @@ extern struct dqstats dqstats; | |||
242 | #define DQ_FAKE_B 3 /* no limits only usage */ | 251 | #define DQ_FAKE_B 3 /* no limits only usage */ |
243 | #define DQ_READ_B 4 /* dquot was read into memory */ | 252 | #define DQ_READ_B 4 /* dquot was read into memory */ |
244 | #define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */ | 253 | #define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */ |
254 | #define DQ_LASTSET_B 6 /* Following 6 bits (see QIF_) are reserved\ | ||
255 | * for the mask of entries set via SETQUOTA\ | ||
256 | * quotactl. They are set under dq_data_lock\ | ||
257 | * and the quota format handling dquot can\ | ||
258 | * clear them when it sees fit. */ | ||
245 | 259 | ||
246 | struct dquot { | 260 | struct dquot { |
247 | struct hlist_node dq_hash; /* Hash list in memory */ | 261 | struct hlist_node dq_hash; /* Hash list in memory */ |