diff options
author | Jan Kara <jack@suse.cz> | 2016-07-12 14:18:10 +0200 |
---|---|---|
committer | Jan Kara <jack@suse.cz> | 2016-07-12 14:18:10 +0200 |
commit | beeec582a54e86052560b75440562028cd6a7d0a (patch) | |
tree | 91d4156b218b6003c9f101164697841d401e13d5 | |
parent | 3715b0f5bd11116796f5f80144ceefe539b320aa (diff) | |
download | linuxquota-beeec582a54e86052560b75440562028cd6a7d0a.tar.gz |
quotaon: Improve reporting of quota state
quotactl Q_XFS_GETQSTAT is able to report whether only accounting or
also quota enforcement is turned on. This works for XFS and GFS2 for
ages and since kernel 4.1 also for other filesystems. Use this quotactl
when it is supported and report more details in verbose mode.
Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r-- | quotaon.c | 34 | ||||
-rw-r--r-- | quotasys.c | 34 | ||||
-rw-r--r-- | quotasys.h | 6 |
3 files changed, 55 insertions, 19 deletions
@@ -332,23 +332,39 @@ static int newstate(struct mount_entry *mnt, int type, char *extra) static int print_state(struct mount_entry *mnt, int type) { int on = 0; - - if (!strcmp(mnt->me_type, MNTTYPE_XFS) || - !strcmp(mnt->me_type, MNTTYPE_GFS2)) { - if (kern_qfmt_supp(QF_XFS)) - on = kern_quota_on(mnt, type, QF_XFS) != -1; + char *state; + + if (kern_qfmt_supp(QF_XFS)) { + on = kern_quota_state_xfs(mnt->me_devname, type); + if (!strcmp(mnt->me_type, MNTTYPE_XFS) || + !strcmp(mnt->me_type, MNTTYPE_GFS2) || on >= 0) { + if (on < 0) + on = 0; + if (!(flags & FL_VERBOSE)) + goto print_state; + if (on == 0) + state = _("off"); + else if (on == 1) + state = _("on (accounting)"); + else + state = _("on (enforced)"); + goto print; + } } - else if (kernel_iface == IFACE_GENERIC) + if (kernel_iface == IFACE_GENERIC) on = kern_quota_on(mnt, type, -1) != -1; else if (kern_qfmt_supp(QF_VFSV0)) on = kern_quota_on(mnt, type, QF_VFSV0) != -1; else if (kern_qfmt_supp(QF_VFSOLD)) on = kern_quota_on(mnt, type, QF_VFSOLD) != -1; - printf(_("%s quota on %s (%s) is %s\n"), _(type2name(type)), mnt->me_dir, mnt->me_devname, - on ? _("on") : _("off")); +print_state: + state = on ? _("on") : _("off"); +print: + printf(_("%s quota on %s (%s) is %s\n"), _(type2name(type)), + mnt->me_dir, mnt->me_devname, state); - return on; + return on > 0; } int main(int argc, char **argv) @@ -1114,20 +1114,34 @@ static int v2_kern_quota_on(const char *dev, int type) return 0; } -/* Check whether XFS quota is turned on on given device */ -static int xfs_kern_quota_on(const char *dev, int type) +/* + * Check whether quota is turned on on given device. This quotactl always + * worked for XFS and it works even for VFS quotas for kernel 4.1 and newer. + * + * We return 0 when quota is not turned on, 1 when only accounting is turned + * on, and 2 when both accounting and enforcement is turned on. We return -1 + * on error. + */ +int kern_quota_state_xfs(const char *dev, int type) { struct xfs_mem_dqinfo info; if (!quotactl(QCMD(Q_XFS_GETQSTAT, type), dev, 0, (void *)&info)) { - if (type == USRQUOTA && (info.qs_flags & XFS_QUOTA_UDQ_ACCT)) - return 1; - if (type == GRPQUOTA && (info.qs_flags & XFS_QUOTA_GDQ_ACCT)) - return 1; - if (type == PRJQUOTA && (info.qs_flags & XFS_QUOTA_PDQ_ACCT)) - return 1; + if (type == USRQUOTA) { + return !!(info.qs_flags & XFS_QUOTA_UDQ_ACCT) + + !!(info.qs_flags & XFS_QUOTA_UDQ_ENFD); + } + if (type == GRPQUOTA) { + return !!(info.qs_flags & XFS_QUOTA_GDQ_ACCT) + + !!(info.qs_flags & XFS_QUOTA_GDQ_ENFD); + } + if (type == PRJQUOTA) { + return !!(info.qs_flags & XFS_QUOTA_PDQ_ACCT) + + !!(info.qs_flags & XFS_QUOTA_PDQ_ENFD); + } + return 0; } - return 0; + return -1; } /* @@ -1141,7 +1155,7 @@ int kern_quota_on(struct mount_entry *mnt, int type, int fmt) return -1; if (mnt->me_qfmt[type] == QF_XFS) { if ((fmt == -1 || fmt == QF_XFS) && - xfs_kern_quota_on(mnt->me_devname, type)) /* XFS quota format */ + kern_quota_state_xfs(mnt->me_devname, type) > 0) return QF_XFS; return -1; } @@ -173,6 +173,12 @@ int devcmp_handles(struct quota_handle *a, struct quota_handle *b); /* Check kernel supported quotafile format */ void init_kernel_interface(void); +/* + * Check whether is quota turned on on given device for given type. This + * works for XFS for all kernels and for other filesystems since kernel 4.1. + */ +int kern_quota_state_xfs(const char *dev, int type); + /* Check whether is quota turned on on given device for given type */ int kern_quota_on(struct mount_entry *mnt, int type, int fmt); |