new panic (was: Re: "busy buffer problem" panics)
Matthew Dillon
dillon at apollo.backplane.com
Wed Sep 8 16:36:56 PDT 2004
:
:Oops, sorry Matt, seem to have misplaced my leaf password ...
:here's a better traceback though - one with line numbers -
:
:...
: tf_eax = -872183968, tf_trapno = 12, tf_err = 0, tf_eip = -1071869799, tf_cs = 8, tf_eflags = 66118,
: tf_esp = -1070839358, tf_ss = -714257964}) at ../../i386/i386/trap.c:613
:#6 0xc01c9099 in lwkt_reltoken (_ref=0xd56d49d4) at ../../kern/lwkt_token.c:408
:#7 0xc01f99f2 in vrele (vp=0xc02c49c2) at ../../kern/vfs_subr.c:1703
:#8 0xc03366e9 in linux_copyin_path (uname=0x80a0017 "/etc/ld.so.conf", kname=0xd56d4bac, flags=2)
: at ../../emulation/linux/linux_util.c:119
:#9 0xc032e28d in linux_open (args=0xd56d4c38) at ../../emulation/linux/linux_file.c:101
:#10 0xc036368a in syscall2 (frame={tf_fs = 47, tf_es = 47, tf_ds = 47, tf_edi = 134951678, tf_esi = 8,
: tf_ebp = -1077937400, tf_isp = -714257036, tf_ebx = 134873111, tf_edx = 438, tf_ecx = 0, tf_eax = 5,
: tf_trapno = 12, tf_err = 2, tf_eip = 134601853, tf_cs = 31, tf_eflags = 582, tf_esp = -1077937496,
: tf_ss = 47}) at ../../i386/i386/trap.c:1350
:#11 0xc03553da in Xint0x80_syscall ()
:#12 0x8051316 in ?? ()
:#13 0x80499ba in ?? ()
:#14 0x80484c4 in ?? ()
:#15 0x804c1eb in ?? ()
:(kgdb) quit
It can't be line 119 of linux_util.c, that's in the middle of a comment
if you are using the patch I posted. If you are not using the patch
I posted then you need to try the patch.
I've included it again below. This one also contains some linprocfs
fixes in addition to the original linux_util.c patch. Make sure you
are running a kernel with this patch and see if it panics... if it
does, get a another core dump and backtrace (and hopefully it won't list
a line number that is in the middle of a comment).
-Matt
Matthew Dillon
<dillon at 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
Index: i386/linprocfs/linprocfs_vnops.c
===================================================================
RCS file: /cvs/src/sys/emulation/linux/i386/linprocfs/linprocfs_vnops.c,v
retrieving revision 1.16
diff -u -r1.16 linprocfs_vnops.c
--- i386/linprocfs/linprocfs_vnops.c 17 Aug 2004 18:57:32 -0000 1.16
+++ i386/linprocfs/linprocfs_vnops.c 4 Sep 2004 04:16:50 -0000
@@ -632,13 +632,8 @@
}
/*
- * lookup. this is incredibly complicated in the
- * general case, however for most pseudo-filesystems
- * very little needs to be done.
- *
- * unless you want to get a migraine, just make sure your
- * filesystem doesn't do any locking of its own. otherwise
- * read and inwardly digest ufs_lookup().
+ * lookup. this is incredibly complicated in the general case, however
+ * for most pseudo-filesystems very little needs to be done.
*/
static int
linprocfs_lookup(ap)
@@ -657,6 +652,7 @@
struct pfsnode *pfs;
struct proc *p;
int i;
+ int error;
*vpp = NULL;
@@ -666,11 +662,12 @@
return (EROFS);
}
+ error = 0;
+
if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp;
- vref(dvp);
- /* vn_lock(dvp, NULL, LK_EXCLUSIVE | LK_RETRY, curp); */
- return (0);
+ vref(*vpp);
+ goto out;
}
pfs = VTOPFS(dvp);
@@ -679,20 +676,34 @@
if (cnp->cn_flags & CNP_ISDOTDOT)
return (EIO);
- if (CNEQ(cnp, "self", 4))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pself));
- if (CNEQ(cnp, "meminfo", 7))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmeminfo));
- if (CNEQ(cnp, "cpuinfo", 7))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo));
- if (CNEQ(cnp, "stat", 4))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pstat));
- if (CNEQ(cnp, "uptime", 6))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Puptime));
- if (CNEQ(cnp, "version", 7))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Pversion));
- if (CNEQ(cnp, "loadavg", 7))
- return (linprocfs_allocvp(dvp->v_mount, vpp, 0, Ploadavg));
+ if (CNEQ(cnp, "self", 4)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pself);
+ goto out;
+ }
+ if (CNEQ(cnp, "meminfo", 7)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pmeminfo);
+ goto out;
+ }
+ if (CNEQ(cnp, "cpuinfo", 7)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pcpuinfo);
+ goto out;
+ }
+ if (CNEQ(cnp, "stat", 4)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pstat);
+ goto out;
+ }
+ if (CNEQ(cnp, "uptime", 6)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Puptime);
+ goto out;
+ }
+ if (CNEQ(cnp, "version", 7)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Pversion);
+ goto out;
+ }
+ if (CNEQ(cnp, "loadavg", 7)) {
+ error = linprocfs_allocvp(dvp->v_mount, vpp, 0, Ploadavg);
+ goto out;
+ }
pid = atopid(pname, cnp->cn_namelen);
if (pid == NO_PID)
@@ -702,11 +713,14 @@
if (p == 0)
break;
- return (linprocfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
+ error = linprocfs_allocvp(dvp->v_mount, vpp, pid, Pproc);
+ goto out;
case Pproc:
- if (cnp->cn_flags & CNP_ISDOTDOT)
- return (linprocfs_root(dvp->v_mount, vpp));
+ if (cnp->cn_flags & CNP_ISDOTDOT) {
+ error = linprocfs_root(dvp->v_mount, vpp);
+ goto out;
+ }
p = PFIND(pfs->pfs_pid);
if (p == 0)
@@ -721,14 +735,33 @@
break;
found:
- return (linprocfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
- pt->pt_pfstype));
+ error = linprocfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
+ pt->pt_pfstype);
+ goto out;
default:
- return (ENOTDIR);
+ error = ENOTDIR;
+ goto out;
}
- return (cnp->cn_nameiop == NAMEI_LOOKUP ? ENOENT : EROFS);
+ if (cnp->cn_nameiop == NAMEI_LOOKUP)
+ error = ENOENT;
+ else
+ error = EROFS;
+
+ /*
+ * If no error occured *vpp will hold a referenced locked vnode.
+ * dvp was passed to us locked and *vpp must be returned locked
+ * so if dvp != *vpp and CNP_LOCKPARENT is not set, unlock dvp.
+ */
+out:
+ if (error == 0) {
+ if (*vpp != dvp && (cnp->cn_flags & CNP_LOCKPARENT) == 0) {
+ cnp->cn_flags |= CNP_PDIRUNLOCK;
+ VOP_UNLOCK(dvp, NULL, 0, cnp->cn_td);
+ }
+ }
+ return (error);
}
/*
More information about the Bugs
mailing list