Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 2 May 2007 13:07:21 +0200
From:      Csaba Henk <csaba.henk@creo.hu>
To:        Anish Mistry <amistry@am-productions.biz>
Cc:        freebsd-current@freebsd.org, Robert Watson <rwatson@freebsd.org>, Harald Schmalzbauer <h.schmalzbauer@omnisec.de>
Subject:   Re: Panic: fusefs crashes -current
Message-ID:  <20070502110721.GG79199@beastie.creo.hu>
In-Reply-To: <200704281412.19978.amistry@am-productions.biz>
References:  <4630D572.1020204@omnisec.de> <20070428114243.N28395@fledge.watson.org> <200704281633.32639.h.schmalzbauer@omnisec.de> <200704281412.19978.amistry@am-productions.biz>

next in thread | previous in thread | raw e-mail | index | archive | help

--XRI2XbIfl/05pQwm
Content-Type: multipart/mixed; boundary="XIiC+We3v3zHqZ6Z"
Content-Disposition: inline


--XIiC+We3v3zHqZ6Z
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,

On Sat, Apr 28, 2007 at 02:12:14PM -0400, Anish Mistry wrote:
> I've been able to reproduce this issue.  I've CC'd Csaba.

OK, I've fixed it. I send the patch against fuse4bsd-0.3.0_4
(it can be applied after running "make patch").

I also attach another bugfix backported from the devel version.

Csaba

--XIiC+We3v3zHqZ6Z
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fix-CURRENT-newvnode.diff"
Content-Transfer-Encoding: quoted-printable

diff -r 205480c57d59 fuse_module/fuse.c
--- a/fuse_module/fuse.c	Tue May 01 20:54:55 2007 +0200
+++ b/fuse_module/fuse.c	Tue May 01 21:05:58 2007 +0200
@@ -2070,23 +2070,36 @@ fuse_mount(struct mount *mp, struct thre
 	       M_WAITOK | M_ZERO);
=20
 	err =3D getnewvnode("fuse", mp, &fuse_vnops, &rvp);
+	if (! err) {
+		err =3D vn_lock(rvp, LK_EXCLUSIVE | LK_RETRY, td);
+#if NEW_VNODES_ADJUSTED_MANUALLY
+		if (err)
+			printf("fuse4bsd: leaking vnode %p\n", rvp);
+#endif
+	}
+
+	if (! err) {
+		/*
+		 * FUSE_ROOT_ID as an inode number will be resolved directly.
+		 * without resorting to the vfs hashing mechanism, thus it also
+		 * can be inserted directly to the v_hash slot.
+		 */
+		rvp->v_hash =3D FUSE_ROOT_ID;
+		fmnt->rvp =3D rvp;
+		fuse_vnode_init(rvp, fvdat, FUSE_ROOT_ID, VNON);
+		rvp->v_vflag |=3D VV_ROOT;
+#if NEW_VNODES_ADJUSTED_MANUALLY
+		err =3D insmntque(rvp, mp);
+#endif
+	}
=20
 	if (err) {
 		fdata_kick_set(data);
 		sx_xunlock(slock);
 		FREE(fvdat, M_FUSEFS);
 	        goto out;
-	}
-
-	/*
-	 * FUSE_ROOT_ID as an inode number will be resolved directly.
-	 * without resorting to the vfs hashing mechanism, thus it also
-	 * can be inserted directly to the v_hash slot.
-	 */
-	rvp->v_hash =3D FUSE_ROOT_ID;
-	fmnt->rvp =3D rvp; =09
-	fuse_vnode_init(rvp, fvdat, FUSE_ROOT_ID, VNON);
-	rvp->v_vflag |=3D VV_ROOT;
+	} else
+		VOP_UNLOCK(rvp, 0, td);
=20
 rootdone:
=20
@@ -2405,11 +2418,11 @@ fuse_vget_i(struct mount *mp, struct thr
 fuse_vget_i(struct mount *mp, struct thread *td, uint64_t nodeid,
 	    enum vtype vtyp, struct vnode **vpp, int wantnew)
 {
+#define myflags LK_EXCLUSIVE | LK_RETRY
 	int err =3D 0;
 	struct fuse_mnt_data *fmnt;
 	struct fuse_vnode_data *fvdat;
 	struct vnode *vp2;
-	int myflags =3D LK_EXCLUSIVE;
=20
 	DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname);
 	DEBUG("been asked for vno #%llu\n", (unsigned long long)nodeid);
@@ -2470,6 +2483,18 @@ audit:
 	        return (err);
 	}
=20
+#if NEW_VNODES_ADJUSTED_MANUALLY
+	err =3D vn_lock(*vpp, myflags, td);
+	if (err)
+		printf("fuse4bsd: leaking vnode %p\n", *vpp);
+	else
+		err =3D insmntque(*vpp, mp);
+	if (err) {
+	        free(fvdat, M_FUSEFS);
+	        return (err);
+	}
+#endif
+
 	/*
 	 * There is no harm in fully initializing the vnode before trying
 	 * at insertion, because vnodes are gc-d anyway. For the same reason,
@@ -2504,6 +2529,7 @@ audit:
 	vn_printf(*vpp, " * ");
 #endif
 	return (err);
+#undef myflags
 }
=20
=20
@@ -3571,7 +3597,20 @@ bringup:
 	bzero(fvdat, sizeof(*fvdat));
 	fuse_vnode_init(vp, fvdat, feo->nodeid, VREG);
 	vp->v_op =3D &fuse_vnops;
+#if NEW_VNODES_ADJUSTED_MANUALLY
+	{
+		struct mount *mp =3D vp->v_mount;
+
+		vp->v_mount =3D NULL;
+		err =3D insmntque(vp, mp);
+		if (err) {
+			free(fvdat, M_FUSEFS);
+			return (err);
+		}
+	}
+#else
 	VOP_UNLOCK(vp, 0, td);
+#endif
 	/*
 	 * We can't let the vnode being vput() here, the caller wants
 	 * that do by herself.
@@ -4687,8 +4726,12 @@ fuse_create(struct vop_create_args *ap)
 	if ((err =3D getnewvnode("fuse", dvp->v_mount, &fuse_vnops, vpp)))
 		return (err);
=20
-	if ((err =3D vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread)))
+	if ((err =3D vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread))) {
+#if NEW_VNODES_ADJUSTED_MANUALLY
+		printf("fuse4bsd: leaking vnode %p\n", *vpp);
+#endif
 		return (err);
+	}
=20
 	MALLOC(fvdat, struct fuse_vnode_data *, sizeof(*fvdat), M_FUSEFS,
 	       M_WAITOK | M_ZERO);
@@ -4708,6 +4751,9 @@ fuse_create(struct vop_create_args *ap)
 	 */
 	(*vpp)->v_op =3D &fuse_germ_vnops;
 	(*vpp)->v_data =3D fvdat;
+#if NEW_VNODES_ADJUSTED_MANUALLY
+	(*vpp)->v_mount =3D dvp->v_mount;
+#endif
=20
 	return (0);
=20
diff -r 205480c57d59 fuse_module/fuse.h
--- a/fuse_module/fuse.h	Tue May 01 20:54:55 2007 +0200
+++ b/fuse_module/fuse.h	Tue May 01 20:56:25 2007 +0200
@@ -9,6 +9,14 @@
 #ifndef USE_OLD_CLONEHANDLER_API
 #if __FreeBSD_version < 600034 || ( __FreeBSD_version >=3D 700000 && __Fre=
eBSD_version < 700002 )
 #define USE_OLD_CLONEHANDLER_API
+#endif
+#endif
+
+#ifndef NEW_VNODES_ADJUSTED_MANUALLY
+#if __FreeBSD_version >=3D 700034
+#define NEW_VNODES_ADJUSTED_MANUALLY 1
+#else
+#define NEW_VNODES_ADJUSTED_MANUALLY 0
 #endif
 #endif
=20

--XIiC+We3v3zHqZ6Z
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fix-io-on-hole-xd.diff"
Content-Transfer-Encoding: quoted-printable

diff -r c9549d324226 fuse_module/fuse.c
--- a/fuse_module/fuse.c	Sat Feb 11 01:30:59 2006 +0200
+++ b/fuse_module/fuse.c	Wed May 02 11:13:41 2007 +0200
@@ -4215,10 +4215,8 @@ fuse_read_biobackend(struct fuse_io_data
 #if _DEBUG
 			prettyprint(bp->b_data, 48);
 			printf("\n");
-#if ZERO_PAD_INCOMPLETE_BUFS
 			prettyprint(bp->b_data + PAGE_SIZE, 48);
 			printf("\n");
-#endif
 #endif
 			if (err) {
 				brelse(bp);
@@ -4492,13 +4490,6 @@ fuse_dir_buffeater(struct uio *uio, size
 			err =3D ((cou =3D=3D 1) ? -1 : 0);
 			break;
 		}
-
-#ifdef ZERO_PAD_INCOMPLETE_BUFS
-		if (isbzero(buf), FUSE_NAME_OFFSET) {
-			err =3D -1;
-			break;
-		}
-#endif
=20
 		/* Sanity checks */
=20
@@ -5741,23 +5732,16 @@ fuse_strategy_i(struct vnode *vp, struct
 			        chunksize, (long long unsigned)fri->offset, respsize);
 =09
 			if (respsize < chunksize) {
-#ifdef ZERO_PAD_INCOMPLETE_BUFS
 				/*
-				 * "if we don't get enough data, just fill the
-				 * rest with zeros."
-				 * in nfs context this means a hole in the
-				 * file, I don't know what to do with this
-				 * here... [we just get a buch of zeroes
-				 * instead of EOF, baaad]
+				 * if we don't get enough data, just fill the
+				 * rest with zeros.
 				 */=20
 				DEBUG("zeroing tail of %ld bytes\n",
 				      bp->b_resid);
 				bzero((char *)bp->b_data + bp->b_bcount - bp->b_resid,
 				      bp->b_resid);
-				bp->b_resid =3D 0;
-#else
+
 				break;
-#endif
 			}
 			ticket_refresh(fdi.tick);
 			DEBUG("bp->b_data %p\n", bp->b_data);

--XIiC+We3v3zHqZ6Z--

--XRI2XbIfl/05pQwm
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.2 (FreeBSD)

iD8DBQFGOHDn6tF8nOdLsHQRAkpXAKDRSaSbdjPMAIU0LsXEKLyukxAWWQCgt69T
Eji8kO0gQCCLg3+xFxgz3Mo=
=1sDn
-----END PGP SIGNATURE-----

--XRI2XbIfl/05pQwm--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20070502110721.GG79199>