Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 15 Jul 1999 16:45:10 +0100
From:      Ian Dowse <iedowse@maths.tcd.ie>
To:        Jan Conrad <conrad@th.physik.uni-bonn.de>
Cc:        freebsd-hackers@freebsd.org
Subject:   Re: NFS problems due to getcwd/realpath 
Message-ID:   <199907151645.aa25796@salmon.maths.tcd.ie>
In-Reply-To: Your message of "Thu, 15 Jul 1999 14:10:52 %2B0200." <Pine.BSF.4.10.9907151329040.9501-100000@merlin.th.physik.uni-bonn.de> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <Pine.BSF.4.10.9907151329040.9501-100000@merlin.th.physik.uni-bonn.d
e>, Jan Conrad writes:
>after wondering for two years why FreeBSD (2.2.x ... 3.2) might lock up
>when an NFS server is down, I think I have found one reason for that (see
>kern/12609 - I now know it doesn't belong to kern - sorry).
>
>It is the implementation of getcwd (src/lib/libc/gen/getcwd.c). When
>examining the parent dir of a mounted filesystem, getcwd lstats every
>directory entry prior to the mountpoint to find out the name of the
>mountpoint (but it would only need the inodes's device to do a rough 
>check....).

This should no longer be an issue with FreeBSD 3.x, as the system normally
uses the new _getcwd syscall. The old code is still in getcwd.c, but is
only used if the syscall isn't present (e.g. if running a 3.x executable
on a 2.2 system).

We use the following patch on all our 2.2-stable machines, which works
around the problem. This was submitted as PR bin/6658, but it wasn't
committed, as a backport of 3.x's _getcwd (which never occurred) was
considered to be a more appropriate change.

Ian

--- getcwd.c.orig	Tue Jun 30 15:38:44 1998
+++ getcwd.c	Tue Jun 30 15:39:08 1998
@@ -36,6 +36,7 @@
 #endif /* LIBC_SCCS and not lint */
 
 #include <sys/param.h>
+#include <sys/mount.h>
 #include <sys/stat.h>
 
 #include <errno.h>
@@ -169,7 +170,28 @@
 				if (dp->d_fileno == ino)
 					break;
 			}
-		} else
+		} 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,7 +209,9 @@
 				if (s.st_dev == dev && s.st_ino == ino)
 					break;
 			}
+		}
 
+found:
 		/*
 		 * Check for length of the current name, preceding slash,
 		 * leading slash.


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <199907151645.aa25796>