看板 DFBSD_bugs 關於我們 聯絡資訊
: :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@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 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); } /*