diff options
-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); |