Hi, I've created a patch that increases the performance of mtree. This is of particular use during a port install. In an extreme case I have experienced a ~20% increase [1].
For a full discussion see PR bin/143732. This arose out of [2] where I experienced the increase. For your convenience I have attached the patch. Please review this patch and if it is acceptable, commit it. Regards, David 1] http://markmail.org/message/iju3l6hyv7s7emrb 2] http://markmail.org/message/gfztjpszl5dozzii
--- /usr/src/usr.sbin/mtree/verify.c 2010-02-07 15:07:28.000000000 +0200
+++ verify.c 2010-02-07 15:04:10.000000000 +0200
@@ -50,17 +50,23 @@
static NODE *root;
static char path[MAXPATHLEN];
-static void miss(NODE *, char *);
+static int miss(NODE *, char *);
+static int check(NODE *, char *);
static int vwalk(void);
int
mtree_verifyspec(FILE *fi)
{
- int rval;
+ int rval = 0;
root = mtree_readspec(fi);
- rval = vwalk();
- miss(root, path);
+ /*
+ * No need to walk entire tree if we are only updating the structure
+ * and extra files are ignored.
+ */
+ if (!(uflag && eflag))
+ rval = vwalk();
+ rval |= miss(root, path);
return (rval);
}
@@ -155,15 +161,47 @@
return (rval);
}
-static void
+static int
+check(NODE *p, char *tail)
+{
+ FTSENT fts;
+ struct stat fts_stat;
+
+ strcpy(tail, p->name);
+
+ /*
+ * It is assumed that compare() only requires fts_accpath and fts_statp
+ * fields in the FTSENT structure.
+ */
+ fts.fts_accpath = path;
+ fts.fts_statp = &fts_stat;
+
+ if (stat(path, fts.fts_statp))
+ return (0);
+
+ p->flags |= F_VISIT;
+ if ((p->flags & F_NOCHANGE) == 0 && compare(p->name, p, &fts))
+ return (MISMATCHEXIT);
+ else
+ return (0);
+
+ /*
+ * tail is not restored to '\0' as the next time tail (or path) is used
+ * is with a strcpy (thus overriding the '\0'). See +19 lines below.
+ */
+}
+
+static int
miss(NODE *p, char *tail)
{
int create;
char *tp;
const char *type, *what;
- int serr;
+ int serr, rval = 0;
for (; p; p = p->next) {
+ if (uflag && eflag)
+ rval |= check(p, tail);
if (p->flags & F_OPT && !(p->flags & F_VISIT))
continue;
if (p->type != F_DIR && (dflag || p->flags & F_VISIT))
@@ -256,4 +294,5 @@
(void)printf("%s: file flags not set: %s\n",
path, strerror(errno));
}
+ return (rval);
}
signature.asc
Description: This is a digitally signed message part.

