1 From: Jan Kara <jack@suse.cz>
2 References: fate#302681
3 Subject: [PATCH 05/28] quota: Allow to separately enable quota accounting and enforcing limits
4 Patch-mainline: 2.6.29?
6 Split DQUOT_USR_ENABLED (and DQUOT_GRP_ENABLED) into DQUOT_USR_USAGE_ENABLED
7 and DQUOT_USR_LIMITS_ENABLED. This way we are able to separately enable /
8 disable whether we should:
9 1) ignore quotas completely
10 2) just keep uptodate information about usage
11 3) actually enforce quota limits
13 This is going to be useful when quota is treated as filesystem metadata - we
14 then want to keep quota information uptodate all the time and just enable /
15 disable limits enforcement.
17 Signed-off-by: Jan Kara <jack@suse.cz>
19 fs/dquot.c | 222 ++++++++++++++++++++++++++++-----------------
21 include/linux/quota.h | 30 ++++++-
22 include/linux/quotaops.h | 86 ++++++++++++++----
23 4 files changed, 234 insertions(+), 112 deletions(-)
25 diff --git a/fs/dquot.c b/fs/dquot.c
26 index aea7bf9..bdfae7d 100644
29 @@ -489,7 +489,7 @@ int vfs_quota_sync(struct super_block *sb, int type)
30 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
31 if (type != -1 && cnt != type)
33 - if (!sb_has_quota_enabled(sb, cnt))
34 + if (!sb_has_quota_active(sb, cnt))
36 spin_lock(&dq_list_lock);
37 dirty = &dqopt->info[cnt].dqi_dirty_list;
38 @@ -514,8 +514,8 @@ int vfs_quota_sync(struct super_block *sb, int type)
41 for (cnt = 0; cnt < MAXQUOTAS; cnt++)
42 - if ((cnt == type || type == -1) && sb_has_quota_enabled(sb, cnt)
43 - && info_dirty(&dqopt->info[cnt]))
44 + if ((cnt == type || type == -1) && sb_has_quota_active(sb, cnt)
45 + && info_dirty(&dqopt->info[cnt]))
46 sb->dq_op->write_info(sb, cnt);
47 spin_lock(&dq_list_lock);
49 @@ -594,7 +594,7 @@ we_slept:
50 /* We have more than one user... nothing to do */
51 atomic_dec(&dquot->dq_count);
52 /* Releasing dquot during quotaoff phase? */
53 - if (!sb_has_quota_enabled(dquot->dq_sb, dquot->dq_type) &&
54 + if (!sb_has_quota_active(dquot->dq_sb, dquot->dq_type) &&
55 atomic_read(&dquot->dq_count) == 1)
56 wake_up(&dquot->dq_wait_unused);
57 spin_unlock(&dq_list_lock);
58 @@ -668,7 +668,7 @@ static struct dquot *dqget(struct super_block *sb, unsigned int id, int type)
59 unsigned int hashent = hashfn(sb, id, type);
60 struct dquot *dquot, *empty = NODQUOT;
62 - if (!sb_has_quota_enabled(sb, type))
63 + if (!sb_has_quota_active(sb, type))
66 spin_lock(&dq_list_lock);
67 @@ -1041,7 +1041,8 @@ static inline char ignore_hardlimit(struct dquot *dquot)
68 static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
70 *warntype = QUOTA_NL_NOWARN;
71 - if (test_bit(DQ_FAKE_B, &dquot->dq_flags))
72 + if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
73 + test_bit(DQ_FAKE_B, &dquot->dq_flags))
76 if (dquot->dq_dqb.dqb_ihardlimit &&
77 @@ -1073,7 +1074,8 @@ static int check_idq(struct dquot *dquot, qsize_t inodes, char *warntype)
78 static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *warntype)
80 *warntype = QUOTA_NL_NOWARN;
81 - if (test_bit(DQ_FAKE_B, &dquot->dq_flags))
82 + if (!sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type) ||
83 + test_bit(DQ_FAKE_B, &dquot->dq_flags))
86 if (dquot->dq_dqb.dqb_bhardlimit &&
87 @@ -1114,7 +1116,8 @@ static int check_bdq(struct dquot *dquot, qsize_t space, int prealloc, char *war
88 static int info_idq_free(struct dquot *dquot, qsize_t inodes)
90 if (test_bit(DQ_FAKE_B, &dquot->dq_flags) ||
91 - dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit)
92 + dquot->dq_dqb.dqb_curinodes <= dquot->dq_dqb.dqb_isoftlimit ||
93 + !sb_has_quota_limits_enabled(dquot->dq_sb, dquot->dq_type))
94 return QUOTA_NL_NOWARN;
96 if (dquot->dq_dqb.dqb_curinodes - inodes <= dquot->dq_dqb.dqb_isoftlimit)
97 @@ -1508,7 +1511,7 @@ warn_put_all:
98 /* Wrapper for transferring ownership of an inode */
99 int vfs_dq_transfer(struct inode *inode, struct iattr *iattr)
101 - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode)) {
102 + if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode)) {
104 if (inode->i_sb->dq_op->transfer(inode, iattr) == NO_QUOTA)
106 @@ -1549,53 +1552,22 @@ struct dquot_operations dquot_operations = {
107 .write_info = dquot_commit_info
110 -static inline void set_enable_flags(struct quota_info *dqopt, int type)
114 - dqopt->flags |= DQUOT_USR_ENABLED;
115 - dqopt->flags &= ~DQUOT_USR_SUSPENDED;
118 - dqopt->flags |= DQUOT_GRP_ENABLED;
119 - dqopt->flags &= ~DQUOT_GRP_SUSPENDED;
124 -static inline void reset_enable_flags(struct quota_info *dqopt, int type,
130 - dqopt->flags |= DQUOT_USR_SUSPENDED;
132 - dqopt->flags &= ~DQUOT_USR_ENABLED;
133 - dqopt->flags &= ~DQUOT_USR_SUSPENDED;
138 - dqopt->flags |= DQUOT_GRP_SUSPENDED;
140 - dqopt->flags &= ~DQUOT_GRP_ENABLED;
141 - dqopt->flags &= ~DQUOT_GRP_SUSPENDED;
149 * Turn quota off on a device. type == -1 ==> quotaoff for all types (umount)
151 -int vfs_quota_off(struct super_block *sb, int type, int remount)
152 +int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags)
155 struct quota_info *dqopt = sb_dqopt(sb);
156 struct inode *toputinode[MAXQUOTAS];
158 + /* Cannot turn off usage accounting without turning off limits, or
159 + * suspend quotas and simultaneously turn quotas off. */
160 + if ((flags & DQUOT_USAGE_ENABLED && !(flags & DQUOT_LIMITS_ENABLED))
161 + || (flags & DQUOT_SUSPENDED && flags & (DQUOT_LIMITS_ENABLED |
162 + DQUOT_USAGE_ENABLED)))
165 /* We need to serialize quota_off() for device */
166 mutex_lock(&dqopt->dqonoff_mutex);
168 @@ -1604,7 +1576,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
169 * sometimes we are called when fill_super() failed and calling
170 * sync_fs() in such cases does no good.
172 - if (!sb_any_quota_enabled(sb) && !sb_any_quota_suspended(sb)) {
173 + if (!sb_any_quota_loaded(sb)) {
174 mutex_unlock(&dqopt->dqonoff_mutex);
177 @@ -1612,17 +1584,28 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
178 toputinode[cnt] = NULL;
179 if (type != -1 && cnt != type)
181 - /* If we keep inodes of quota files after remount and quotaoff
182 - * is called, drop kept inodes. */
183 - if (!remount && sb_has_quota_suspended(sb, cnt)) {
184 - iput(dqopt->files[cnt]);
185 - dqopt->files[cnt] = NULL;
186 - reset_enable_flags(dqopt, cnt, 0);
187 + if (!sb_has_quota_loaded(sb, cnt))
190 + if (flags & DQUOT_SUSPENDED) {
192 + dquot_state_flag(DQUOT_SUSPENDED, cnt);
194 + dqopt->flags &= ~dquot_state_flag(flags, cnt);
195 + /* Turning off suspended quotas? */
196 + if (!sb_has_quota_loaded(sb, cnt) &&
197 + sb_has_quota_suspended(sb, cnt)) {
198 + dqopt->flags &= ~dquot_state_flag(
199 + DQUOT_SUSPENDED, cnt);
200 + iput(dqopt->files[cnt]);
201 + dqopt->files[cnt] = NULL;
205 - if (!sb_has_quota_enabled(sb, cnt))
207 + /* We still have to keep quota loaded? */
208 + if (sb_has_quota_loaded(sb, cnt) && !(flags & DQUOT_SUSPENDED))
210 - reset_enable_flags(dqopt, cnt, remount);
212 /* Note: these are blocking operations */
213 drop_dquot_ref(sb, cnt);
214 @@ -1638,7 +1621,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
215 put_quota_format(dqopt->info[cnt].dqi_format);
217 toputinode[cnt] = dqopt->files[cnt];
219 + if (!sb_has_quota_loaded(sb, cnt))
220 dqopt->files[cnt] = NULL;
221 dqopt->info[cnt].dqi_flags = 0;
222 dqopt->info[cnt].dqi_igrace = 0;
223 @@ -1661,7 +1644,7 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
224 mutex_lock(&dqopt->dqonoff_mutex);
225 /* If quota was reenabled in the meantime, we have
227 - if (!sb_has_quota_enabled(sb, cnt)) {
228 + if (!sb_has_quota_loaded(sb, cnt)) {
229 mutex_lock_nested(&toputinode[cnt]->i_mutex, I_MUTEX_QUOTA);
230 toputinode[cnt]->i_flags &= ~(S_IMMUTABLE |
231 S_NOATIME | S_NOQUOTA);
232 @@ -1671,10 +1654,13 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
234 mutex_unlock(&dqopt->dqonoff_mutex);
235 /* On remount RO, we keep the inode pointer so that we
236 - * can reenable quota on the subsequent remount RW.
237 - * But we have better not keep inode pointer when there
238 - * is pending delete on the quota file... */
240 + * can reenable quota on the subsequent remount RW. We
241 + * have to check 'flags' variable and not use sb_has_
242 + * function because another quotaon / quotaoff could
243 + * change global state before we got here. We refuse
244 + * to suspend quotas when there is pending delete on
245 + * the quota file... */
246 + if (!(flags & DQUOT_SUSPENDED))
247 iput(toputinode[cnt]);
248 else if (!toputinode[cnt]->i_nlink)
250 @@ -1684,12 +1670,22 @@ int vfs_quota_off(struct super_block *sb, int type, int remount)
254 +int vfs_quota_off(struct super_block *sb, int type, int remount)
256 + return vfs_quota_disable(sb, type, remount ? DQUOT_SUSPENDED :
257 + (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED));
261 * Turn quotas on on a device
264 -/* Helper function when we already have the inode */
265 -static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
267 + * Helper function to turn quotas on when we already have the inode of
268 + * quota file and no quota information is loaded.
270 +static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
271 + unsigned int flags)
273 struct quota_format_type *fmt = find_quota_format(format_id);
274 struct super_block *sb = inode->i_sb;
275 @@ -1711,6 +1707,11 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
279 + /* Usage always has to be set... */
280 + if (!(flags & DQUOT_USAGE_ENABLED)) {
285 /* As we bypass the pagecache we must now flush the inode so that
286 * we see all the changes from userspace... */
287 @@ -1719,8 +1720,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
288 invalidate_bdev(sb->s_bdev);
289 mutex_lock(&inode->i_mutex);
290 mutex_lock(&dqopt->dqonoff_mutex);
291 - if (sb_has_quota_enabled(sb, type) ||
292 - sb_has_quota_suspended(sb, type)) {
293 + if (sb_has_quota_loaded(sb, type)) {
297 @@ -1752,7 +1752,7 @@ static int vfs_quota_on_inode(struct inode *inode, int type, int format_id)
299 mutex_unlock(&dqopt->dqio_mutex);
300 mutex_unlock(&inode->i_mutex);
301 - set_enable_flags(dqopt, type);
302 + dqopt->flags |= dquot_state_flag(flags, type);
304 add_dquot_ref(sb, type);
305 mutex_unlock(&dqopt->dqonoff_mutex);
306 @@ -1785,20 +1785,23 @@ static int vfs_quota_on_remount(struct super_block *sb, int type)
307 struct quota_info *dqopt = sb_dqopt(sb);
310 + unsigned int flags;
312 mutex_lock(&dqopt->dqonoff_mutex);
313 if (!sb_has_quota_suspended(sb, type)) {
314 mutex_unlock(&dqopt->dqonoff_mutex);
317 - BUG_ON(sb_has_quota_enabled(sb, type));
319 inode = dqopt->files[type];
320 dqopt->files[type] = NULL;
321 - reset_enable_flags(dqopt, type, 0);
322 + flags = dqopt->flags & dquot_state_flag(DQUOT_USAGE_ENABLED |
323 + DQUOT_LIMITS_ENABLED, type);
324 + dqopt->flags &= ~dquot_state_flag(DQUOT_STATE_FLAGS, type);
325 mutex_unlock(&dqopt->dqonoff_mutex);
327 - ret = vfs_quota_on_inode(inode, type, dqopt->info[type].dqi_fmt_id);
328 + flags = dquot_generic_flag(flags, type);
329 + ret = vfs_load_quota_inode(inode, type, dqopt->info[type].dqi_fmt_id,
334 @@ -1814,12 +1817,12 @@ int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
335 if (path->mnt->mnt_sb != sb)
338 - error = vfs_quota_on_inode(path->dentry->d_inode, type,
340 + error = vfs_load_quota_inode(path->dentry->d_inode, type,
341 + format_id, DQUOT_USAGE_ENABLED |
342 + DQUOT_LIMITS_ENABLED);
346 -/* Actual function called from quotactl() */
347 int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
350 @@ -1838,6 +1841,50 @@ int vfs_quota_on(struct super_block *sb, int type, int format_id, char *path,
354 + * More powerful function for turning on quotas allowing setting
355 + * of individual quota flags
357 +int vfs_quota_enable(struct inode *inode, int type, int format_id,
358 + unsigned int flags)
361 + struct super_block *sb = inode->i_sb;
362 + struct quota_info *dqopt = sb_dqopt(sb);
364 + /* Just unsuspend quotas? */
365 + if (flags & DQUOT_SUSPENDED)
366 + return vfs_quota_on_remount(sb, type);
369 + /* Just updating flags needed? */
370 + if (sb_has_quota_loaded(sb, type)) {
371 + mutex_lock(&dqopt->dqonoff_mutex);
372 + /* Now do a reliable test... */
373 + if (!sb_has_quota_loaded(sb, type)) {
374 + mutex_unlock(&dqopt->dqonoff_mutex);
377 + if (flags & DQUOT_USAGE_ENABLED &&
378 + sb_has_quota_usage_enabled(sb, type)) {
382 + if (flags & DQUOT_LIMITS_ENABLED &&
383 + sb_has_quota_limits_enabled(sb, type)) {
387 + sb_dqopt(sb)->flags |= dquot_state_flag(flags, type);
389 + mutex_unlock(&dqopt->dqonoff_mutex);
394 + return vfs_load_quota_inode(inode, type, format_id, flags);
398 * This function is used when filesystem needs to initialize quotas
401 @@ -1858,7 +1905,8 @@ int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
403 error = security_quota_on(dentry);
405 - error = vfs_quota_on_inode(dentry->d_inode, type, format_id);
406 + error = vfs_load_quota_inode(dentry->d_inode, type, format_id,
407 + DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED);
411 @@ -1995,12 +2043,14 @@ int vfs_set_dqblk(struct super_block *sb, int type, qid_t id, struct if_dqblk *d
414 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
415 - if (!(dquot = dqget(sb, id, type))) {
416 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
418 + dquot = dqget(sb, id, type);
423 rc = do_set_dqblk(dquot, di);
426 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
429 @@ -2011,7 +2061,7 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
430 struct mem_dqinfo *mi;
432 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
433 - if (!sb_has_quota_enabled(sb, type)) {
434 + if (!sb_has_quota_active(sb, type)) {
435 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
438 @@ -2030,11 +2080,12 @@ int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
439 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
441 struct mem_dqinfo *mi;
444 mutex_lock(&sb_dqopt(sb)->dqonoff_mutex);
445 - if (!sb_has_quota_enabled(sb, type)) {
446 - mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
448 + if (!sb_has_quota_active(sb, type)) {
452 mi = sb_dqopt(sb)->info + type;
453 spin_lock(&dq_data_lock);
454 @@ -2048,8 +2099,9 @@ int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii)
455 mark_info_dirty(sb, type);
456 /* Force write to disk */
457 sb->dq_op->write_info(sb, type);
459 mutex_unlock(&sb_dqopt(sb)->dqonoff_mutex);
464 struct quotactl_ops vfs_quotactl_ops = {
465 @@ -2211,9 +2263,11 @@ EXPORT_SYMBOL(register_quota_format);
466 EXPORT_SYMBOL(unregister_quota_format);
467 EXPORT_SYMBOL(dqstats);
468 EXPORT_SYMBOL(dq_data_lock);
469 +EXPORT_SYMBOL(vfs_quota_enable);
470 EXPORT_SYMBOL(vfs_quota_on);
471 EXPORT_SYMBOL(vfs_quota_on_path);
472 EXPORT_SYMBOL(vfs_quota_on_mount);
473 +EXPORT_SYMBOL(vfs_quota_disable);
474 EXPORT_SYMBOL(vfs_quota_off);
475 EXPORT_SYMBOL(vfs_quota_sync);
476 EXPORT_SYMBOL(vfs_get_dqinfo);
477 diff --git a/fs/quota.c b/fs/quota.c
478 index 7f4386e..a8026f1 100644
481 @@ -73,7 +73,7 @@ static int generic_quotactl_valid(struct super_block *sb, int type, int cmd, qid
484 /* This is just informative test so we are satisfied without a lock */
485 - if (!sb_has_quota_enabled(sb, type))
486 + if (!sb_has_quota_active(sb, type))
490 @@ -175,7 +175,7 @@ static void quota_sync_sb(struct super_block *sb, int type)
491 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
492 if (type != -1 && cnt != type)
494 - if (!sb_has_quota_enabled(sb, cnt))
495 + if (!sb_has_quota_active(sb, cnt))
497 mutex_lock_nested(&sb_dqopt(sb)->files[cnt]->i_mutex, I_MUTEX_QUOTA);
498 truncate_inode_pages(&sb_dqopt(sb)->files[cnt]->i_data, 0);
499 @@ -201,7 +201,7 @@ restart:
500 for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
501 if (type != -1 && type != cnt)
503 - if (!sb_has_quota_enabled(sb, cnt))
504 + if (!sb_has_quota_active(sb, cnt))
506 if (!info_dirty(&sb_dqopt(sb)->info[cnt]) &&
507 list_empty(&sb_dqopt(sb)->info[cnt].dqi_dirty_list))
508 @@ -245,7 +245,7 @@ static int do_quotactl(struct super_block *sb, int type, int cmd, qid_t id, void
511 down_read(&sb_dqopt(sb)->dqptr_sem);
512 - if (!sb_has_quota_enabled(sb, type)) {
513 + if (!sb_has_quota_active(sb, type)) {
514 up_read(&sb_dqopt(sb)->dqptr_sem);
517 diff --git a/include/linux/quota.h b/include/linux/quota.h
518 index 5167786..0e4b550 100644
519 --- a/include/linux/quota.h
520 +++ b/include/linux/quota.h
521 @@ -320,12 +320,34 @@ struct quota_format_type {
522 struct quota_format_type *qf_next;
525 -#define DQUOT_USR_ENABLED 0x01 /* User diskquotas enabled */
526 -#define DQUOT_GRP_ENABLED 0x02 /* Group diskquotas enabled */
527 -#define DQUOT_USR_SUSPENDED 0x04 /* User diskquotas are off, but
528 +/* Quota state flags - they actually come in two flavors - for users and groups */
530 + _DQUOT_USAGE_ENABLED = 0, /* Track disk usage for users */
531 + _DQUOT_LIMITS_ENABLED, /* Enforce quota limits for users */
532 + _DQUOT_SUSPENDED, /* User diskquotas are off, but
533 * we have necessary info in
534 * memory to turn them on */
535 -#define DQUOT_GRP_SUSPENDED 0x08 /* The same for group quotas */
538 +#define DQUOT_USAGE_ENABLED (1 << _DQUOT_USAGE_ENABLED)
539 +#define DQUOT_LIMITS_ENABLED (1 << _DQUOT_LIMITS_ENABLED)
540 +#define DQUOT_SUSPENDED (1 << _DQUOT_SUSPENDED)
541 +#define DQUOT_STATE_FLAGS (DQUOT_USAGE_ENABLED | DQUOT_LIMITS_ENABLED | \
544 +static inline unsigned int dquot_state_flag(unsigned int flags, int type)
546 + if (type == USRQUOTA)
548 + return flags << _DQUOT_STATE_FLAGS;
551 +static inline unsigned int dquot_generic_flag(unsigned int flags, int type)
553 + if (type == USRQUOTA)
555 + return flags >> _DQUOT_STATE_FLAGS;
559 unsigned int flags; /* Flags for diskquotas on this device */
560 diff --git a/include/linux/quotaops.h b/include/linux/quotaops.h
561 index 12363cc..f7dcc30 100644
562 --- a/include/linux/quotaops.h
563 +++ b/include/linux/quotaops.h
564 @@ -43,11 +43,14 @@ int dquot_mark_dquot_dirty(struct dquot *dquot);
566 int vfs_quota_on(struct super_block *sb, int type, int format_id,
567 char *path, int remount);
568 +int vfs_quota_enable(struct inode *inode, int type, int format_id,
569 + unsigned int flags);
570 int vfs_quota_on_path(struct super_block *sb, int type, int format_id,
572 int vfs_quota_on_mount(struct super_block *sb, char *qf_name,
573 int format_id, int type);
574 int vfs_quota_off(struct super_block *sb, int type, int remount);
575 +int vfs_quota_disable(struct super_block *sb, int type, unsigned int flags);
576 int vfs_quota_sync(struct super_block *sb, int type);
577 int vfs_get_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
578 int vfs_set_dqinfo(struct super_block *sb, int type, struct if_dqinfo *ii);
579 @@ -67,26 +70,22 @@ static inline struct mem_dqinfo *sb_dqinfo(struct super_block *sb, int type)
580 * Functions for checking status of quota
583 -static inline int sb_has_quota_enabled(struct super_block *sb, int type)
584 +static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
586 - if (type == USRQUOTA)
587 - return (sb_dqopt(sb)->flags & DQUOT_USR_ENABLED)
588 - && !(sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED);
589 - return (sb_dqopt(sb)->flags & DQUOT_GRP_ENABLED)
590 - && !(sb_dqopt(sb)->flags & DQUOT_GROUP_SUSPENDED);
591 + return sb_dqopt(sb)->flags &
592 + dquot_state_flag(DQUOT_USAGE_ENABLED, type);
595 -static inline int sb_any_quota_enabled(struct super_block *sb)
596 +static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
598 - return sb_has_quota_enabled(sb, USRQUOTA) ||
599 - sb_has_quota_enabled(sb, GRPQUOTA);
600 + return sb_dqopt(sb)->flags &
601 + dquot_state_flag(DQUOT_LIMITS_ENABLED, type);
604 static inline int sb_has_quota_suspended(struct super_block *sb, int type)
606 - if (type == USRQUOTA)
607 - return sb_dqopt(sb)->flags & DQUOT_USR_SUSPENDED;
608 - return sb_dqopt(sb)->flags & DQUOT_GRP_SUSPENDED;
609 + return sb_dqopt(sb)->flags &
610 + dquot_state_flag(DQUOT_SUSPENDED, type);
613 static inline int sb_any_quota_suspended(struct super_block *sb)
614 @@ -95,6 +94,34 @@ static inline int sb_any_quota_suspended(struct super_block *sb)
615 sb_has_quota_suspended(sb, GRPQUOTA);
618 +/* Does kernel know about any quota information for given sb + type? */
619 +static inline int sb_has_quota_loaded(struct super_block *sb, int type)
621 + /* Currently if anything is on, then quota usage is on as well */
622 + return sb_has_quota_usage_enabled(sb, type);
625 +static inline int sb_any_quota_loaded(struct super_block *sb)
627 + return sb_has_quota_loaded(sb, USRQUOTA) ||
628 + sb_has_quota_loaded(sb, GRPQUOTA);
631 +static inline int sb_has_quota_active(struct super_block *sb, int type)
633 + return sb_has_quota_loaded(sb, type) &&
634 + !sb_has_quota_suspended(sb, type);
637 +static inline int sb_any_quota_active(struct super_block *sb)
639 + return sb_has_quota_active(sb, USRQUOTA) ||
640 + sb_has_quota_active(sb, GRPQUOTA);
643 +/* For backward compatibility until we remove all users */
644 +#define sb_any_quota_enabled(sb) sb_any_quota_active(sb)
647 * Operations supported for diskquotas.
649 @@ -109,7 +136,7 @@ extern struct quotactl_ops vfs_quotactl_ops;
650 static inline void vfs_dq_init(struct inode *inode)
652 BUG_ON(!inode->i_sb);
653 - if (sb_any_quota_enabled(inode->i_sb) && !IS_NOQUOTA(inode))
654 + if (sb_any_quota_active(inode->i_sb) && !IS_NOQUOTA(inode))
655 inode->i_sb->dq_op->initialize(inode, -1);
658 @@ -117,7 +144,7 @@ static inline void vfs_dq_init(struct inode *inode)
659 * a transaction (deadlocks possible otherwise) */
660 static inline int vfs_dq_prealloc_space_nodirty(struct inode *inode, qsize_t nr)
662 - if (sb_any_quota_enabled(inode->i_sb)) {
663 + if (sb_any_quota_active(inode->i_sb)) {
664 /* Used space is updated in alloc_space() */
665 if (inode->i_sb->dq_op->alloc_space(inode, nr, 1) == NO_QUOTA)
667 @@ -137,7 +164,7 @@ static inline int vfs_dq_prealloc_space(struct inode *inode, qsize_t nr)
669 static inline int vfs_dq_alloc_space_nodirty(struct inode *inode, qsize_t nr)
671 - if (sb_any_quota_enabled(inode->i_sb)) {
672 + if (sb_any_quota_active(inode->i_sb)) {
673 /* Used space is updated in alloc_space() */
674 if (inode->i_sb->dq_op->alloc_space(inode, nr, 0) == NO_QUOTA)
676 @@ -157,7 +184,7 @@ static inline int vfs_dq_alloc_space(struct inode *inode, qsize_t nr)
678 static inline int vfs_dq_alloc_inode(struct inode *inode)
680 - if (sb_any_quota_enabled(inode->i_sb)) {
681 + if (sb_any_quota_active(inode->i_sb)) {
683 if (inode->i_sb->dq_op->alloc_inode(inode, 1) == NO_QUOTA)
685 @@ -167,7 +194,7 @@ static inline int vfs_dq_alloc_inode(struct inode *inode)
687 static inline void vfs_dq_free_space_nodirty(struct inode *inode, qsize_t nr)
689 - if (sb_any_quota_enabled(inode->i_sb))
690 + if (sb_any_quota_active(inode->i_sb))
691 inode->i_sb->dq_op->free_space(inode, nr);
693 inode_sub_bytes(inode, nr);
694 @@ -181,7 +208,7 @@ static inline void vfs_dq_free_space(struct inode *inode, qsize_t nr)
696 static inline void vfs_dq_free_inode(struct inode *inode)
698 - if (sb_any_quota_enabled(inode->i_sb))
699 + if (sb_any_quota_active(inode->i_sb))
700 inode->i_sb->dq_op->free_inode(inode, 1);
703 @@ -202,12 +229,12 @@ static inline int vfs_dq_off(struct super_block *sb, int remount)
707 -static inline int sb_has_quota_enabled(struct super_block *sb, int type)
708 +static inline int sb_has_quota_usage_enabled(struct super_block *sb, int type)
713 -static inline int sb_any_quota_enabled(struct super_block *sb)
714 +static inline int sb_has_quota_limits_enabled(struct super_block *sb, int type)
718 @@ -222,6 +249,25 @@ static inline int sb_any_quota_suspended(struct super_block *sb)
722 +/* Does kernel know about any quota information for given sb + type? */
723 +static inline int sb_has_quota_loaded(struct super_block *sb, int type)
728 +static inline int sb_any_quota_loaded(struct super_block *sb)
733 +static inline int sb_any_quota_active(struct super_block *sb)
738 +/* For backward compatibility until we remove all users */
739 +#define sb_any_quota_enabled(sb) sb_any_quota_active(sb)
742 * NO-OP when quota not configured.