From owner-freebsd-bugs Mon Apr 16 10: 8: 3 2001 Delivered-To: freebsd-bugs@freebsd.org Received: from pacific-carrier-annex.mit.edu (PACIFIC-CARRIER-ANNEX.MIT.EDU [18.7.21.83]) by hub.freebsd.org (Postfix) with ESMTP id 2D64A37B422; Mon, 16 Apr 2001 10:07:58 -0700 (PDT) (envelope-from fredette@MIT.EDU) Received: from grand-central-station.mit.edu (GRAND-CENTRAL-STATION.MIT.EDU [18.7.21.82]) by pacific-carrier-annex.mit.edu (8.9.2/8.9.2) with ESMTP id NAA04034; Mon, 16 Apr 2001 13:07:54 -0400 (EDT) Received: from manawatu-mail-centre.mit.edu (MANAWATU-MAIL-CENTRE.MIT.EDU [18.7.21.85]) by grand-central-station.mit.edu (8.9.2/8.9.2) with ESMTP id NAA13848; Mon, 16 Apr 2001 13:07:53 -0400 (EDT) Received: from ten-thousand-dollar-bill.mit.edu (TEN-THOUSAND-DOLLAR-BILL.MIT.EDU [18.184.0.39]) by manawatu-mail-centre.mit.edu (8.9.2/8.9.2) with ESMTP id NAA09919; Mon, 16 Apr 2001 13:07:47 -0400 (EDT) Received: (from fredette@localhost) by ten-thousand-dollar-bill.mit.edu (8.9.3) id NAA26501; Mon, 16 Apr 2001 13:07:53 -0400 (EDT) Message-Id: <200104161707.NAA26501@ten-thousand-dollar-bill.mit.edu> To: gnats-admin@FreeBSD.org, freebsd-bugs@FreeBSD.org Subject: Re: kern/26618: unmount(2) can't unmount a filesystem whose device has been lost In-Reply-To: Your message of "Mon, 16 Apr 2001 10:00:01 PDT." <200104161700.f3GH01u25681@freefall.freebsd.org> Date: Mon, 16 Apr 2001 13:07:52 -0400 From: Matthew Fredette Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org Here's a patch against sys/kern/vfs_syscalls.c revision 1.187: [snip] --- vfs_syscalls.c.orig Mon Apr 16 12:32:59 2001 +++ vfs_syscalls.c Mon Apr 16 12:36:37 2001 @@ -468,11 +468,71 @@ NDINIT(&nd, LOOKUP, FOLLOW | LOCKLEAF, UIO_USERSPACE, SCARG(uap, path), p); - if ((error = namei(&nd)) != 0) + if ((error = namei(&nd)) == ENXIO && suser(p) == 0) { + /* + * When root is trying to unmount a filesystem on a + * device that has disappeared, try to find the + * mountpoint by looking through the mountlist. + * Otherwise, such a filesystem can never get unmounted. + */ + char *path; + register struct mount *nmp; + register struct statfs *sp; + + mp = NULL; + simple_lock(&mountlist_slock); + path = zalloc(namei_zone); + for (;;) { + + /* Copy in the mount point. */ + if ((error = copyinstr(SCARG(uap, path), path, MAXPATHLEN, NULL)) != 0) + break; + + /* Don't allow empty pathnames. */ + if (*path == '\0') { + error = ENOENT; + break; + } + + /* Walk the mount list. */ + for (mp = TAILQ_FIRST(&mountlist); mp != NULL; mp = nmp) { + if (vfs_busy(mp, LK_NOWAIT, &mountlist_slock, p)) { + nmp = TAILQ_NEXT(mp, mnt_list); + continue; + } + sp = &mp->mnt_stat; + if (!strcmp(sp->f_mntonname, path)) { + vfs_unbusy(mp, p); + break; + } + nmp = TAILQ_NEXT(mp, mnt_list); + vfs_unbusy(mp, p); + } + + error = (mp == NULL ? ENOENT : 0); + break; + } + + zfree(namei_zone, path); + simple_unlock(&mountlist_slock); + if (error) + return (error); + } else if (error != 0) return (error); - vp = nd.ni_vp; - NDFREE(&nd, NDF_ONLY_PNBUF); - mp = vp->v_mount; + else { + vp = nd.ni_vp; + NDFREE(&nd, NDF_ONLY_PNBUF); + mp = vp->v_mount; + + /* + * Must be the root of the filesystem + */ + if ((vp->v_flag & VROOT) == 0) { + vput(vp); + return (EINVAL); + } + vput(vp); + } /* * Only root, or the user that did the original mount is @@ -480,7 +540,6 @@ */ if ((mp->mnt_stat.f_owner != p->p_ucred->cr_uid) && (error = suser(p))) { - vput(vp); return (error); } @@ -488,18 +547,9 @@ * Don't allow unmounting the root file system. */ if (mp->mnt_flag & MNT_ROOTFS) { - vput(vp); return (EINVAL); } - /* - * Must be the root of the filesystem - */ - if ((vp->v_flag & VROOT) == 0) { - vput(vp); - return (EINVAL); - } - vput(vp); return (dounmount(mp, SCARG(uap, flags), p)); } [snip] Matt -- Matt Fredette http://mit.edu/fredette/www To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message