diff --git a/quota-4.03-Add-support-for-scanning-using-Q_XGETNEXTQUOTA.patch b/quota-4.03-Add-support-for-scanning-using-Q_XGETNEXTQUOTA.patch new file mode 100644 index 0000000..1eb0d17 --- /dev/null +++ b/quota-4.03-Add-support-for-scanning-using-Q_XGETNEXTQUOTA.patch @@ -0,0 +1,92 @@ +From 7367f5d511ec4555fbb7a87c1c1853fd4fd01712 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 26 Jan 2016 14:06:59 +0100 +Subject: [PATCH 2/2] Add support for scanning using Q_XGETNEXTQUOTA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Add support for scanning of all available quota structures using +Q_XGETNEXTQUOTA quotactl. + +Signed-off-by: Jan Kara +Signed-off-by: Petr Písař +--- + quotaio_xfs.c | 42 +++++++++++++++++++++++++++++++++++++++--- + quotaio_xfs.h | 1 + + 2 files changed, 40 insertions(+), 3 deletions(-) + +diff --git a/quotaio_xfs.c b/quotaio_xfs.c +index 903c03e..9d90a3e 100644 +--- a/quotaio_xfs.c ++++ b/quotaio_xfs.c +@@ -191,15 +191,51 @@ static int xfs_get_dquot(struct dquot *dq) + return 0; + } + ++static int xfs_kernel_scan_dquots(struct quota_handle *h, ++ int (*process_dquot)(struct dquot *dquot, char *dqname)) ++{ ++ struct dquot *dquot = get_empty_dquot(); ++ qid_t id = 0; ++ struct xfs_kern_dqblk xdqblk; ++ int ret; ++ ++ dquot->dq_h = h; ++ while (1) { ++ ret = quotactl(QCMD(Q_XGETNEXTQUOTA, h->qh_type), ++ h->qh_quotadev, id, (void *)&xdqblk); ++ if (ret < 0) ++ break; ++ ++ xfs_kern2utildqblk(&dquot->dq_dqb, &xdqblk); ++ dquot->dq_id = xdqblk.d_id; ++ ret = process_dquot(dquot, NULL); ++ if (ret < 0) ++ break; ++ id = xdqblk.d_id + 1; ++ } ++ free(dquot); ++ ++ if (errno == ENOENT) ++ return 0; ++ return ret; ++} ++ + /* + * Scan all known dquots and call callback on each + */ + static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *dquot, char *dqname)) + { +- if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h)) +- return 0; ++ int ret; ++ struct xfs_kern_dqblk xdqblk; + +- return generic_scan_dquots(h, process_dquot, xfs_get_dquot); ++ ret = quotactl(QCMD(Q_XGETNEXTQUOTA, h->qh_type), h->qh_quotadev, 0, ++ (void *)&xdqblk); ++ if (ret < 0 && (errno == ENOSYS || errno == EINVAL)) { ++ if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h)) ++ return 0; ++ return generic_scan_dquots(h, process_dquot, xfs_get_dquot); ++ } ++ return xfs_kernel_scan_dquots(h, process_dquot); + } + + /* +diff --git a/quotaio_xfs.h b/quotaio_xfs.h +index 54725b0..2236da4 100644 +--- a/quotaio_xfs.h ++++ b/quotaio_xfs.h +@@ -46,6 +46,7 @@ + #define Q_XSETQLIM XQM_CMD(0x4) /* set disk limits only */ + #define Q_XGETQSTAT XQM_CMD(0x5) /* returns fs_quota_stat_t struct */ + #define Q_XQUOTARM XQM_CMD(0x6) /* free quota files' space */ ++#define Q_XGETNEXTQUOTA XQM_CMD(0x9) /* get disk limits and usage >= ID */ + + /* + * fs_disk_quota structure: +-- +2.5.0 + diff --git a/quota-4.03-Scan-dquots-using-Q_GETNEXTQUOTA.patch b/quota-4.03-Scan-dquots-using-Q_GETNEXTQUOTA.patch new file mode 100644 index 0000000..38707ed --- /dev/null +++ b/quota-4.03-Scan-dquots-using-Q_GETNEXTQUOTA.patch @@ -0,0 +1,142 @@ +From 85687833434d50e3f5fd4b849e543eb505bf5a20 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Tue, 26 Jan 2016 13:10:59 +0100 +Subject: [PATCH 1/2] Scan dquots using Q_GETNEXTQUOTA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Check for new kernel quotactl Q_GETNEXTQUOTA and if available use it for +scanning all dquot structures. + +Signed-off-by: Jan Kara +Signed-off-by: Petr Písař +--- + quota.h | 14 ++++++++++++++ + quotaio_generic.c | 34 ++++++++++++++++++++++++++++++++++ + quotaio_generic.h | 4 ++++ + quotaio_meta.c | 14 +++++++++++++- + 4 files changed, 65 insertions(+), 1 deletion(-) + +diff --git a/quota.h b/quota.h +index 0c38427..0607e04 100644 +--- a/quota.h ++++ b/quota.h +@@ -63,6 +63,7 @@ typedef int64_t qsize_t; /* Type in which we store size limitations */ + #define Q_SETINFO 0x800006 /* set information about quota files */ + #define Q_GETQUOTA 0x800007 /* get user quota structure */ + #define Q_SETQUOTA 0x800008 /* set user quota structure */ ++#define Q_GETNEXTQUOTA 0x800009 /* get disk limits and usage >= ID */ + + /* + * Quota structure used for communication with userspace via quotactl +@@ -91,6 +92,19 @@ struct if_dqblk { + u_int32_t dqb_valid; + }; + ++struct if_nextdqblk { ++ u_int64_t dqb_bhardlimit; ++ u_int64_t dqb_bsoftlimit; ++ u_int64_t dqb_curspace; ++ u_int64_t dqb_ihardlimit; ++ u_int64_t dqb_isoftlimit; ++ u_int64_t dqb_curinodes; ++ u_int64_t dqb_btime; ++ u_int64_t dqb_itime; ++ u_int32_t dqb_valid; ++ u_int32_t dqb_id; ++}; ++ + /* + * Structure used for setting quota information about file via quotactl + * Following flags are used to specify which fields are valid +diff --git a/quotaio_generic.c b/quotaio_generic.c +index 5001a56..4bdf380 100644 +--- a/quotaio_generic.c ++++ b/quotaio_generic.c +@@ -161,3 +161,37 @@ int generic_scan_dquots(struct quota_handle *h, + free(dquot); + return ret; + } ++ ++int vfs_scan_dquots(struct quota_handle *h, ++ int (*process_dquot)(struct dquot *dquot, char *dqname)) ++{ ++ struct dquot *dquot = get_empty_dquot(); ++ qid_t id = 0; ++ struct if_nextdqblk kdqblk; ++ int ret; ++ ++ dquot->dq_h = h; ++ while (1) { ++ ret = quotactl(QCMD(Q_GETNEXTQUOTA, h->qh_type), ++ h->qh_quotadev, id, (void *)&kdqblk); ++ if (ret < 0) ++ break; ++ ++ /* ++ * This is a slight hack but we know struct if_dqblk is a ++ * subset of struct if_nextdqblk ++ */ ++ generic_kern2utildqblk(&dquot->dq_dqb, ++ (struct if_dqblk *)&kdqblk); ++ dquot->dq_id = kdqblk.dqb_id; ++ ret = process_dquot(dquot, NULL); ++ if (ret < 0) ++ break; ++ id = kdqblk.dqb_id + 1; ++ } ++ free(dquot); ++ ++ if (errno == ENOENT) ++ return 0; ++ return ret; ++} +diff --git a/quotaio_generic.h b/quotaio_generic.h +index 5edc11c..a7930f0 100644 +--- a/quotaio_generic.h ++++ b/quotaio_generic.h +@@ -27,4 +27,8 @@ int generic_scan_dquots(struct quota_handle *h, + int (*process_dquot)(struct dquot *dquot, char *dqname), + int (*get_dquot)(struct dquot *dquot)); + ++/* Scan all dquots using kernel quotactl to get existing ids */ ++int vfs_scan_dquots(struct quota_handle *h, ++ int (*process_dquot)(struct dquot *dquot, char *dqname)); ++ + #endif +diff --git a/quotaio_meta.c b/quotaio_meta.c +index e52b4f4..ad6ff7a 100644 +--- a/quotaio_meta.c ++++ b/quotaio_meta.c +@@ -8,6 +8,7 @@ + + #include + #include ++#include + + #include + +@@ -55,7 +56,18 @@ static int meta_commit_dquot(struct dquot *dquot, int flags) + + static int meta_scan_dquots(struct quota_handle *h, int (*process_dquot)(struct dquot *dquot, char *dqname)) + { +- return generic_scan_dquots(h, process_dquot, vfs_get_dquot); ++ struct if_nextdqblk kdqblk; ++ int ret; ++ ++ ret = quotactl(QCMD(Q_GETNEXTQUOTA, h->qh_type), h->qh_quotadev, 0, ++ (void *)&kdqblk); ++ /* ++ * Fall back to scanning using passwd if Q_GETNEXTQUOTA is not ++ * supported ++ */ ++ if (ret < 0 && (errno == ENOSYS || errno == EINVAL)) ++ return generic_scan_dquots(h, process_dquot, vfs_get_dquot); ++ return vfs_scan_dquots(h, process_dquot); + } + + struct quotafile_ops quotafile_ops_meta = { +-- +2.5.0 + diff --git a/quota.spec b/quota.spec index 92792f9..2c9b401 100644 --- a/quota.spec +++ b/quota.spec @@ -4,7 +4,7 @@ Name: quota Epoch: 1 Version: 4.03 -Release: 2%{?dist} +Release: 3%{?dist} Summary: System administration tools for monitoring users' disk usage # quota_nld.c, quotaio_xfs.h: GPLv2 # bylabel.c copied from util-linux: GPLv2+ @@ -44,6 +44,11 @@ Patch3: quota-4.03-Respect-enviroment-CFLAGS.patch # bug #1296455, reported to upstream # Patch4: quota-4.03-Work-around-an-AC_CHECK_LIB-bug-in-Autoconf.patch +# Query kernel for next quota on file system with hiden quota files, +# bug #1306195, in upstream after 4.03 +Patch5: quota-4.03-Scan-dquots-using-Q_GETNEXTQUOTA.patch +# Query kernel for next XFS quota, bug #1306195, in upstream after 4.03 +Patch6: quota-4.03-Add-support-for-scanning-using-Q_XGETNEXTQUOTA.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: bash @@ -154,6 +159,8 @@ Linux/UNIX environment. %patch2 -p1 %patch3 -p1 %patch4 -p1 +%patch5 -p1 +%patch6 -p1 # Unpack forgotten LDAP scripts tar -xzkf %{SOURCE5} # Regenerate build scripts, also because of Respect-enviroment-CFLAGS.patch @@ -266,6 +273,10 @@ make check %changelog +* Mon Feb 22 2016 Petr Pisar - 1:4.03-3 +- Query kernel for next quota on XFS or file system with hidden quota files + (bug #1306195) + * Thu Feb 04 2016 Fedora Release Engineering - 1:4.03-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild