vger still blocks my default domain, so I hope this forward via thundebird from another domain will get thru and patch won't get corrupted. --- Treść przekazanej wiadomości --- Temat: [PATCH] xfs_quota: Support XFS_GETNEXTQUOTA in range calls Data: Thu, 9 Dec 2021 13:39:34 +0100 Nadawca: Arkadiusz Miśkiewicz <arekm@xxxxxxxx> Adresat: linux-xfs@xxxxxxxxxxxxxxx Kopia: Arkadiusz Miśkiewicz <arekm@xxxxxxxx> Use XFS_GETNEXTQUOTA in range call with -L/-U limits. This makes them perform very fast comparing to current iteration over each (existing and not existing) ID. dump_file() and report_mount() take upper agrument which is taken into account only when GETNEXTQUOTA_MATCH_FLAG is requested and don't print anything if upper limit is crossed. Signed-off-by: Arkadiusz Miśkiewicz <arekm@xxxxxxxx> --- quota/quota.h | 1 + quota/report.c | 118 ++++++++++++++++++++++++++++++------------------- 2 files changed, 74 insertions(+), 45 deletions(-) diff --git a/quota/quota.h b/quota/quota.h index 78b0d66d..310812f4 100644 --- a/quota/quota.h +++ b/quota/quota.h @@ -65,6 +65,7 @@ enum { 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 */ + GETNEXTQUOTA_MATCH_FLAG = 0x1000, /* report only if matches range */ }; /* diff --git a/quota/report.c b/quota/report.c index 6ac55490..39b5286b 100644 --- a/quota/report.c +++ b/quota/report.c @@ -65,6 +65,7 @@ static int dump_file( FILE *fp, uint id, + uint upper, uint *oid, uint type, char *dev, @@ -91,6 +92,9 @@ dump_file( /* Did kernelspace wrap? */ if (*oid < id) return 0; + /* Range limit was requested */ + if (flags & GETNEXTQUOTA_MATCH_FLAG && *oid > upper) + return 0; } if (!d.d_blk_softlimit && !d.d_blk_hardlimit && @@ -137,29 +141,36 @@ 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, 0); - return; - } + /* Range was specified */ + if (lower) + id = lower; /* Use GETNEXTQUOTA if it's available */ - if (dump_file(fp, id, &oid, type, mount->fs_name, GETNEXTQUOTA_FLAG)) { + if (dump_file(fp, id, upper, &oid, type, mount->fs_name, + GETNEXTQUOTA_FLAG|GETNEXTQUOTA_MATCH_FLAG)) { id = oid + 1; - while (dump_file(fp, id, &oid, type, mount->fs_name, - GETNEXTQUOTA_FLAG)) + while (dump_file(fp, id, upper, &oid, type, mount->fs_name, + GETNEXTQUOTA_FLAG|GETNEXTQUOTA_MATCH_FLAG)) id = oid + 1; return; } /* Otherwise fall back to iterating over each uid/gid/prjid */ + + /* Range was specified; query everything in it */ + if (upper) { + for (id = lower; id <= upper; id++) + dump_file(fp, id, 0, NULL, type, mount->fs_name, 0); + return; + } + + /* No range */ switch (type) { case XFS_GROUP_QUOTA: { struct group *g; setgrent(); while ((g = getgrent()) != NULL) - dump_file(fp, g->gr_gid, NULL, type, + dump_file(fp, 0, g->gr_gid, NULL, type, mount->fs_name, 0); endgrent(); break; @@ -168,7 +179,7 @@ dump_limits_any_type( struct fs_project *p; setprent(); while ((p = getprent()) != NULL) - dump_file(fp, p->pr_prid, NULL, type, + dump_file(fp, 0, p->pr_prid, NULL, type, mount->fs_name, 0); endprent(); break; @@ -177,7 +188,7 @@ dump_limits_any_type( struct passwd *u; setpwent(); while ((u = getpwent()) != NULL) - dump_file(fp, u->pw_uid, NULL, type, + dump_file(fp, 0, u->pw_uid, NULL, type, mount->fs_name, 0); endpwent(); break; @@ -322,6 +333,7 @@ static int report_mount( FILE *fp, uint32_t id, + uint32_t upper, char *name, uint32_t *oid, uint form, @@ -355,6 +367,9 @@ report_mount( /* Did kernelspace wrap? */ if (* oid < id) return 0; + /* Upper range was specified */ + if (upper && * oid > upper) + return 0; } if (flags & TERSE_FLAG) { @@ -479,26 +494,31 @@ report_user_mount( struct passwd *u; uint id = 0, oid; - if (upper) { /* identifier range specified */ - for (id = lower; id <= upper; id++) { - if (report_mount(fp, id, NULL, NULL, - form, XFS_USER_QUOTA, mount, flags)) - flags |= NO_HEADER_FLAG; - } - } else if (report_mount(fp, id, NULL, &oid, form, + /* Range was specified */ + if (lower) + id = lower; + if (upper) + flags |= GETNEXTQUOTA_MATCH_FLAG; + + if (report_mount(fp, id, upper, 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)) { + while (report_mount(fp, id, upper, NULL, &oid, form, XFS_USER_QUOTA, + mount, flags)) id = oid + 1; + } else if (upper) { /* identifier range specified */ + for (id = lower; id <= upper; id++) { + if (report_mount(fp, id, upper, 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, NULL, + if (report_mount(fp, u->pw_uid, 0, u->pw_name, NULL, form, XFS_USER_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } @@ -521,26 +541,30 @@ report_group_mount( struct group *g; uint id = 0, oid; - if (upper) { /* identifier range specified */ - for (id = lower; id <= upper; id++) { - if (report_mount(fp, id, NULL, NULL, - form, XFS_GROUP_QUOTA, mount, flags)) - flags |= NO_HEADER_FLAG; - } - } else if (report_mount(fp, id, NULL, &oid, form, - XFS_GROUP_QUOTA, mount, + /* Range was specified */ + if (lower) + id = lower; + if (upper) + flags |= GETNEXTQUOTA_MATCH_FLAG; + + if (report_mount(fp, id, upper, 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)) { + while (report_mount(fp, id, upper, NULL, &oid, form, XFS_GROUP_QUOTA, + mount, flags)) id = oid + 1; + } else if (upper) { /* identifier range specified */ + for (id = lower; id <= upper; id++) { + if (report_mount(fp, id, upper, 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, NULL, + if (report_mount(fp, g->gr_gid, 0, g->gr_name, NULL, form, XFS_GROUP_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } @@ -562,21 +586,25 @@ report_project_mount( fs_project_t *p; uint id = 0, oid; - if (upper) { /* identifier range specified */ - for (id = lower; id <= upper; id++) { - if (report_mount(fp, id, NULL, NULL, - form, XFS_PROJ_QUOTA, mount, flags)) - flags |= NO_HEADER_FLAG; - } - } else if (report_mount(fp, id, NULL, &oid, form, - XFS_PROJ_QUOTA, mount, + /* Range was specified */ + if (lower) + id = lower; + if (upper) + flags |= GETNEXTQUOTA_MATCH_FLAG; + + if (report_mount(fp, id, upper, 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)) { + while (report_mount(fp, id, upper, NULL, &oid, form, XFS_PROJ_QUOTA, + mount, flags)) id = oid + 1; + } else if (upper) { /* identifier range specified */ + for (id = lower; id <= upper; id++) { + if (report_mount(fp, id, upper, NULL, NULL, + form, XFS_PROJ_QUOTA, mount, flags)) + flags |= NO_HEADER_FLAG; } } else { if (!getprprid(0)) { @@ -584,14 +612,14 @@ report_project_mount( * Print default project quota, even if projid 0 * isn't defined */ - if (report_mount(fp, 0, NULL, NULL, + if (report_mount(fp, 0, 0, NULL, NULL, form, XFS_PROJ_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } setprent(); while ((p = getprent()) != NULL) { - if (report_mount(fp, p->pr_prid, p->pr_name, NULL, + if (report_mount(fp, p->pr_prid, 0, p->pr_name, NULL, form, XFS_PROJ_QUOTA, mount, flags)) flags |= NO_HEADER_FLAG; } -- 2.33.1