Commit 3cd0126d authored by Eric Sandeen's avatar Eric Sandeen Committed by Jan Kara

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: default avatarEric Sandeen <sandeen@redhat.com>
Reviewed-by: default avatarBill O'Donnell <billodo@redhat.com>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent f7a1c358
...@@ -341,6 +341,7 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) ...@@ -341,6 +341,7 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
struct qc_state state; struct qc_state state;
int ret; int ret;
memset(&state, 0, sizeof (struct qc_state));
ret = sb->s_qcop->get_state(sb, &state); ret = sb->s_qcop->get_state(sb, &state);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -365,17 +366,19 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs) ...@@ -365,17 +366,19 @@ static int quota_getstate(struct super_block *sb, struct fs_quota_stat *fqs)
fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) {
/* Inodes may be allocated even if inactive; copy out if present */
if (state.s_state[USRQUOTA].ino) {
fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
} }
if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { if (state.s_state[GRPQUOTA].ino) {
fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
} }
if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { if (state.s_state[PRJQUOTA].ino) {
/* /*
* Q_XGETQSTAT doesn't have room for both group and project * Q_XGETQSTAT doesn't have room for both group and project
* quotas. So, allow the project quota values to be copied out * 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,6 +414,7 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
struct qc_state state; struct qc_state state;
int ret; int ret;
memset(&state, 0, sizeof (struct qc_state));
ret = sb->s_qcop->get_state(sb, &state); ret = sb->s_qcop->get_state(sb, &state);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -435,17 +439,19 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs) ...@@ -435,17 +439,19 @@ static int quota_getstatev(struct super_block *sb, struct fs_quota_statv *fqs)
fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit; fqs->qs_rtbtimelimit = state.s_state[type].rt_spc_timelimit;
fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit; fqs->qs_bwarnlimit = state.s_state[type].spc_warnlimit;
fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit; fqs->qs_iwarnlimit = state.s_state[type].ino_warnlimit;
if (state.s_state[USRQUOTA].flags & QCI_ACCT_ENABLED) {
/* Inodes may be allocated even if inactive; copy out if present */
if (state.s_state[USRQUOTA].ino) {
fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino; fqs->qs_uquota.qfs_ino = state.s_state[USRQUOTA].ino;
fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks; fqs->qs_uquota.qfs_nblks = state.s_state[USRQUOTA].blocks;
fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents; fqs->qs_uquota.qfs_nextents = state.s_state[USRQUOTA].nextents;
} }
if (state.s_state[GRPQUOTA].flags & QCI_ACCT_ENABLED) { if (state.s_state[GRPQUOTA].ino) {
fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino; fqs->qs_gquota.qfs_ino = state.s_state[GRPQUOTA].ino;
fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks; fqs->qs_gquota.qfs_nblks = state.s_state[GRPQUOTA].blocks;
fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents; fqs->qs_gquota.qfs_nextents = state.s_state[GRPQUOTA].nextents;
} }
if (state.s_state[PRJQUOTA].flags & QCI_ACCT_ENABLED) { if (state.s_state[PRJQUOTA].ino) {
fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino; fqs->qs_pquota.qfs_ino = state.s_state[PRJQUOTA].ino;
fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks; fqs->qs_pquota.qfs_nblks = state.s_state[PRJQUOTA].blocks;
fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents; fqs->qs_pquota.qfs_nextents = state.s_state[PRJQUOTA].nextents;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment