public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] xfsprogs: use Q_XGETNEXTQUOTA
@ 2016-01-22  4:27 Eric Sandeen
  2016-01-22  4:27 ` [PATCH 1/3] xfs_quota: define Q_XGETNEXTQUOTA Eric Sandeen
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Eric Sandeen @ 2016-01-22  4:27 UTC (permalink / raw)
  To: xfs

Patch series to make xfs_quota's repquota and quota dump use the new
Q_XGETNEXTQUOTA interface.

-Eric

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/3] xfs_quota: define Q_XGETNEXTQUOTA
  2016-01-22  4:27 [PATCH 0/3] xfsprogs: use Q_XGETNEXTQUOTA Eric Sandeen
@ 2016-01-22  4:27 ` Eric Sandeen
  2016-01-22  4:28 ` [PATCH 2/3] xfs_quota: make report_mount() & dump_file() take an "output id" Eric Sandeen
  2016-01-22  4:28 ` [PATCH 3/3] xfs_quota: use Q_XGETNEXTQUOTA for report and dump Eric Sandeen
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Sandeen @ 2016-01-22  4:27 UTC (permalink / raw)
  To: xfs

This simply defines the Q_XGETNEXTQUOTA quotactl in xfsprogs.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
 include/xqm.h |    1 +
 quota/linux.c |    2 ++
 quota/quota.h |    2 ++
 3 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/include/xqm.h b/include/xqm.h
index 47f58a0..8357c9d 100644
--- a/include/xqm.h
+++ b/include/xqm.h
@@ -32,6 +32,7 @@
 #define Q_XGETQSTAT	XQM_CMD(5)	/* get quota subsystem status */
 #define Q_XQUOTARM	XQM_CMD(6)	/* free disk space used by dquots */
 #define Q_XQUOTASYNC	XQM_CMD(7)	/* delalloc flush, updates dquots */
+#define Q_XGETNEXTQUOTA	XQM_CMD(9)	/* get disk limits and usage */
 
 /*
  * fs_disk_quota structure:
diff --git a/quota/linux.c b/quota/linux.c
index 8a73922..74dba01 100644
--- a/quota/linux.c
+++ b/quota/linux.c
@@ -49,6 +49,8 @@ xcommand_to_qcommand(
 		return Q_XQUOTAOFF;
 	case XFS_GETQUOTA:
 		return Q_XGETQUOTA;
+	case XFS_GETNEXTQUOTA:
+		return Q_XGETNEXTQUOTA;
 	case XFS_SETQLIM:
 		return Q_XSETQLIM;
 	case XFS_GETQSTAT:
diff --git a/quota/quota.h b/quota/quota.h
index 416f335..2bbc176 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -43,6 +43,8 @@ enum {
 	XFS_GETQSTAT,	/* get quota subsystem status */
 	XFS_QUOTARM,	/* free disk space used by dquots */
 	XFS_QSYNC,	/* flush delayed allocate space */
+	XFS_GETQSTATV,	/* newer version of quota stats */
+	XFS_GETNEXTQUOTA, /* get disk limits and usage */
 };
 
 /*
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/3] xfs_quota: make report_mount() & dump_file() take an "output id"
  2016-01-22  4:27 [PATCH 0/3] xfsprogs: use Q_XGETNEXTQUOTA Eric Sandeen
  2016-01-22  4:27 ` [PATCH 1/3] xfs_quota: define Q_XGETNEXTQUOTA Eric Sandeen
@ 2016-01-22  4:28 ` Eric Sandeen
  2016-01-22  4:28 ` [PATCH 3/3] xfs_quota: use Q_XGETNEXTQUOTA for report and dump Eric Sandeen
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Sandeen @ 2016-01-22  4:28 UTC (permalink / raw)
  To: xfs

Allow report_mount() and dump_file() to take a *oid pointer,
an "output id" which will be filled in from the returned quota
information.  Useful if the quotactl returns an ID for something
other than that which was passed in, i.e. GETNEXTQUOTA.

Also, when printing results, print the id which was actually
returned, not the id which was passed in.

Should be a no-op change at this point; the next patch which
wires in Q_XGETNEXTQUOTA will make use of this.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
 quota/report.c |   46 ++++++++++++++++++++++++++++++----------------
 1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/quota/report.c b/quota/report.c
index c77b24f..3085a9e 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -77,6 +77,7 @@ static void
 dump_file(
 	FILE		*fp,
 	uint		id,
+	uint		*oid,
 	uint		type,
 	char		*dev)
 {
@@ -87,6 +88,10 @@ dump_file(
 			perror("XFS_GETQUOTA");
 		return;
 	}
+
+	if (oid)
+		*oid = d.d_id;
+
 	if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
 	    !d.d_ino_softlimit && !d.d_ino_hardlimit &&
 	    !d.d_rtb_softlimit && !d.d_rtb_hardlimit)
@@ -94,7 +99,8 @@ dump_file(
 	fprintf(fp, "fs = %s\n", dev);
 	/* this branch is for backward compatibility reasons */
 	if (d.d_rtb_softlimit || d.d_rtb_hardlimit)
-		fprintf(fp, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n", id,
+		fprintf(fp, "%-10d %7llu %7llu %7llu %7llu %7llu %7llu\n",
+			d.d_id,
 			(unsigned long long)d.d_blk_softlimit,
 			(unsigned long long)d.d_blk_hardlimit,
 			(unsigned long long)d.d_ino_softlimit,
@@ -102,7 +108,8 @@ dump_file(
 			(unsigned long long)d.d_rtb_softlimit,
 			(unsigned long long)d.d_rtb_hardlimit);
 	else
-		fprintf(fp, "%-10d %7llu %7llu %7llu %7llu\n", id,
+		fprintf(fp, "%-10d %7llu %7llu %7llu %7llu\n",
+			d.d_id,
 			(unsigned long long)d.d_blk_softlimit,
 			(unsigned long long)d.d_blk_hardlimit,
 			(unsigned long long)d.d_ino_softlimit,
@@ -129,7 +136,7 @@ dump_limits_any_type(
 
 	if (upper) {
 		for (id = lower; id <= upper; id++)
-			dump_file(fp, id, type, mount->fs_name);
+			dump_file(fp, id, NULL, type, mount->fs_name);
 		return;
 	}
 
@@ -138,7 +145,8 @@ dump_limits_any_type(
 			struct group *g;
 			setgrent();
 			while ((g = getgrent()) != NULL)
-				dump_file(fp, g->gr_gid, type, mount->fs_name);
+				dump_file(fp, g->gr_gid, NULL, type,
+					  mount->fs_name);
 			endgrent();
 			break;
 		}
@@ -146,7 +154,8 @@ dump_limits_any_type(
 			struct fs_project *p;
 			setprent();
 			while ((p = getprent()) != NULL)
-				dump_file(fp, p->pr_prid, type, mount->fs_name);
+				dump_file(fp, p->pr_prid, NULL, type,
+					  mount->fs_name);
 			endprent();
 			break;
 		}
@@ -154,7 +163,8 @@ dump_limits_any_type(
 			struct passwd *u;
 			setpwent();
 			while ((u = getpwent()) != NULL)
-				dump_file(fp, u->pw_uid, type, mount->fs_name);
+				dump_file(fp, u->pw_uid, NULL, type,
+					  mount->fs_name);
 			endpwent();
 			break;
 		}
@@ -291,6 +301,7 @@ report_mount(
 	FILE		*fp,
 	__uint32_t	id,
 	char		*name,
+	__uint32_t	*oid,
 	uint		form,
 	uint		type,
 	fs_path_t	*mount,
@@ -308,6 +319,9 @@ report_mount(
 		return 0;
 	}
 
+	if (oid)
+		*oid = d.d_id;
+
 	if (flags & TERSE_FLAG) {
 		count = 0;
 		if ((form & XFS_BLOCK_QUOTA) && d.d_bcount)
@@ -324,19 +338,19 @@ report_mount(
 		report_header(fp, form, type, mount, flags);
 
 	if (flags & NO_LOOKUP_FLAG) {
-		fprintf(fp, "#%-10u", id);
+		fprintf(fp, "#%-10u", d.d_id);
 	} else {
 		if (name == NULL) {
 			if (type == XFS_USER_QUOTA) {
-				struct passwd	*u = getpwuid(id);
+				struct passwd	*u = getpwuid(d.d_id);
 				if (u)
 					name = u->pw_name;
 			} else if (type == XFS_GROUP_QUOTA) {
-				struct group	*g = getgrgid(id);
+				struct group	*g = getgrgid(d.d_id);
 				if (g)
 					name = g->gr_name;
 			} else if (type == XFS_PROJ_QUOTA) {
-				fs_project_t	*p = getprprid(id);
+				fs_project_t	*p = getprprid(d.d_id);
 				if (p)
 					name = p->pr_name;
 			}
@@ -425,14 +439,14 @@ report_user_mount(
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
-			if (report_mount(fp, id, NULL,
+			if (report_mount(fp, id, NULL, NULL,
 					form, XFS_USER_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
 	} else {
 		setpwent();
 		while ((u = getpwent()) != NULL) {
-			if (report_mount(fp, u->pw_uid, u->pw_name,
+			if (report_mount(fp, u->pw_uid, u->pw_name, NULL,
 					form, XFS_USER_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
@@ -457,14 +471,14 @@ report_group_mount(
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
-			if (report_mount(fp, id, NULL,
+			if (report_mount(fp, id, NULL, NULL,
 					form, XFS_GROUP_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
 	} else {
 		setgrent();
 		while ((g = getgrent()) != NULL) {
-			if (report_mount(fp, g->gr_gid, g->gr_name,
+			if (report_mount(fp, g->gr_gid, g->gr_name, NULL,
 					form, XFS_GROUP_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
@@ -488,14 +502,14 @@ report_project_mount(
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
-			if (report_mount(fp, id, NULL,
+			if (report_mount(fp, id, NULL, NULL,
 					form, XFS_PROJ_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
 	} else {
 		setprent();
 		while ((p = getprent()) != NULL) {
-			if (report_mount(fp, p->pr_prid, p->pr_name,
+			if (report_mount(fp, p->pr_prid, p->pr_name, NULL,
 					form, XFS_PROJ_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 3/3] xfs_quota: use Q_XGETNEXTQUOTA for report and dump
  2016-01-22  4:27 [PATCH 0/3] xfsprogs: use Q_XGETNEXTQUOTA Eric Sandeen
  2016-01-22  4:27 ` [PATCH 1/3] xfs_quota: define Q_XGETNEXTQUOTA Eric Sandeen
  2016-01-22  4:28 ` [PATCH 2/3] xfs_quota: make report_mount() & dump_file() take an "output id" Eric Sandeen
@ 2016-01-22  4:28 ` Eric Sandeen
  2 siblings, 0 replies; 4+ messages in thread
From: Eric Sandeen @ 2016-01-22  4:28 UTC (permalink / raw)
  To: xfs

Rather than a loop over getpwnam() etc, use the Q_XGETNEXTQUOTA
command to iterate through all active quotas in quota
reports and quota file dump.

If Q_XGETNEXTQUOTA fails, go back to the old way.

Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---


(This stuff is screaming to be refactored and made consistent,
but my first attempt left me screaming too, so I'll leave
it for another day.)


 quota/quota.h  |    1 +
 quota/report.c |   84 ++++++++++++++++++++++++++++++++++++++++++++++---------
 2 files changed, 71 insertions(+), 14 deletions(-)

diff --git a/quota/quota.h b/quota/quota.h
index 2bbc176..4bde351 100644
--- a/quota/quota.h
+++ b/quota/quota.h
@@ -74,6 +74,7 @@ enum {
 	DEFAULTS_FLAG =		0x0100,	/* use value as a default */
 	ABSOLUTE_FLAG =		0x0200, /* absolute time, not related to now */
 	NO_LOOKUP_FLAG =	0x0400, /* skip name lookups, just report ID */
+	GETNEXTQUOTA_FLAG =	0x0800, /* use getnextquota quotactl */
 };
 
 /*
diff --git a/quota/report.c b/quota/report.c
index 3085a9e..8653134 100644
--- a/quota/report.c
+++ b/quota/report.c
@@ -73,20 +73,27 @@ report_help(void)
 "\n"));
 }
 
-static void
+static int 
 dump_file(
 	FILE		*fp,
 	uint		id,
 	uint		*oid,
 	uint		type,
-	char		*dev)
+	char		*dev,
+	int		flags)
 {
 	fs_disk_quota_t	d;
+	int		cmd;
+
+	if (flags & GETNEXTQUOTA_FLAG)
+		cmd = XFS_GETNEXTQUOTA;
+	else
+		cmd = XFS_GETQUOTA;
 
-	if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
+	if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
 		if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
 			perror("XFS_GETQUOTA");
-		return;
+		return 0;
 	}
 
 	if (oid)
@@ -95,7 +102,7 @@ dump_file(
 	if (!d.d_blk_softlimit && !d.d_blk_hardlimit &&
 	    !d.d_ino_softlimit && !d.d_ino_hardlimit &&
 	    !d.d_rtb_softlimit && !d.d_rtb_hardlimit)
-		return;
+		return 1;
 	fprintf(fp, "fs = %s\n", dev);
 	/* this branch is for backward compatibility reasons */
 	if (d.d_rtb_softlimit || d.d_rtb_hardlimit)
@@ -114,6 +121,8 @@ dump_file(
 			(unsigned long long)d.d_blk_hardlimit,
 			(unsigned long long)d.d_ino_softlimit,
 			(unsigned long long)d.d_ino_hardlimit);
+
+	return 1;
 }
 
 static void
@@ -125,7 +134,7 @@ dump_limits_any_type(
 	uint		upper)
 {
 	fs_path_t	*mount;
-	uint		id;
+	uint		id = 0, oid;
 
 	if ((mount = fs_table_lookup(dir, FS_MOUNT_POINT)) == NULL) {
 		exitcode = 1;
@@ -134,19 +143,30 @@ dump_limits_any_type(
 		return;
 	}
 
+	/* Range was specified; query everything in it */
 	if (upper) {
 		for (id = lower; id <= upper; id++)
-			dump_file(fp, id, NULL, type, mount->fs_name);
+			dump_file(fp, id, NULL, type, mount->fs_name, 0);
 		return;
 	}
 
+	/* Use GETNEXTQUOTA if it's available */
+	if (dump_file(fp, id, &oid, type, mount->fs_name, GETNEXTQUOTA_FLAG)) {
+		id = oid + 1;
+		while (dump_file(fp, id, &oid, type, mount->fs_name,
+				 GETNEXTQUOTA_FLAG))
+			id = oid + 1;
+		return;
+        }
+
+	/* Otherwise fall back to iterating over each uid/gid/prjid */
 	switch (type) {
 	case XFS_GROUP_QUOTA: {
 			struct group *g;
 			setgrent();
 			while ((g = getgrent()) != NULL)
 				dump_file(fp, g->gr_gid, NULL, type,
-					  mount->fs_name);
+					  mount->fs_name, 0);
 			endgrent();
 			break;
 		}
@@ -155,7 +175,7 @@ dump_limits_any_type(
 			setprent();
 			while ((p = getprent()) != NULL)
 				dump_file(fp, p->pr_prid, NULL, type,
-					  mount->fs_name);
+					  mount->fs_name, 0);
 			endprent();
 			break;
 		}
@@ -164,7 +184,7 @@ dump_limits_any_type(
 			setpwent();
 			while ((u = getpwent()) != NULL)
 				dump_file(fp, u->pw_uid, NULL, type,
-					  mount->fs_name);
+					  mount->fs_name, 0);
 			endpwent();
 			break;
 		}
@@ -312,8 +332,14 @@ report_mount(
 	char		c[8], h[8], s[8];
 	uint		qflags;
 	int		count;
+	int		cmd;
+
+	if (flags & GETNEXTQUOTA_FLAG)
+		cmd = XFS_GETNEXTQUOTA;
+	else
+		cmd = XFS_GETQUOTA;
 
-	if (xfsquotactl(XFS_GETQUOTA, dev, type, id, (void *)&d) < 0) {
+	if (xfsquotactl(cmd, dev, type, id, (void *)&d) < 0) {
 		if (errno != ENOENT && errno != ENOSYS && errno != ESRCH)
 			perror("XFS_GETQUOTA");
 		return 0;
@@ -435,7 +461,7 @@ report_user_mount(
 	uint		flags)
 {
 	struct passwd	*u;
-	uint		id;
+	uint		id = 0, oid;
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
@@ -443,6 +469,16 @@ report_user_mount(
 					form, XFS_USER_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
+	} else if (report_mount(fp, id, NULL, &oid, form,
+				XFS_USER_QUOTA, mount,
+				flags|GETNEXTQUOTA_FLAG)) {
+		id = oid + 1;
+		flags |= GETNEXTQUOTA_FLAG;
+		flags |= NO_HEADER_FLAG;
+		while (report_mount(fp, id, NULL, &oid, form, XFS_USER_QUOTA,
+				    mount, flags)) {
+			id = oid + 1;
+		}
 	} else {
 		setpwent();
 		while ((u = getpwent()) != NULL) {
@@ -467,7 +503,7 @@ report_group_mount(
 	uint		flags)
 {
 	struct group	*g;
-	uint		id;
+	uint		id = 0, oid;
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
@@ -475,6 +511,16 @@ report_group_mount(
 					form, XFS_GROUP_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
+	} else if (report_mount(fp, id, NULL, &oid, form,
+				XFS_GROUP_QUOTA, mount,
+				flags|GETNEXTQUOTA_FLAG)) {
+		id = oid + 1;
+		flags |= GETNEXTQUOTA_FLAG;
+		flags |= NO_HEADER_FLAG;
+		while (report_mount(fp, id, NULL, &oid, form, XFS_GROUP_QUOTA,
+				    mount, flags)) {
+			id = oid + 1;
+		}
 	} else {
 		setgrent();
 		while ((g = getgrent()) != NULL) {
@@ -498,7 +544,7 @@ report_project_mount(
 	uint		flags)
 {
 	fs_project_t	*p;
-	uint		id;
+	uint		id = 0, oid;
 
 	if (upper) {	/* identifier range specified */
 		for (id = lower; id <= upper; id++) {
@@ -506,6 +552,16 @@ report_project_mount(
 					form, XFS_PROJ_QUOTA, mount, flags))
 				flags |= NO_HEADER_FLAG;
 		}
+	} else if (report_mount(fp, id, NULL, &oid, form,
+				XFS_PROJ_QUOTA, mount,
+				flags|GETNEXTQUOTA_FLAG)) {
+		id = oid + 1;
+		flags |= GETNEXTQUOTA_FLAG;
+		flags |= NO_HEADER_FLAG;
+		while (report_mount(fp, id, NULL, &oid, form, XFS_PROJ_QUOTA,
+				    mount, flags)) {
+			id = oid + 1;
+		}
 	} else {
 		setprent();
 		while ((p = getprent()) != NULL) {
-- 
1.7.1

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-01-22  4:28 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-01-22  4:27 [PATCH 0/3] xfsprogs: use Q_XGETNEXTQUOTA Eric Sandeen
2016-01-22  4:27 ` [PATCH 1/3] xfs_quota: define Q_XGETNEXTQUOTA Eric Sandeen
2016-01-22  4:28 ` [PATCH 2/3] xfs_quota: make report_mount() & dump_file() take an "output id" Eric Sandeen
2016-01-22  4:28 ` [PATCH 3/3] xfs_quota: use Q_XGETNEXTQUOTA for report and dump Eric Sandeen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox