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>
This commit is contained in:
parent
db49d2df48
commit
4d59bce4f9
2 changed files with 30 additions and 8 deletions
12
fs/dquot.c
12
fs/dquot.c
|
@ -2010,25 +2010,33 @@ static int do_set_dqblk(struct dquot *dquot, struct if_dqblk *di)
|
||||||
if (di->dqb_valid & QIF_SPACE) {
|
if (di->dqb_valid & QIF_SPACE) {
|
||||||
dm->dqb_curspace = di->dqb_curspace;
|
dm->dqb_curspace = di->dqb_curspace;
|
||||||
check_blim = 1;
|
check_blim = 1;
|
||||||
|
__set_bit(DQ_LASTSET_B + QIF_SPACE_B, &dquot->dq_flags);
|
||||||
}
|
}
|
||||||
if (di->dqb_valid & QIF_BLIMITS) {
|
if (di->dqb_valid & QIF_BLIMITS) {
|
||||||
dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
|
dm->dqb_bsoftlimit = qbtos(di->dqb_bsoftlimit);
|
||||||
dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
|
dm->dqb_bhardlimit = qbtos(di->dqb_bhardlimit);
|
||||||
check_blim = 1;
|
check_blim = 1;
|
||||||
|
__set_bit(DQ_LASTSET_B + QIF_BLIMITS_B, &dquot->dq_flags);
|
||||||
}
|
}
|
||||||
if (di->dqb_valid & QIF_INODES) {
|
if (di->dqb_valid & QIF_INODES) {
|
||||||
dm->dqb_curinodes = di->dqb_curinodes;
|
dm->dqb_curinodes = di->dqb_curinodes;
|
||||||
check_ilim = 1;
|
check_ilim = 1;
|
||||||
|
__set_bit(DQ_LASTSET_B + QIF_INODES_B, &dquot->dq_flags);
|
||||||
}
|
}
|
||||||
if (di->dqb_valid & QIF_ILIMITS) {
|
if (di->dqb_valid & QIF_ILIMITS) {
|
||||||
dm->dqb_isoftlimit = di->dqb_isoftlimit;
|
dm->dqb_isoftlimit = di->dqb_isoftlimit;
|
||||||
dm->dqb_ihardlimit = di->dqb_ihardlimit;
|
dm->dqb_ihardlimit = di->dqb_ihardlimit;
|
||||||
check_ilim = 1;
|
check_ilim = 1;
|
||||||
|
__set_bit(DQ_LASTSET_B + QIF_ILIMITS_B, &dquot->dq_flags);
|
||||||
}
|
}
|
||||||
if (di->dqb_valid & QIF_BTIME)
|
if (di->dqb_valid & QIF_BTIME) {
|
||||||
dm->dqb_btime = di->dqb_btime;
|
dm->dqb_btime = di->dqb_btime;
|
||||||
if (di->dqb_valid & QIF_ITIME)
|
__set_bit(DQ_LASTSET_B + QIF_BTIME_B, &dquot->dq_flags);
|
||||||
|
}
|
||||||
|
if (di->dqb_valid & QIF_ITIME) {
|
||||||
dm->dqb_itime = di->dqb_itime;
|
dm->dqb_itime = di->dqb_itime;
|
||||||
|
__set_bit(DQ_LASTSET_B + QIF_ITIME_B, &dquot->dq_flags);
|
||||||
|
}
|
||||||
|
|
||||||
if (check_blim) {
|
if (check_blim) {
|
||||||
if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) {
|
if (!dm->dqb_bsoftlimit || dm->dqb_curspace < dm->dqb_bsoftlimit) {
|
||||||
|
|
|
@ -80,12 +80,21 @@
|
||||||
* Quota structure used for communication with userspace via quotactl
|
* Quota structure used for communication with userspace via quotactl
|
||||||
* Following flags are used to specify which fields are valid
|
* Following flags are used to specify which fields are valid
|
||||||
*/
|
*/
|
||||||
#define QIF_BLIMITS 1
|
enum {
|
||||||
#define QIF_SPACE 2
|
QIF_BLIMITS_B = 0,
|
||||||
#define QIF_ILIMITS 4
|
QIF_SPACE_B,
|
||||||
#define QIF_INODES 8
|
QIF_ILIMITS_B,
|
||||||
#define QIF_BTIME 16
|
QIF_INODES_B,
|
||||||
#define QIF_ITIME 32
|
QIF_BTIME_B,
|
||||||
|
QIF_ITIME_B,
|
||||||
|
};
|
||||||
|
|
||||||
|
#define QIF_BLIMITS (1 << QIF_BLIMITS_B)
|
||||||
|
#define QIF_SPACE (1 << QIF_SPACE_B)
|
||||||
|
#define QIF_ILIMITS (1 << QIF_ILIMITS_B)
|
||||||
|
#define QIF_INODES (1 << QIF_INODES_B)
|
||||||
|
#define QIF_BTIME (1 << QIF_BTIME_B)
|
||||||
|
#define QIF_ITIME (1 << QIF_ITIME_B)
|
||||||
#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
|
#define QIF_LIMITS (QIF_BLIMITS | QIF_ILIMITS)
|
||||||
#define QIF_USAGE (QIF_SPACE | QIF_INODES)
|
#define QIF_USAGE (QIF_SPACE | QIF_INODES)
|
||||||
#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
|
#define QIF_TIMES (QIF_BTIME | QIF_ITIME)
|
||||||
|
@ -242,6 +251,11 @@ extern struct dqstats dqstats;
|
||||||
#define DQ_FAKE_B 3 /* no limits only usage */
|
#define DQ_FAKE_B 3 /* no limits only usage */
|
||||||
#define DQ_READ_B 4 /* dquot was read into memory */
|
#define DQ_READ_B 4 /* dquot was read into memory */
|
||||||
#define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */
|
#define DQ_ACTIVE_B 5 /* dquot is active (dquot_release not called) */
|
||||||
|
#define DQ_LASTSET_B 6 /* Following 6 bits (see QIF_) are reserved\
|
||||||
|
* for the mask of entries set via SETQUOTA\
|
||||||
|
* quotactl. They are set under dq_data_lock\
|
||||||
|
* and the quota format handling dquot can\
|
||||||
|
* clear them when it sees fit. */
|
||||||
|
|
||||||
struct dquot {
|
struct dquot {
|
||||||
struct hlist_node dq_hash; /* Hash list in memory */
|
struct hlist_node dq_hash; /* Hash list in memory */
|
||||||
|
|
Loading…
Add table
Reference in a new issue