看板 DFBSD_bugs 關於我們 聯絡資訊
: :This box is both an nfs client (about 20 static mount points) and a server :(about 5 clients, several mount points), and I'm running amd so it's :automounting on /net a lot, especially during many clearcase operations.=20 : :Not sure if 'cleartool lsact -l' does anything with /net but it is possible. : :I'm thinking that locking in the linuxulator is at the root of this ... : :Andrew. Try this patch with the latest kernel. The failure case is odd, because it looks like the underlying lock is somehow entering the system shutdown code. The code in linux_util appears to have some severe leaks: a vnode reference count leak and a memory leak, which thi s patch fixes. Does running clearcase crash it immediately or does it take a number of runs? For the reference count to be causing the problem, the vnode would have to cycle through 2-4 billion accesses (to wrap the ref count). This is certainly possible, but it would take a while. -Matt Matthew Dillon <dillon@backplane.com> Index: linux_util.c =================================================================== RCS file: /cvs/src/sys/emulation/linux/linux_util.c,v retrieving revision 1.8 diff -u -r1.8 linux_util.c --- linux_util.c 13 Nov 2003 04:04:42 -0000 1.8 +++ linux_util.c 3 Sep 2004 04:49:27 -0000 @@ -74,10 +74,8 @@ length = strlen(linux_emul_path); bcopy(linux_emul_path, buf, length); error = copyinstr(uname, buf + length, MAXPATHLEN - length, &dummy); - if (error) { - linux_free_path(kname); - return (error); - } + if (error) + goto done; switch (flags) { case LINUX_PATH_CREATE: @@ -87,14 +85,20 @@ * the last '/'. */ cp = buf + strlen(buf); - while (*--cp != '/'); - *cp = '\0'; + while (--cp >= buf) { + if (*cp == '/') + break; + } + if (cp < buf) + goto dont_translate; + *cp = 0; NDINIT(&nd, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, buf, td); error = namei(&nd); if (error) goto dont_translate; - + NDFREE(&nd, NDF_ONLY_PNBUF); + vrele(nd.ni_vp); *cp = '/'; return (0); case LINUX_PATH_EXISTS: @@ -119,30 +123,36 @@ NDINIT(&ndroot, NAMEI_LOOKUP, CNP_FOLLOW, UIO_SYSSPACE, linux_emul_path, td); error = namei(&ndroot); - if (error) + if (error) { + NDFREE(&nd, NDF_ONLY_PNBUF); + vrele(nd.ni_vp); goto dont_translate; + } error = VOP_GETATTR(nd.ni_vp, &vat, td); + if (error == 0) { + error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td); + if (error == 0) { + if (vat.va_fsid == vatroot.va_fsid && + vat.va_fileid == vatroot.va_fileid) + error = ENOENT; + } + } + NDFREE(&nd, NDF_ONLY_PNBUF); + vrele(nd.ni_vp); + NDFREE(&ndroot, NDF_ONLY_PNBUF); + vrele(ndroot.ni_vp); if (error) goto dont_translate; - - error = VOP_GETATTR(ndroot.ni_vp, &vatroot, td); - if (error) - goto dont_translate; - - if (vat.va_fsid == vatroot.va_fsid && - vat.va_fileid == vatroot.va_fileid) - goto dont_translate; - return (0); default: - linux_free_path(kname); - return (EINVAL); + error = EINVAL; + goto done; } dont_translate: - error = copyinstr(uname, buf, MAXPATHLEN, &dummy); +done: if (error) linux_free_path(kname); return (error); @@ -176,6 +186,8 @@ error = 0; goto cleanup; } + NDFREE(&nd, NDF_ONLY_PNBUF); + vrele(nd.ni_vp); /* * The alternate path does exist. Return it in the buffer if