double close strikes panic if md attaching a corrupt file

Csaba Henk csaba-ml at creo.hu
Fri Nov 25 21:49:53 GMT 2005


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
-------------- next part --------------
--- /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
-------------- next part --------------
--- /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);


More information about the freebsd-current mailing list