aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Sandeen <sandeen@redhat.com>2016-08-12 18:40:09 -0400
committerJan Kara <jack@suse.cz>2016-08-15 11:43:31 -0400
commit3cd0126dca82ecba8b2a6bf5aca91454da0a0776 (patch)
tree3e378fb00b74d19750f1fc530216e84898b20be3
parentf7a1c358e51c21b80336413fb824e1a82df648b9 (diff)
quota: fill in Q_XGETQSTAT inode information for inactive quotas
The manpage for quotactl says that the Q_XGETQSTAT command is "useful in finding out how much space is spent to store quota information," but the current implementation does not report this info if the inode is allocated, but its quota type is not enabled. This is a change from the earlier XFS implementation, which reported information about allocated quota inodes even if their quota type was not currently active. Change quota_getstate() and quota_getstatev() to copy out the inode information if the filesystem has provided it, even if the quota type for that inode is not currently active. Signed-off-by: Eric Sandeen <sandeen@redhat.com> Reviewed-by: Bill O'Donnell <billodo@redhat.com> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/quota/quota.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/fs/quota/quota.c b/fs/quota/quota.c
index 35df08ee9c97..2d445425aad7 100644
--- a/fs/quota/quota.c
+++ b/fs/quota/quota.c
@@ -341,6 +341,7 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
341 struct qc_state state; 341 struct qc_state state;
342 int ret; 342 int ret;
343 343
344 memset(&state, 0, sizeof (struct qc_state));
344 ret = sb->s_qcop->get_state(sb, &state); 345 ret = sb->s_qcop->get_state(sb, &state);
345 if (ret < 0) 346 if (ret < 0)
346 return ret; 347 return ret;
@@ -365,17 +366,19 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
365 fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; 366 fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
366 fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; 367 fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
367 fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; 368 fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
368 if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { 369
370 /* Inodes may be allocated even if inactive; copy out if present */
371 if (state.s_state[USRQUOTA].ino) {
369 fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; 372 fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
370 fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; 373 fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
371 fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; 374 fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
372 } 375 }
373 if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { 376 if (state.s_state[GRPQUOTA].ino) {
374 fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; 377 fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
375 fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; 378 fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
376 fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; 379 fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
377 } 380 }
378 if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { 381 if (state.s_state[PRJQUOTA].ino) {
379 /* 382 /*
380 * Q_XGETQSTAT doesn't have room for both group and project 383 * Q_XGETQSTAT doesn't have room for both group and project
381 * quotas. So, allow the project quota values to be copied out 384 * quotas. So, allow the project quota values to be copied out
@@ -411,6 +414,7 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
411 struct qc_state state; 414 struct qc_state state;
412 int ret; 415 int ret;
413 416
417 memset(&state, 0, sizeof (struct qc_state));
414 ret = sb->s_qcop->get_state(sb, &state); 418 ret = sb->s_qcop->get_state(sb, &state);
415 if (ret < 0) 419 if (ret < 0)
416 return ret; 420 return ret;
@@ -435,17 +439,19 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
435 fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; 439 fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
436 fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; 440 fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
437 fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; 441 fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
438 if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) { 442
443 /* Inodes may be allocated even if inactive; copy out if present */
444 if (state.s_state[USRQUOTA].ino) {
439 fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; 445 fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
440 fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; 446 fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
441 fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; 447 fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
442 } 448 }
443 if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { 449 if (state.s_state[GRPQUOTA].ino) {
444 fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; 450 fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
445 fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; 451 fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
446 fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; 452 fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
447 } 453 }
448 if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { 454 if (state.s_state[PRJQUOTA].ino) {
449 fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino; 455 fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino;
450 fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks; 456 fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks;
451 fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents; 457 fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents;