From owner-freebsd-hackers Fri Dec 27 08:36:06 1996 Return-Path: Received: (from root@localhost) by freefall.freebsd.org (8.8.4/8.8.4) id IAA26671 for hackers-outgoing; Fri, 27 Dec 1996 08:36:06 -0800 (PST) Received: from skynet.ctr.columbia.edu (skynet.ctr.columbia.edu [128.59.64.70]) by freefall.freebsd.org (8.8.4/8.8.4) with SMTP id IAA26657 for ; Fri, 27 Dec 1996 08:35:52 -0800 (PST) Received: (from wpaul@localhost) by skynet.ctr.columbia.edu (8.6.12/8.6.9) id LAA21311; Fri, 27 Dec 1996 11:33:21 -0500 From: Bill Paul Message-Id: <199612271633.LAA21311@skynet.ctr.columbia.edu> Subject: Re: [2.2-BETA] NFS hangup! To: joerg_wunsch@uriah.heep.sax.de Date: Fri, 27 Dec 1996 11:33:20 -0500 (EST) Cc: hackers@freebsd.org In-Reply-To: <199612270856.JAA03454@uriah.heep.sax.de> from "J Wunsch" at Dec 27, 96 09:56:03 am X-Mailer: ELM [version 2.4 PL24] Content-Type: text Sender: owner-hackers@freebsd.org X-Loop: FreeBSD.org Precedence: bulk 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" =============================================================================