From owner-freebsd-bugs Fri Jun 1 22:30:12 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 06E4A37B43C for ; Fri, 1 Jun 2001 22:30:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f525U0p11063; Fri, 1 Jun 2001 22:30:00 -0700 (PDT) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 3913A37B422 for ; Fri, 1 Jun 2001 22:24:49 -0700 (PDT) (envelope-from nobody@FreeBSD.org) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f525OnI10853; Fri, 1 Jun 2001 22:24:49 -0700 (PDT) (envelope-from nobody) Message-Id: <200106020524.f525OnI10853@freefall.freebsd.org> Date: Fri, 1 Jun 2001 22:24:49 -0700 (PDT) From: mwatson@apple.com To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: misc/27829: pax's uid/gid cache is read-only Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org >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