From iedowse@maths.tcd.ie  Sat May 16 19:38:53 1998
Received: from salmon.maths.tcd.ie (mmdf@salmon.maths.tcd.ie [134.226.81.11])
          by hub.freebsd.org (8.8.8/8.8.8) with SMTP id TAA16404
          for <FreeBSD-gnats-submit@freebsd.org>; Sat, 16 May 1998 19:38:53 -0700 (PDT)
          (envelope-from iedowse@maths.tcd.ie)
Received: from walton.maths.tcd.ie by salmon.maths.tcd.ie with SMTP
          id <aa19575@salmon.maths.tcd.ie>; 17 May 98 03:38:49 +0100 (BST)
Message-Id: <9805170338.aa14317@walton.maths.tcd.ie>
Date: Sun, 17 May 98 03:38:48 +0100 (BST)
From: iedowse@maths.tcd.ie
Sender: iedowse@maths.tcd.ie
Reply-To: iedowse@maths.tcd.ie
To: FreeBSD-gnats-submit@freebsd.org
Subject: -stable getcwd(3) performs unnecessary lstats
X-Send-Pr-Version: 3.2

>Number:         6658
>Category:       bin
>Synopsis:       [PATCH] -stable getcwd(3) performs unnecessary lstats
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Sat May 16 19:40:03 PDT 1998
>Closed-Date:    Wed Jun 28 03:21:28 PDT 2000
>Last-Modified:  Wed Jun 28 03:22:01 PDT 2000
>Originator:     Ian Dowse
>Release:        FreeBSD 2.2.6-STABLE i386
>Organization:
	School of Mathematics,
	Trinity College Dublin
>Environment:

	FreeBSD 2.2.6-STABLE

>Description:
	
	getcwd(3) in -stable does a lot of lstat'ing every time it crosses
	a mount point. This can really slow down its operation if it has
	to lstat nfs disks or slow devices. The usual suggested workaround
	of putting all 'slow' filesystems in separate directories is not
	ideal.

	The path component that getcwd does all these lstats to find can
	virtually always be obtained using statfs(2) at a much lower cost.
	The patch below makes getcwd first try statfs, and then resort to
	the old method if this fails (I'm not convinced that statfs will
	get the correct answer in absolutely every situation).

	This PR can of course be ignored if a getcwd syscall is likely to
	appear soon in -stable.

>How-To-Repeat:

	Run sh with cwd in filesystem /f1 while nfs filesystem /f2 is not
	responding.

>Fix:
	
*** /usr/src/lib/libc/gen/getcwd.c	Thu Mar 26 09:22:48 1998
--- getcwd.c	Sun May 17 03:30:24 1998
***************
*** 36,41 ****
--- 36,42 ----
  #endif /* LIBC_SCCS and not lint */
  
  #include <sys/param.h>
+ #include <sys/mount.h>
  #include <sys/stat.h>
  
  #include <errno.h>
***************
*** 169,175 ****
  				if (dp->d_fileno == ino)
  					break;
  			}
! 		} else
  			for (;;) {
  				if (!(dp = readdir(dir)))
  					goto notfound;
--- 170,193 ----
  				if (dp->d_fileno == ino)
  					break;
  			}
! 		} else {
! 			struct statfs sfs;
! 			char *dirname;
! 
! 			if (!statfs(".", &sfs) &&
! 			    (dirname = rindex(sfs.f_mntonname, '/'))) 
! 				while((dp = readdir(dir))) {
! 					if (ISDOT(dp))
! 						continue;
! 					bcopy(dp->d_name, bup, dp->d_namlen+1);
! 					if (!strcmp(dirname + 1, dp->d_name) &&
! 					    !lstat(up, &s) &&
! 					    s.st_dev == dev &&
! 					    s.st_ino == ino)
! 						goto found;
! 				}
! 			rewinddir(dir);
! 
  			for (;;) {
  				if (!(dp = readdir(dir)))
  					goto notfound;
***************
*** 187,193 ****
--- 205,213 ----
  				if (s.st_dev == dev && s.st_ino == ino)
  					break;
  			}
+ 		}
  
+ found:
  		/*
  		 * Check for length of the current name, preceding slash,
  		 * leading slash.
>Release-Note:
>Audit-Trail:

From: Ian Dowse <iedowse@maths.tcd.ie>
To: freebsd-gnats-submit@freebsd.org
Cc:  Subject: Re: bin/6658: -stable getcwd(3) performs unnecessary lstats 
Date: Sun, 17 May 1998 18:03:16 +0100

 In message <9805170338.aa14317@walton.maths.tcd.ie>, iedowse writes:
 >
 >! 
 >! 			if (!statfs(".", &sfs) &&
 
 Whoops... That of course will only work for the first mount point. The
 corrected patch is below.
 
 Ian
 
 
 *** /usr/src/lib/libc/gen/getcwd.c	Thu Mar 26 09:22:48 1998
 --- getcwd.c	Sun May 17 17:40:25 1998
 ***************
 *** 36,41 ****
 --- 36,42 ----
   #endif /* LIBC_SCCS and not lint */
   
   #include <sys/param.h>
 + #include <sys/mount.h>
   #include <sys/stat.h>
   
   #include <errno.h>
 ***************
 *** 169,175 ****
   				if (dp->d_fileno == ino)
   					break;
   			}
 ! 		} else
   			for (;;) {
   				if (!(dp = readdir(dir)))
   					goto notfound;
 --- 170,197 ----
   				if (dp->d_fileno == ino)
   					break;
   			}
 ! 		} else {
 ! 			struct statfs sfs;
 ! 			char *dirname;
 ! 
 ! 			/*
 ! 			 * Try to get the directory name by using statfs on
 ! 			 * the mount point. 
 ! 			 */
 ! 			if (!statfs(up[3] ? up + 3 : ".", &sfs) &&
 ! 			    (dirname = rindex(sfs.f_mntonname, '/'))) 
 ! 				while((dp = readdir(dir))) {
 ! 					if (ISDOT(dp))
 ! 						continue;
 ! 					bcopy(dp->d_name, bup, dp->d_namlen+1);
 ! 					if (!strcmp(dirname + 1, dp->d_name) &&
 ! 					    !lstat(up, &s) &&
 ! 					    s.st_dev == dev &&
 ! 					    s.st_ino == ino)
 ! 						goto found;
 ! 				}
 ! 			rewinddir(dir);
 ! 
   			for (;;) {
   				if (!(dp = readdir(dir)))
   					goto notfound;
 ***************
 *** 187,193 ****
 --- 209,217 ----
   				if (s.st_dev == dev && s.st_ino == ino)
   					break;
   			}
 + 		}
   
 + found:
   		/*
   		 * Check for length of the current name, preceding slash,
   		 * leading slash.

From: Poul-Henning Kamp <phk@critter.freebsd.dk>
To: Ian Dowse <iedowse@maths.tcd.ie>
Cc: freebsd-bugs@FreeBSD.ORG, freebsd-gnats-submit@FreeBSD.ORG
Subject: Re: bin/6658: -stable getcwd(3) performs unnecessary lstats 
Date: Sun, 17 May 1998 19:27:05 +0200

 Ian, before you spend too much time on this, check out the __getcwd()
 syscall and its use in libc:getcwd() in -current.
 
 --
 Poul-Henning Kamp             FreeBSD coreteam member
 phk@FreeBSD.ORG               "Real hackers run -current on their laptop."
 "ttyv0" -- What UNIX calls a $20K state-of-the-art, 3D, hi-res color terminal
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Tue May 19 02:17:05 PDT 1998 
State-Changed-Why:  
Awaiting -stable committer. 

Seriouly consider pulling the -current change instead. 
State-Changed-From-To: suspended->closed 
State-Changed-By: nbm 
State-Changed-When: Wed Jun 28 03:21:28 PDT 2000 
State-Changed-Why:  
We use the __getcwd syscall since 3.x. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=6658 
>Unformatted:
