From owner-freebsd-current@FreeBSD.ORG Fri Nov 25 21:49:53 2005 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0C18616A41F for ; Fri, 25 Nov 2005 21:49:53 +0000 (GMT) (envelope-from csaba@beastie.creo.hu) Received: from beastie.creo.hu (www.creo.hu [217.113.62.14]) by mx1.FreeBSD.org (Postfix) with ESMTP id 4315D43D58 for ; Fri, 25 Nov 2005 21:49:50 +0000 (GMT) (envelope-from csaba@beastie.creo.hu) Received: from beastie.creo.hu (localhost [127.0.0.1]) by beastie.creo.hu (8.13.3/8.13.3) with ESMTP id jAPLlc10027144 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Fri, 25 Nov 2005 22:47:38 +0100 (CET) (envelope-from csaba@beastie.creo.hu) Received: (from csaba@localhost) by beastie.creo.hu (8.13.3/8.13.3/Submit) id jAPLlcDF027143 for freebsd-current@freebsd.org; Fri, 25 Nov 2005 22:47:38 +0100 (CET) (envelope-from csaba) Date: Fri, 25 Nov 2005 22:47:38 +0100 From: Csaba Henk To: freebsd-current@freebsd.org Message-ID: <20051125214738.GL2911@beastie.creo.hu> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="sm4nu43k4a2Rpi4c" Content-Disposition: inline User-Agent: Mutt/1.5.9i Subject: double close strikes panic if md attaching a corrupt file X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 25 Nov 2005 21:49:53 -0000 --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi! Imagine the following: You have a corrupt file (so that you can open it, but when you try reading from it, it returns EIO). Pretty common with crappy optical media. You try "mdconfig -a -t vnode" on it. This will lead to a call to xmdioctl() such that mdio->md_type is MD_VNODE. So you get the following call chain: xmdioctl -> mdcreate_vnode -> mdsetcred -> VOP_READ VOP_READ returns EIO. This error value will be propagated to mdcreate_vnode, who will then feel like vn_close-ing the vnode, and propagate the error further. Now we got back to xmdioctl, who will call for mddestroy because of the error. mddestroy still sees the vnode, and will vn_close it again. This will yield a "negative refcount" panic. Two different ideas for fixing this: 1. Don't vn_close in mdcreate_vnode when there is an error. 2. Not just vn_close in mdcreate_vnode upon error but also nullify the sc->vnode field. I attach two patches, they realize the above ideas, respectively. Note that I didn't test either. Regards, Csaba --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="md-doubleclose-1.diff" --- /sys/dev/md/md.c Sun Nov 13 10:43:06 2005 +++ - Fri Nov 25 22:42:29 2005 @@ -889,11 +889,7 @@ mdcreate_vnode(struct md_s *sc, struct m sc->vnode = nd.ni_vp; error = mdsetcred(sc, td->td_ucred); - if (error != 0) { - (void)vn_close(nd.ni_vp, flags, td->td_ucred, td); - return (error); - } - return (0); + return (error); } static int --sm4nu43k4a2Rpi4c Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="md-doubleclose-2.diff" --- /sys/dev/md/md.c Sun Nov 13 10:43:06 2005 +++ - Fri Nov 25 22:41:40 2005 @@ -891,6 +891,7 @@ mdcreate_vnode(struct md_s *sc, struct m error = mdsetcred(sc, td->td_ucred); if (error != 0) { (void)vn_close(nd.ni_vp, flags, td->td_ucred, td); + sc->vnode = NULL; return (error); } return (0); --sm4nu43k4a2Rpi4c--