diff options
author | jkar8572 <jkar8572> | 2001-09-25 15:56:59 +0000 |
---|---|---|
committer | jkar8572 <jkar8572> | 2001-09-25 15:56:59 +0000 |
commit | 48448ca24e00e530e59d774bfdb3c2a76616330c (patch) | |
tree | e4d9c17dbb086945bfa1acc59e5d0bba1156f211 | |
parent | d9b70c744b212ede06d4487e134c9aaca084e037 (diff) |
repquota now buffers entries to be printed when resolving is needed (major speedup).
Workaround for bug in RH 7.1 kernel (Anders Blomdell)
-rw-r--r-- | quotaio.h | 1 | ||||
-rw-r--r-- | quotaio_v1.c | 7 | ||||
-rw-r--r-- | quotaio_v2.c | 4 | ||||
-rw-r--r-- | quotasys.c | 23 | ||||
-rw-r--r-- | repquota.c | 66 |
5 files changed, 89 insertions, 12 deletions
@@ -104,6 +104,7 @@ struct util_dqblk { }; #define DQ_FOUND 0x01 /* Dquot was found in the edquotas file */ +#define DQ_PRINTED 0x02 /* Dquota has been already printed by repquota */ /* Structure for one loaded quota */ struct dquot { diff --git a/quotaio_v1.c b/quotaio_v1.c index db09199..4792c53 100644 --- a/quotaio_v1.c +++ b/quotaio_v1.c @@ -34,7 +34,7 @@ #ident "$Copyright: (c) 1980, 1990 Regents of the University of California. $" #ident "$Copyright: All rights reserved. $" -#ident "$Id: quotaio_v1.c,v 1.8 2001/08/22 21:17:56 jkar8572 Exp $" +#ident "$Id: quotaio_v1.c,v 1.9 2001/09/25 15:56:59 jkar8572 Exp $" #include <unistd.h> #include <errno.h> @@ -286,7 +286,7 @@ static int v1_commit_dquot(struct dquot *dquot) static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct dquot *, char *)) { int rd, scanbufpos = 0, scanbufsize = 0; - char name[MAXNAMELEN], scanbuf[sizeof(struct v1_disk_dqblk)*SCANBUFSIZE]; + char scanbuf[sizeof(struct v1_disk_dqblk)*SCANBUFSIZE]; struct v1_disk_dqblk *ddqblk; struct dquot *dquot = get_empty_dquot(); qid_t id = 0; @@ -316,8 +316,7 @@ static int v1_scan_dquots(struct quota_handle *h, int (*process_dquot) (struct d continue; v1_disk2memdqblk(&dquot->dq_dqb, ddqblk); dquot->dq_id = id; - id2name(dquot->dq_id, h->qh_type, name); - if ((rd = process_dquot(dquot, name)) < 0) { + if ((rd = process_dquot(dquot, NULL)) < 0) { free(dquot); return rd; } diff --git a/quotaio_v2.c b/quotaio_v2.c index 76a3681..cd0d3c4 100644 --- a/quotaio_v2.c +++ b/quotaio_v2.c @@ -662,7 +662,6 @@ static int report_block(struct dquot *dquot, uint blk, char *bitmap, dqbuf_t buf = getdqbuf(); struct v2_disk_dqdbheader *dh; struct v2_disk_dqblk *ddata; - char name[MAXNAMELEN]; int entries, i; set_bit(bitmap, blk); @@ -674,8 +673,7 @@ static int report_block(struct dquot *dquot, uint blk, char *bitmap, if (!empty_dquot(ddata + i)) { v2_disk2memdqblk(&dquot->dq_dqb, ddata + i); dquot->dq_id = __le32_to_cpu(ddata[i].dqb_id); - id2name(dquot->dq_id, dquot->dq_h->qh_type, name); - if (process_dquot(dquot, name) < 0) + if (process_dquot(dquot, NULL) < 0) break; } freedqbuf(buf); @@ -481,8 +481,27 @@ int kern_quota_format(void) else if (quotactl(QCMD(Q_GETSTATS, 0), NULL, 0, (void *)&stats) < 0) { if (errno == ENOSYS || errno == ENOTSUP) /* Quota not compiled? */ return QF_ERROR; - if (errno == EINVAL || errno == EFAULT || errno == EPERM) /* Old quota compiled? */ - return ret | (1 << QF_VFSOLD); + if (errno == EINVAL || errno == EFAULT || errno == EPERM) { /* Old quota compiled? */ + /* RedHat 7.1 (2.4.2-2) newquota check + * Q_GETSTATS in it's old place, Q_GETQUOTA in the new place + * (they haven't moved Q_GETSTATS to its new value) */ + int err_stat = 0; + int err_quota = 0; + char tmp[1024]; /* Just temporary buffer */ + + if (quotactl(QCMD(Q_V1_GETSTATS, 0), NULL, 0, (void *)&stats)) + err_stat = errno; + if (quotactl(QCMD(Q_V1_GETQUOTA, 0), "", 0, tmp)) + err_quota = errno; + + /* On a RedHat 2.4.2-2 we expect 0, EINVAL + * On a 2.4.x we expect 0, ENOENT + * On a 2.4.x-ac we wont get here */ + if (err_stat == 0 && err_quota == EINVAL) + return ret | (1 << QF_VFSV0); /* New format supported */ + else + return ret | (1 << QF_VFSOLD); + } die(4, _("Error while detecting kernel quota version: %s\n"), strerror(errno)); } /* We might do some more generic checks in future but this should be enough for now */ @@ -13,6 +13,8 @@ #include <string.h> #include <time.h> #include <errno.h> +#include <pwd.h> +#include <grp.h> #include "pot.h" #include "common.h" @@ -20,6 +22,7 @@ #include "quotaio.h" #define PRINTNAMELEN 9 /* Number of characters to be reserved for name on screen */ +#define MAX_CACHE_DQUOTS 1024 /* Number of dquots in cache */ #define FL_USER 1 #define FL_GROUP 2 @@ -31,6 +34,8 @@ int flags, fmt = -1; char **mnt; int mntcnt; +int cached_dquots; +struct dquot dquot_cache[MAX_CACHE_DQUOTS]; char *progname; static void usage(void) @@ -107,7 +112,7 @@ static char overlim(uint usage, uint softlim, uint hardlim) return '-'; } -static int print(struct dquot *dquot, char *name) +static void print(struct dquot *dquot, char *name) { char pname[MAXNAMELEN]; char time[MAXTIMELEN]; @@ -116,7 +121,7 @@ static int print(struct dquot *dquot, char *name) struct util_dqblk *entry = &dquot->dq_dqb; if (!entry->dqb_curspace && !entry->dqb_curinodes && !(flags & FL_VERBOSE)) - return 0; + return; sstrncpy(pname, name, sizeof(pname)); if (flags & FL_TRUNCNAMES) pname[PRINTNAMELEN] = 0; @@ -133,6 +138,60 @@ static int print(struct dquot *dquot, char *name) number2str(entry->dqb_isoftlimit, numbuf[1], flags & FL_SHORTNUMS); number2str(entry->dqb_ihardlimit, numbuf[2], flags & FL_SHORTNUMS); printf(" %7s %5s %5s %6s\n", numbuf[0], numbuf[1], numbuf[2], time); +} + +/* Print all dquots in the cache */ +static void dump_cached_dquots(int type) +{ + int i; + char namebuf[MAXNAMELEN]; + + if (!cached_dquots) + return; + if (type == USRQUOTA) { + struct passwd *pwent; + + setpwent(); + while ((pwent = getpwent())) { + for (i = 0; i < cached_dquots && pwent->pw_uid != dquot_cache[i].dq_id; i++); + if (i < cached_dquots) { + print(dquot_cache+i, pwent->pw_name); + dquot_cache[i].dq_flags |= DQ_PRINTED; + } + } + endpwent(); + } + else { + struct group *grent; + + setgrent(); + while ((grent = getgrent())) { + for (i = 0; i < cached_dquots && grent->gr_gid != dquot_cache[i].dq_id; i++); + if (i < cached_dquots) { + print(dquot_cache+i, grent->gr_name); + dquot_cache[i].dq_flags |= DQ_PRINTED; + } + } + endgrent(); + } + for (i = 0; i < cached_dquots; i++) + if (!(dquot_cache[i].dq_flags & DQ_PRINTED)) { + sprintf(namebuf, "#%u", dquot_cache[i].dq_id); + print(dquot_cache+i, namebuf); + } + cached_dquots = 0; +} + +static int output(struct dquot *dquot, char *name) +{ + + if (name) + print(dquot, name); + else { + memcpy(dquot_cache+cached_dquots++, dquot, sizeof(struct dquot)); + if (cached_dquots >= MAX_CACHE_DQUOTS) + dump_cached_dquots(dquot->dq_h->qh_type); + } return 0; } @@ -148,8 +207,9 @@ static void report_it(struct quota_handle *h, int type) printf(_("%-9s used soft hard grace used soft hard grace\n"), (type == USRQUOTA)?_("User"):_("Group")); printf("----------------------------------------------------------------------\n"); - if (h->qh_ops->scan_dquots(h, print) < 0) + if (h->qh_ops->scan_dquots(h, output) < 0) return; + dump_cached_dquots(type); if (h->qh_ops->report) { putchar('\n'); h->qh_ops->report(h, flags & FL_VERBOSE); |