summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjkar8572 <jkar8572>2001-09-25 15:56:59 +0000
committerjkar8572 <jkar8572>2001-09-25 15:56:59 +0000
commit48448ca24e00e530e59d774bfdb3c2a76616330c (patch)
treee4d9c17dbb086945bfa1acc59e5d0bba1156f211
parentd9b70c744b212ede06d4487e134c9aaca084e037 (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.h1
-rw-r--r--quotaio_v1.c7
-rw-r--r--quotaio_v2.c4
-rw-r--r--quotasys.c23
-rw-r--r--repquota.c66
5 files changed, 89 insertions, 12 deletions
diff --git a/quotaio.h b/quotaio.h
index 79e7ce0..16c6f4a 100644
--- a/quotaio.h
+++ b/quotaio.h
@@ -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);
diff --git a/quotasys.c b/quotasys.c
index b76cf23..d74ca30 100644
--- a/quotasys.c
+++ b/quotasys.c
@@ -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 */
diff --git a/repquota.c b/repquota.c
index 749c6b4..b4eac62 100644
--- a/repquota.c
+++ b/repquota.c
@@ -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);