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.