Subject: pgo_get on a dead vnode
To: None <tech-kern@netbsd.org>
From: Antti Kantee <pooka@cs.hut.fi>
List: tech-kern
Date: 12/08/2006 22:06:05
In case of a forced unmount vnodes are brutally coerced to deadfs.
If we take a page fault for a converted vnode after this, uvn_get()
ends up calling VOP_GETPAGES() as vn_default_error().  This leaves the
vm object locked upon return even if PGO_LOCKED is not set.

The following patch teaches deadfs about getpages locking.  Comments?


Index: dead_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/miscfs/deadfs/dead_vnops.c,v
retrieving revision 1.41
diff -u -r1.41 dead_vnops.c
--- dead_vnops.c	16 Nov 2006 01:33:38 -0000	1.41
+++ dead_vnops.c	8 Dec 2006 20:03:20 -0000
@@ -86,6 +86,7 @@
 #define dead_advlock	genfs_ebadf
 #define dead_bwrite	genfs_nullop
 #define dead_revoke	genfs_nullop
+int	dead_getpages(void *);
 #define dead_putpages	genfs_null_putpages
 
 int	chkvnlock(struct vnode *);
@@ -132,6 +133,7 @@
 	{ &vop_pathconf_desc, dead_pathconf },		/* pathconf */
 	{ &vop_advlock_desc, dead_advlock },		/* advlock */
 	{ &vop_bwrite_desc, dead_bwrite },		/* bwrite */
+	{ &vop_getpages_desc, dead_getpages },		/* getpages */
 	{ &vop_putpages_desc, dead_putpages },		/* putpages */
 	{ NULL, NULL }
 };
@@ -324,6 +326,26 @@
 	return 0;
 }
 
+int
+dead_getpages(void *v)
+{
+	struct vop_getpages_args /* {
+		struct vnode *a_vp;
+		voff_t a_offset;
+		struct vm_page **a_m;
+		int *a_count;
+		int a_centeridx;
+		vm_prot_t a_access_type;
+		int a_advice;
+		int a_flags;
+	} */ *ap = v;
+
+	if ((ap->a_flags & PGO_LOCKED) == 0)
+		simple_unlock(&ap->a_vp->v_interlock);
+
+	return (EFAULT);
+}
+
 /*
  * We have to wait during times when the vnode is
  * in a state of change.

-- 
Antti Kantee <pooka@iki.fi>                     Of course he runs NetBSD
http://www.iki.fi/pooka/                          http://www.NetBSD.org/
    "la qualité la plus indispensable du cuisinier est l'exactitude"