Blame SOURCES/quota-4.03-Add-support-for-scanning-using-Q_XGETNEXTQUOTA.patch

370c56
From 7367f5d511ec4555fbb7a87c1c1853fd4fd01712 Mon Sep 17 00:00:00 2001
370c56
From: Jan Kara <jack@suse.cz>
370c56
Date: Tue, 26 Jan 2016 14:06:59 +0100
370c56
Subject: [PATCH 2/2] Add support for scanning using Q_XGETNEXTQUOTA
370c56
MIME-Version: 1.0
370c56
Content-Type: text/plain; charset=UTF-8
370c56
Content-Transfer-Encoding: 8bit
370c56
370c56
Add support for scanning of all available quota structures using
370c56
Q_XGETNEXTQUOTA quotactl.
370c56
370c56
Signed-off-by: Jan Kara <jack@suse.cz>
370c56
Signed-off-by: Petr Písař <ppisar@redhat.com>
370c56
---
370c56
 quotaio_xfs.c | 42 +++++++++++++++++++++++++++++++++++++++---
370c56
 quotaio_xfs.h |  1 +
370c56
 2 files changed, 40 insertions(+), 3 deletions(-)
370c56
370c56
diff --git a/quotaio_xfs.c b/quotaio_xfs.c
370c56
index 903c03e..9d90a3e 100644
370c56
--- a/quotaio_xfs.c
370c56
+++ b/quotaio_xfs.c
370c56
@@ -191,15 +191,51 @@ static int xfs_get_dquot(struct dquot *dq)
370c56
 	return 0;
370c56
 }
370c56
 
370c56
+static int xfs_kernel_scan_dquots(struct quota_handle *h,
370c56
+		int (*process_dquot)(struct dquot *dquot, char *dqname))
370c56
+{
370c56
+	struct dquot *dquot = get_empty_dquot();
370c56
+	qid_t id = 0;
370c56
+	struct xfs_kern_dqblk xdqblk;
370c56
+	int ret;
370c56
+
370c56
+	dquot->dq_h = h;
370c56
+	while (1) {
370c56
+		ret = quotactl(QCMD(Q_XGETNEXTQUOTA, h->qh_type),
370c56
+			       h->qh_quotadev, id, (void *)&xdqblk);
370c56
+		if (ret < 0)
370c56
+			break;
370c56
+
370c56
+		xfs_kern2utildqblk(&dquot->dq_dqb, &xdqblk);
370c56
+		dquot->dq_id = xdqblk.d_id;
370c56
+		ret = process_dquot(dquot, NULL);
370c56
+		if (ret < 0)
370c56
+			break;
370c56
+		id = xdqblk.d_id + 1;
370c56
+	}
370c56
+	free(dquot);
370c56
+
370c56
+	if (errno == ENOENT)
370c56
+		return 0;
370c56
+	return ret;
370c56
+}
370c56
+
370c56
 /*
370c56
  *	Scan all known dquots and call callback on each
370c56
  */
370c56
 static int xfs_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *dquot, char *dqname))
370c56
 {
370c56
-	if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h))
370c56
-		return 0;
370c56
+	int ret;
370c56
+	struct xfs_kern_dqblk xdqblk;
370c56
 
370c56
-	return generic_scan_dquots(h, process_dquot, xfs_get_dquot);
370c56
+	ret = quotactl(QCMD(Q_XGETNEXTQUOTA, h->qh_type), h->qh_quotadev, 0,
370c56
+		       (void *)&xdqblk);
370c56
+	if (ret < 0 && (errno == ENOSYS || errno == EINVAL)) {
370c56
+		if (!XFS_USRQUOTA(h) && !XFS_GRPQUOTA(h))
370c56
+			return 0;
370c56
+		return generic_scan_dquots(h, process_dquot, xfs_get_dquot);
370c56
+	}
370c56
+	return xfs_kernel_scan_dquots(h, process_dquot);
370c56
 }
370c56
 
370c56
 /*
370c56
diff --git a/quotaio_xfs.h b/quotaio_xfs.h
370c56
index 54725b0..2236da4 100644
370c56
--- a/quotaio_xfs.h
370c56
+++ b/quotaio_xfs.h
370c56
@@ -46,6 +46,7 @@
370c56
 #define Q_XSETQLIM   XQM_CMD(0x4)	/* set disk limits only */
370c56
 #define Q_XGETQSTAT  XQM_CMD(0x5)	/* returns fs_quota_stat_t struct */
370c56
 #define Q_XQUOTARM   XQM_CMD(0x6)	/* free quota files' space */
370c56
+#define Q_XGETNEXTQUOTA	XQM_CMD(0x9)	/* get disk limits and usage >= ID */
370c56
 
370c56
 /*
370c56
  * fs_disk_quota structure:
370c56
-- 
370c56
2.5.0
370c56