summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--quotaon.c34
-rw-r--r--quotasys.c34
-rw-r--r--quotasys.h6
3 files changed, 55 insertions, 19 deletions
diff --git a/quotaon.c b/quotaon.c
index b9cc841..fe19224 100644
--- a/quotaon.c
+++ b/quotaon.c
@@ -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)
diff --git a/quotasys.c b/quotasys.c
index d04f25a..48368a5 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -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;
}
diff --git a/quotasys.h b/quotasys.h
index f19b00e..cb1f22f 100644
--- a/quotasys.h
+++ b/quotasys.h
@@ -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);