Date: Fri, 27 Dec 1996 11:33:20 -0500 (EST) From: Bill Paul <wpaul@skynet.ctr.columbia.edu> To: joerg_wunsch@uriah.heep.sax.de Cc: hackers@freebsd.org Subject: Re: [2.2-BETA] NFS hangup! Message-ID: <199612271633.LAA21311@skynet.ctr.columbia.edu> In-Reply-To: <199612270856.JAA03454@uriah.heep.sax.de> from "J Wunsch" at Dec 27, 96 09:56:03 am
next in thread | previous in thread | raw e-mail | index | archive | help
Of all the gin joints in all the towns in all the world, J Wunsch had to walk into mine and say: > As Naoki Hamada wrote: > > > This morning I encountered a sudden hangup and found out what is the > > case. On a NFS imported filesystem, when I execute the following > > sequence, the PC totally hangs up after the `mv' command. > > > > % mkdir -p tmp/tmp > > % mv tmp/tmp . > > I get the dreaded > > panic: nfs: sillyrename dir > > when trying this. (Both, client and server are FreeBSD.) > > Doesn't this ring a bell for somebody? Happens for me too (SunOS 4.1.3 server, FreeBSD client). The offending code is in nfs_vnops.c: static int nfs_sillyrename(dvp, vp, cnp) struct vnode *dvp, *vp; struct componentname *cnp; { register struct sillyrename *sp; struct nfsnode *np; int error; short pid; cache_purge(dvp); np = VTONFS(vp); #ifndef DIAGNOSTIC if (vp->v_type == VDIR) panic("nfs: sillyrename dir"); #endif It's basically disallowing sillyrenames for directories. If you compile with options DIAGNOSTIC it looks like the problem is hidden; this doesn't look like the right thing to do though. With SunOS, I get: mv: tmp/tmp: rename: Directory not empty Looking at our code, it seems that the client will attempt a sillyrename in nfs_rename() if the 'destination' vnode exists is in use. The 2.1.0 code didn't do this (which I guess is a bug if you're renaming foo to bar, and foo and bar are both files, and bar exists and is still being referenced by someone). (Of course none of this crap works if you have two client machines, and a process on one host unlinks bar while a process on the other host has a reference to bar, but that's NFS for you.) The code in nfs_rename() says: /* * If the tvp exists and is in use, sillyrename it before doing the * rename of the new file over it. */ if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename && !nfs_sillyrename(tdvp, tvp, tcnp)) { vrele(tvp); tvp = NULL; } Should the test in nfs_rename() check if the 'destination' vnode is a directory and skip the sillyrename if it is? I.e.: /* * If the tvp exists and is in use, sillyrename it before doing the * rename of the new file over it. * XXX Can't sillyrename a directory. The server will catch the * error for us anyway. */ if (tvp && tvp->v_usecount > 1 && !VTONFS(tvp)->n_sillyrename && tvp->v_type != VDIR && !nfs_sillyrename(tdvp, tvp, tcnp)) { vrele(tvp); tvp = NULL; } -Bill -- ============================================================================= -Bill Paul (212) 854-6020 | System Manager, Master of Unix-Fu Work: wpaul@ctr.columbia.edu | Center for Telecommunications Research Home: wpaul@skynet.ctr.columbia.edu | Columbia University, New York City ============================================================================= "It is not I who am crazy; it is I who am mad!" - Ren Hoek, "Space Madness" =============================================================================
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199612271633.LAA21311>