Date: Fri, 18 Dec 1998 01:25:02 +1100 From: Bruce Evans <bde@zeta.org.au> To: freebsd-scsi@FreeBSD.ORG, swjeong@net.kitel.co.kr Subject: Re: kernel panic with ufsspec_write Message-ID: <199812171425.BAA27006@godzilla.zeta.org.au>
next in thread | raw e-mail | index | archive | help
>... >(kgdb) l 1842,1863 >1837 >1838 uio = ap->a_uio; >1839 resid = uio->uio_resid; >1840 >1841 if (VTOI(ap->a_vp) == NULL) /* work around */ >1842 { >1843 printf("ufsspec_write would panic at point A\n"); >1844 return EFAULT; >1845 } >1846 >1847 error = VOCALL(spec_vnodeop_p, VOFFSET(vop_write), ap); >1848 >1849 >1850 >1851 if (VTOI(ap->a_vp) == NULL) /* work around */ >1852 { >1853 printf("ufsspec_write would panic at point B\n"); >1854 return EFAULT; >1855 } >1857 >1858 >1859 >1860 if (uio->uio_resid != resid) >1861 VTOI(ap->a_vp)->i_flag |= IN_CHANGE | IN_UPDATE; >1862 return (error); >1863 } >(kgdb) p *ap->a_vp >$1 = {v_flag = 8, v_usecount = 1, v_writecount = 1, v_holdcnt = 0, > v_lastr = 0, v_id = 205016, v_mount = 0x0, v_op = 0xf19d4100, v_freelist = { > tqe_next = 0x0, tqe_prev = 0xf6145520}, v_mntvnodes = { > le_next = 0xf61a5ea0, le_prev = 0xf61a11e8}, v_cleanblkhd = { > lh_first = 0x0}, v_dirtyblkhd = {lh_first = 0x0}, v_synclist = { > le_next = 0x0, le_prev = 0xf19b7484}, v_numoutput = 0, v_type = VBAD, > v_un = {vu_mountedhere = 0x0, vu_socket = 0x0, vu_specinfo = 0x0, > vu_fifoinfo = 0x0}, v_lease = 0x0, v_lastw = 0, v_cstart = 0, v_lasta = 0, > v_clen = 0, v_maxio = 0, v_object = 0x0, v_interlock = {lock_data = 0}, > v_vnlock = 0x0, v_tag = VT_NON, v_data = 0x0, v_cache_src = { > lh_first = 0x0}, v_cache_dst = {tqh_first = 0x0, tqh_last = 0xf60202fc}, > v_dd = 0xf6020280, v_ddid = 0, v_pollinfo = {vpi_lock = {lock_data = 0}, > vpi_selinfo = {si_pid = 0, si_flags = 0}, vpi_events = 0, vpi_revents = 0}} >(kgdb) > >Note that v_data is NULL. This caused panic at line 1861 (originaly 1842). Also note that v_type is VBAD. >I made work around for this panic by putting ap->a_vp->v_data checking. >Always point B is excuted and, point A was never executed. >During 24 hours, point B was executed 3 times. >There was about thirty outgoing rlogin users. And kernel configuration >contained 'pseudo-device pty 64'. and there existed corresponding >pseudo terminal device. This is caused by revoke() of an active device. It is easiest to demonstrate for reads since reads are more likely to block: on ttyv0 on ttyv1 on ttyv2 $ cat /dev/ttypN [waits] $ cat >/dev/ptypN 1 1 % revoke /dev/ttypN [hangs] 2 ["2" is not read -- revoke has partially completed] ^C [panic in ufsspec_read] ddb> set $eip=$eip+4 # fix problem using ddb :-) ddb> continue $ $ $ The vnode is half gone when VOCALL() in ufsspec_READ() returns. revoke() is apparently waiting for it to be fully gone. I think revoke() should do more to attempt to terminate outstanding i/o so that it doesn't block, but your workaround is the correct fix for cases where it does block. I/o routines are apparently supposed to allow for the vnode's fs changing to deadfs underneath them! Bruce To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-scsi" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199812171425.BAA27006>