Date: Wed, 27 Oct 1999 10:27:42 -0700 (PDT) From: Matthew Dillon <dillon@apollo.backplane.com> To: Alexander Bezroutchko <abb@zenon.net> Cc: freebsd-hackers@FreeBSD.ORG Subject: Re: lookup() deadlock in 3.3-stable ? Message-ID: <199910271727.KAA27499@apollo.backplane.com> References: <3817008F.4779686C@zenon.net>
next in thread | previous in thread | raw e-mail | index | archive | help
:Hi : :I have box running 3.3-STABLE which locks up several times per day. :After system hangs, ps command in DDB displays a lot of processes :in "inode" state. I suspect deadlock occurs: : : process 45676 unlink("msg/..") : holds lock to "msg" : tries to acquire lock to "msg/..", i.e. "." : : process 45678 stat("msg") : holds lock to "." : tries to acquire lock to "msg" : :How-To-Repeat: : 1. create test directory: : mkdir t : 2. run first process : perl -e 'for(;;) { stat("t") || die }' : 3. run second process : perl -e 'for(;;) { unlink("t/..") || die }' : 4. run disk-bound process (one or move) : find / > /dev/null : :I have kernel core and ready to provide additional information. Well, the system isn't supposed to lockup so this is a bug. It's because ufs_lookup isn't expecting someone to try to delete (or rename for that matter) ".." and so is not doing the normal lock fixups required when traversing "..". Please try the following untested patch. If it works for you I'll commit it into both -current and -stable. -Matt Index: ufs_lookup.c =================================================================== RCS file: /home/ncvs/src/sys/ufs/ufs/ufs_lookup.c,v retrieving revision 1.26.2.1 diff -u -r1.26.2.1 ufs_lookup.c --- ufs_lookup.c 1999/08/29 16:33:22 1.26.2.1 +++ ufs_lookup.c 1999/10/27 17:25:27 @@ -452,7 +452,11 @@ *vpp = vdp; return (0); } + if (flags & ISDOTDOT) + VOP_UNLOCK(vdp, 0, p); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp); + if (flags & ISDOTDOT) + vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p); if (error) return (error); /* @@ -481,7 +485,7 @@ * regular file, or empty directory. */ if (nameiop == RENAME && wantparent && (flags & ISLASTCN)) { - if (error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) + if ((error = VOP_ACCESS(vdp, VWRITE, cred, cnp->cn_proc)) != 0) return (error); /* * Careful about locking second inode. @@ -489,7 +493,11 @@ */ if (dp->i_number == dp->i_ino) return (EISDIR); + if (flags & ISDOTDOT) + VOP_UNLOCK(vdp, 0, p); /* race to get the inode */ error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp); + if (flags & ISDOTDOT) + vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p); if (error) return (error); *vpp = tdp; To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199910271727.KAA27499>