kern/91879: [patch] Panic in nfs_putpages() on 6-stable.

Frank Mayhar frank at exit.com
Mon Jan 16 10:50:19 PST 2006


>Number:         91879
>Category:       kern
>Synopsis:       [patch] Panic in nfs_putpages() on 6-stable.
>Confidential:   no
>Severity:       serious
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jan 16 18:50:07 GMT 2006
>Closed-Date:
>Last-Modified:
>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 at 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:
>Unformatted:


More information about the freebsd-bugs mailing list