From frank@exit.com  Mon Jan 16 18:44:58 2006
Return-Path: <frank@exit.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 74B2D16A41F
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Jan 2006 18:44:58 +0000 (GMT)
	(envelope-from frank@exit.com)
Received: from tinker.exit.com (tinker.exit.com [206.223.0.1])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 1AA9F43D45
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Jan 2006 18:44:58 +0000 (GMT)
	(envelope-from frank@exit.com)
Received: from realtime.exit.com (realtime [206.223.0.5])
	by tinker.exit.com (8.13.4/8.13.4) with ESMTP id k0GIiv2D055285
	for <FreeBSD-gnats-submit@freebsd.org>; Mon, 16 Jan 2006 10:44:57 -0800 (PST)
	(envelope-from frank@exit.com)
Message-Id: <1137437097.69962@realtime.exit.com>
Date: Mon, 16 Jan 2006 10:44:57 -0800
From: "Frank Mayhar" <frank@exit.com>
To: "FreeBSD gnats submit" <FreeBSD-gnats-submit@freebsd.org>
Subject: [patch] Panic in nfs_putpages() on 6-stable.
X-Send-Pr-Version: gtk-send-pr 0.4.7 
X-GNATS-Notify:

>Number:         91879
>Category:       kern
>Synopsis:       [patch] Panic in nfs_putpages() on 6-stable.
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    alfred
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 16 18:50:07 GMT 2006
>Closed-Date:    Mon Sep 11 15:41:04 GMT 2006
>Last-Modified:  Mon Sep 11 15:41:04 GMT 2006
>Originator:     Frank Mayhar
>Release:        FreeBSD 7.0-CURRENT i386
>Organization:
Exit Consulting 
>Environment:


System: FreeBSD 7.0-CURRENT #2: Sun Jan  8 11:17:43 PST 2006     frank@auton:/home/obj/usr/src/sys/AUTON



>Description:


I ran into an nfs client panic a couple of times in a row over the last few days.  I tracked it down to the fact that nfs_reclaim() is setting vp->v_data to NULL _before_ calling vnode_destroy_object().  After silence from the mailing list I checked further and discovered that ufs_reclaim() is unique among FreeBSD filesystems for calling vnode_destroy_object() early, long before tossing v_data or much of anything else, for that matter.  The rest, including NFS, appear to be identical, as if they were just clones of one original routine.

After further silence from the mailing lists, I went ahead and fixed the problem.

The enclosed patch fixes all file systems in essentially the same way, by moving the call to vnode_destroy_object() to early in the routine (before the call to vfs_hash_remove(), if any).  I have only tested NFS, but I've now run for over eighteen hours with the patch where I wouldn't get past four or five without it.

I suggest MFC to (at least) 6-stable ASAP; that is in fact where I tested it.


>How-To-Repeat:





>Fix:


Index: sys/fs/hpfs/hpfs_vnops.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/hpfs/hpfs_vnops.c,v
retrieving revision 1.67
diff -u -r1.67 hpfs_vnops.c
--- sys/fs/hpfs/hpfs_vnops.c	4 Dec 2005 10:06:04 -0000	1.67
+++ sys/fs/hpfs/hpfs_vnops.c	16 Jan 2006 18:21:01 -0000
@@ -600,12 +600,16 @@
 
 	dprintf(("hpfs_reclaim(0x%x0): \n", hp->h_no));
 
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+
 	vfs_hash_remove(vp);
 
 	mtx_destroy(&hp->h_interlock);
 
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 
 	FREE(hp, M_HPFSNO);
 
Index: sys/fs/msdosfs/msdosfs_denode.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/msdosfs/msdosfs_denode.c,v
retrieving revision 1.90
diff -u -r1.90 msdosfs_denode.c
--- sys/fs/msdosfs/msdosfs_denode.c	31 Oct 2005 15:41:20 -0000	1.90
+++ sys/fs/msdosfs/msdosfs_denode.c	16 Jan 2006 18:21:01 -0000
@@ -549,6 +549,10 @@
 	if (prtactive && vrefcnt(vp) != 0)
 		vprint("msdosfs_reclaim(): pushing active", vp);
 	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+	/*
 	 * Remove the denode from its hash chain.
 	 */
 	vfs_hash_remove(vp);
@@ -560,7 +564,6 @@
 #endif
 	FREE(dep, M_MSDOSFSNODE);
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 
 	return (0);
 }
Index: sys/fs/ntfs/ntfs_vnops.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/ntfs/ntfs_vnops.c,v
retrieving revision 1.56
diff -u -r1.56 ntfs_vnops.c
--- sys/fs/ntfs/ntfs_vnops.c	4 Dec 2005 02:12:42 -0000	1.56
+++ sys/fs/ntfs/ntfs_vnops.c	16 Jan 2006 18:21:01 -0000
@@ -248,6 +248,11 @@
 	if (ntfs_prtactive && vrefcnt(vp) != 0)
 		vprint("ntfs_reclaim: pushing active", vp);
 
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+
 	if ((error = ntfs_ntget(ip)) != 0)
 		return (error);
 	
@@ -255,7 +260,6 @@
 	ntfs_frele(fp);
 	ntfs_ntput(ip);
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 
 	return (0);
 }
Index: sys/fs/nwfs/nwfs_node.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/nwfs/nwfs_node.c,v
retrieving revision 1.37
diff -u -r1.37 nwfs_node.c
--- sys/fs/nwfs/nwfs_node.c	31 Oct 2005 15:41:20 -0000	1.37
+++ sys/fs/nwfs/nwfs_node.c	16 Jan 2006 18:21:01 -0000
@@ -255,6 +255,11 @@
 	struct thread *td = ap->a_td;
 	
 	NCPVNDEBUG("%s,%d\n", np->n_name, vrefcnt(vp));
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+
 	if (np->n_flag & NREFPARENT) {
 		np->n_flag &= ~NREFPARENT;
 		if (nwfs_lookupnp(nmp, np->n_parent, td, &dnp) == 0) {
@@ -270,7 +275,6 @@
 		nmp->n_root = NULL;
 	}
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 	FREE(np, M_NWNODE);
 	if (dvp) {
 		vrele(dvp);
Index: sys/fs/smbfs/smbfs_node.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/smbfs/smbfs_node.c,v
retrieving revision 1.29
diff -u -r1.29 smbfs_node.c
--- sys/fs/smbfs/smbfs_node.c	31 Oct 2005 15:41:21 -0000	1.29
+++ sys/fs/smbfs/smbfs_node.c	16 Jan 2006 18:21:01 -0000
@@ -319,6 +319,10 @@
 	KASSERT((np->n_flag & NOPEN) == 0, ("file not closed before reclaim"));
 
 	smbfs_hash_lock(smp, td);
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
 
 	dvp = (np->n_parent && (np->n_flag & NREFPARENT)) ?
 	    np->n_parent : NULL;
@@ -330,7 +334,6 @@
 		smp->sm_root = NULL;
 	}
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 	smbfs_hash_unlock(smp, td);
 	if (np->n_name)
 		smbfs_name_free(np->n_name);
Index: sys/fs/udf/udf_vnops.c
===================================================================
RCS file: /cvs/repos/src/sys/fs/udf/udf_vnops.c,v
retrieving revision 1.59
diff -u -r1.59 udf_vnops.c
--- sys/fs/udf/udf_vnops.c	31 Oct 2005 15:41:21 -0000	1.59
+++ sys/fs/udf/udf_vnops.c	16 Jan 2006 18:21:01 -0000
@@ -965,6 +965,11 @@
 	vp = a->a_vp;
 	unode = VTON(vp);
 
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+
 	if (unode != NULL) {
 		vfs_hash_remove(vp);
 
@@ -973,7 +978,6 @@
 		uma_zfree(udf_zone_node, unode);
 		vp->v_data = NULL;
 	}
-	vnode_destroy_vobject(vp);
 
 	return (0);
 }
Index: sys/isofs/cd9660/cd9660_node.c
===================================================================
RCS file: /cvs/repos/src/sys/isofs/cd9660/cd9660_node.c,v
retrieving revision 1.54
diff -u -r1.54 cd9660_node.c
--- sys/isofs/cd9660/cd9660_node.c	14 Mar 2005 13:22:41 -0000	1.54
+++ sys/isofs/cd9660/cd9660_node.c	16 Jan 2006 18:21:17 -0000
@@ -98,6 +98,10 @@
 	if (prtactive && vrefcnt(vp) != 0)
 		vprint("cd9660_reclaim: pushing active", vp);
 	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+	/*
 	 * Remove the inode from its hash chain.
 	 */
 	vfs_hash_remove(vp);
@@ -109,7 +113,6 @@
 		vrele(ip->i_mnt->im_devvp);
 	FREE(vp->v_data, M_ISOFSNODE);
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 	return (0);
 }
 
Index: sys/nfsclient/nfs_node.c
===================================================================
RCS file: /cvs/repos/src/sys/nfsclient/nfs_node.c,v
retrieving revision 1.78
diff -u -r1.78 nfs_node.c
--- sys/nfsclient/nfs_node.c	27 Jul 2005 15:05:31 -0000	1.78
+++ sys/nfsclient/nfs_node.c	16 Jan 2006 18:21:17 -0000
@@ -211,6 +211,11 @@
 	if (prtactive && vrefcnt(vp) != 0)
 		vprint("nfs_reclaim: pushing active", vp);
 
+	/*
+	 * Destroy the vm object and flush associated pages.
+	 */
+	vnode_destroy_vobject(vp);
+
 	vfs_hash_remove(vp);
 
 	/*
@@ -232,6 +237,5 @@
 
 	uma_zfree(nfsnode_zone, vp->v_data);
 	vp->v_data = NULL;
-	vnode_destroy_vobject(vp);
 	return (0);
 }



>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->patched 
State-Changed-By: linimon 
State-Changed-When: Thu Jan 19 00:46:49 UTC 2006 
State-Changed-Why:  
Fixed in head in r1.91. 


Responsible-Changed-From-To: freebsd-bugs->alfred 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Thu Jan 19 00:46:49 UTC 2006 
Responsible-Changed-Why:  
MFC reminder for committer. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=91879 

From: Rong-En Fan <rafan@infor.org>
To: bug-followup@FreeBSD.org, frank@exit.com
Cc:  
Subject: =?UTF-8?Q?Re: kern/91879: [patch] Panic in nfs=5fputpages() on 6-stable.?=
Date: Mon, 13 Mar 2006 22:56:28 +0800 (CST)

 From cvs-src logs, this has been MFC'ed by scottl@
 yesterday.
State-Changed-From-To: patched->closed 
State-Changed-By: delphij 
State-Changed-When: Mon Sep 11 15:40:47 UTC 2006 
State-Changed-Why:  
scottl@ has MFC'ed the change to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=91879 
>Unformatted:
