From: Eric Sandeen Date: Thu, 4 Feb 2016 21:39:26 +0000 (+1100) Subject: xfs_quota: use Q_XGETNEXTQUOTA for report and dump X-Git-Tag: v4.5.0-rc1~36 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6a9a085e3b4f23ea0d136173f50ca3bb6d1f57d3;p=thirdparty%2Fxfsprogs-dev.git xfs_quota: use Q_XGETNEXTQUOTA for report and dump 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 Reviewed-by: Dave Chinner Signed-off-by: Dave Chinner --- diff --git a/quota/quota.h b/quota/quota.h index 2bbc1764f..4bde35132 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 3085a9e5b..8653134ed 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) {