DragonFly bugs List (threaded) for 2004-09
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
Re: "busy buffer problem" panics
:
: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@xxxxxxxxxxxxx>
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
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]