Subject: Re: spec_poll vs. revoke
To: None <tech-kern@netbsd.org>
From: Jed Davis <jdev@panix.com>
List: tech-kern
Date: 08/24/2006 22:22:40
--=-=-=
Bill Studenmund <wrstuden@netbsd.org> writes:
> On Tue, Aug 22, 2006 at 07:29:43PM -0400, Jed Davis wrote:
>>
>> I notice that spec_ioctl() was corrected for a similar problem in
>> r1.83 of spec_vnops.c. So, is there any reason I shouldn't attempt to
>> apply a similar fix to spec_poll()?
>
> Please do so.
Attached; spec_poll appears to work afterwards, but as I can't
reproduce the race, I can't verify that aspect.
--
(let ((C call-with-current-continuation)) (apply (lambda (x y) (x y)) (map
((lambda (r) ((C C) (lambda (s) (r (lambda l (apply (s s) l)))))) (lambda
(f) (lambda (l) (if (null? l) C (lambda (k) (display (car l)) ((f (cdr l))
(C k))))))) '((#\J #\d #\D #\v #\s) (#\e #\space #\a #\i #\newline)))))
--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=spec_poll_race.diff
Index: miscfs/specfs/spec_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/specfs/spec_vnops.c,v
retrieving revision 1.80.2.1
diff -u -2 -r1.80.2.1 spec_vnops.c
--- miscfs/specfs/spec_vnops.c 26 Sep 2005 20:22:55 -0000 1.80.2.1
+++ miscfs/specfs/spec_vnops.c 24 Aug 2006 04:09:24 -0000
@@ -519,10 +519,26 @@
} */ *ap = v;
const struct cdevsw *cdev;
+ struct vnode *vp;
dev_t dev;
- switch (ap->a_vp->v_type) {
+ /*
+ * Extract all the info we need from the vnode, taking care to
+ * avoid a race with VOP_REVOKE().
+ */
+
+ vp = ap->a_vp;
+ dev = NODEV;
+ simple_lock(&vp->v_interlock);
+ if ((vp->v_flag & VXLOCK) == 0 && vp->v_specinfo) {
+ dev = vp->v_rdev;
+ }
+ simple_unlock(&vp->v_interlock);
+ if (dev == NODEV) {
+ return ENXIO;
+ }
+
+ switch (vp->v_type) {
case VCHR:
- dev = ap->a_vp->v_rdev;
cdev = cdevsw_lookup(dev);
if (cdev == NULL)
--=-=-=--