Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7-0]: src/sys/miscfs/specfs Pull up following revision(s) (reques...



details:   https://anonhg.NetBSD.org/src/rev/cda4346a5052
branches:  netbsd-7-0
changeset: 801177:cda4346a5052
user:      snj <snj%NetBSD.org@localhost>
date:      Fri Apr 29 19:09:32 2016 +0000

description:
Pull up following revision(s) (requested by hannken in ticket #1154):
        sys/miscfs/specfs/spec_vnops.c: revision 1.161, 1.162
Whhen spec_strategy() extracts v_rdev take care to avoid a
race with spec_revoke.
Fixes PR kern/50467 Panic from disconnecting phone while reading its contents
--
Avoid a race with spec_revoke for the assertion too.
Final fix for PR kern/50467 Panic from disconnecting phone while reading
its contents

diffstat:

 sys/miscfs/specfs/spec_vnops.c |  46 +++++++++++++++++++++++++++++------------
 1 files changed, 32 insertions(+), 14 deletions(-)

diffs (75 lines):

diff -r d8731d1cffce -r cda4346a5052 sys/miscfs/specfs/spec_vnops.c
--- a/sys/miscfs/specfs/spec_vnops.c    Fri Apr 29 18:55:31 2016 +0000
+++ b/sys/miscfs/specfs/spec_vnops.c    Fri Apr 29 19:09:32 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: spec_vnops.c,v 1.145 2014/07/25 08:20:53 dholland Exp $        */
+/*     $NetBSD: spec_vnops.c,v 1.145.6.1 2016/04/29 19:09:32 snj Exp $ */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.145 2014/07/25 08:20:53 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: spec_vnops.c,v 1.145.6.1 2016/04/29 19:09:32 snj Exp $");
 
 #include <sys/param.h>
 #include <sys/proc.h>
@@ -1051,26 +1051,44 @@
        } */ *ap = v;
        struct vnode *vp = ap->a_vp;
        struct buf *bp = ap->a_bp;
+       dev_t dev;
        int error;
 
-       KASSERT(vp == vp->v_specnode->sn_dev->sd_bdevvp);
+       dev = NODEV;
 
-       error = 0;
-       bp->b_dev = vp->v_rdev;
-
-       if (!(bp->b_flags & B_READ))
-               error = fscow_run(bp, false);
+       /*
+        * Extract all the info we need from the vnode, taking care to
+        * avoid a race with VOP_REVOKE().
+        */
 
-       if (error) {
-               bp->b_error = error;
-               bp->b_resid = bp->b_bcount;
-               biodone(bp);
-               return (error);
+       mutex_enter(vp->v_interlock);
+       if (vdead_check(vp, VDEAD_NOWAIT) == 0 && vp->v_specnode != NULL) {
+               KASSERT(vp == vp->v_specnode->sn_dev->sd_bdevvp);
+               dev = vp->v_rdev;
        }
+       mutex_exit(vp->v_interlock);
 
+       if (dev == NODEV) {
+               error = ENXIO;
+               goto out;
+       }
+       bp->b_dev = dev;
+
+       if (!(bp->b_flags & B_READ)) {
+               error = fscow_run(bp, false);
+               if (error)
+                       goto out;
+       }
        bdev_strategy(bp);
 
-       return (0);
+       return 0;
+
+out:
+       bp->b_error = error;
+       bp->b_resid = bp->b_bcount;
+       biodone(bp);
+
+       return error;
 }
 
 int



Home | Main Index | Thread Index | Old Index