Date: Fri, 1 Jun 2001 22:24:49 -0700 (PDT) From: mwatson@apple.com To: freebsd-gnats-submit@FreeBSD.org Subject: misc/27829: pax's uid/gid cache is read-only Message-ID: <200106020524.f525OnI10853@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 27829
>Category: misc
>Synopsis: pax's uid/gid cache is read-only
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Fri Jun 01 22:30:00 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator: Matt Watson
>Release: 4.2
>Organization:
Apple Computer, Inc.
>Environment:
>Description:
We found a bug in the Darwin pax where the uid/gid cache was not being used correctly. This resulted in a 10x slowdown of archive extraction in some cases. It's especially bad when archives contain unknown uid/gids
>How-To-Repeat:
Run pax under gdb. break on getpwuid() & getpwnam(). Notice how often you hit the breakpoints.
>Fix:
These diffs may need to be modified to sync up with the current version...
Index: cache.c
===================================================================
RCS file: /cvs/Darwin/Commands/BSD/file_cmds/pax/cache.c,v
retrieving revision 1.1
retrieving revision 1.3
diff -w -u -b -r1.1 -r1.3
--- cache.c 1999/04/23 02:39:07 1.1
+++ cache.c 2001/01/16 23:20:28 1.3
@@ -210,14 +210,15 @@
{
register struct passwd *pw;
register UIDC *ptr;
-
+ register int hash;
if ((uidtb == NULL) && (uidtb_start() < 0))
return("");
/*
* see if we have this uid cached
*/
- ptr = uidtb[uid % UID_SZ];
+ hash = uid % UID_SZ;
+ ptr = uidtb[hash];
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->uid == uid)) {
/*
* have an entry for this uid
@@ -252,6 +253,7 @@
(void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
(unsigned long)uid);
# endif
+ uidtb[hash] = ptr;
if (frc == 0)
return("");
} else {
@@ -264,6 +266,7 @@
(void)strncpy(ptr->name, pw->pw_name, UNMLEN-1);
ptr->name[UNMLEN-1] = '\0';
ptr->valid = VALID;
+ uidtb[hash] = ptr;
}
return(ptr->name);
}
@@ -288,6 +291,7 @@
{
register struct group *gr;
register GIDC *ptr;
+ register int hash;
if ((gidtb == NULL) && (gidtb_start() < 0))
return("");
@@ -295,7 +299,8 @@
/*
* see if we have this gid cached
*/
- ptr = gidtb[gid % GID_SZ];
+ hash = gid % GID_SZ;
+ ptr = gidtb[hash];
if ((ptr != NULL) && (ptr->valid > 0) && (ptr->gid == gid)) {
/*
* have an entry for this gid
@@ -330,6 +335,7 @@
(void)snprintf(ptr->name, sizeof(ptr->name), "%lu",
(unsigned long)gid);
# endif
+ gidtb[hash] = ptr;
if (frc == 0)
return("");
} else {
@@ -342,6 +348,7 @@
(void)strncpy(ptr->name, gr->gr_name, GNMLEN-1);
ptr->name[GNMLEN-1] = '\0';
ptr->valid = VALID;
+ gidtb[hash] = ptr;
}
return(ptr->name);
}
@@ -366,6 +373,7 @@
register struct passwd *pw;
register UIDC *ptr;
register int namelen;
+ register int hash;
/*
* return -1 for mangled names
@@ -379,7 +387,8 @@
* look up in hash table, if found and valid return the uid,
* if found and invalid, return a -1
*/
- ptr = usrtb[st_hash(name, namelen, UNM_SZ)];
+ hash = st_hash(name, namelen, UNM_SZ);
+ ptr = usrtb[hash];
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
if (ptr->valid == INVALID)
return(-1);
@@ -405,6 +414,7 @@
*uid = pw->pw_uid;
return(0);
}
+ usrtb[hash] = ptr;
(void)strncpy(ptr->name, name, UNMLEN-1);
ptr->name[UNMLEN-1] = '\0';
if ((pw = getpwnam(name)) == NULL) {
@@ -436,6 +446,7 @@
register struct group *gr;
register GIDC *ptr;
register int namelen;
+ register int hash;
/*
* return -1 for mangled names
@@ -449,7 +460,8 @@
* look up in hash table, if found and valid return the uid,
* if found and invalid, return a -1
*/
- ptr = grptb[st_hash(name, namelen, GID_SZ)];
+ hash = st_hash(name, namelen, GID_SZ);
+ ptr = grptb[hash];
if ((ptr != NULL) && (ptr->valid > 0) && !strcmp(name, ptr->name)) {
if (ptr->valid == INVALID)
return(-1);
@@ -475,6 +487,7 @@
return(0);
}
+ grptb[hash] = ptr;
(void)strncpy(ptr->name, name, GNMLEN-1);
ptr->name[GNMLEN-1] = '\0';
if ((gr = getgrnam(name)) == NULL) {
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200106020524.f525OnI10853>
