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>