[PATCH 3/3] xfs_quota: use Q_XGETNEXTQUOTA for report and dump

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>
---


(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@xxxxxxxxxxx
http://oss.sgi.com/mailman/listinfo/xfs



[Index of Archives]     [Linux XFS Devel]     [Linux Filesystem Development]     [Filesystem Testing]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux