From owner-freebsd-current@FreeBSD.ORG Wed May 2 11:09:31 2007 Return-Path: X-Original-To: freebsd-current@freebsd.org Delivered-To: freebsd-current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 773B216A401; Wed, 2 May 2007 11:09:31 +0000 (UTC) (envelope-from csaba@beastie.creo.hu) Received: from beastie.creo.hu (www.creo.hu [217.113.62.14]) by mx1.freebsd.org (Postfix) with ESMTP id 9475C13C459; Wed, 2 May 2007 11:09:30 +0000 (UTC) (envelope-from csaba@beastie.creo.hu) Received: from beastie.creo.hu (localhost [127.0.0.1]) by beastie.creo.hu (8.13.4/8.13.4) with ESMTP id l42B7MLC082076 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 2 May 2007 13:07:22 +0200 (CEST) (envelope-from csaba@beastie.creo.hu) Received: (from csaba@localhost) by beastie.creo.hu (8.13.4/8.13.4/Submit) id l42B7Ld8082074; Wed, 2 May 2007 13:07:21 +0200 (CEST) (envelope-from csaba) Date: Wed, 2 May 2007 13:07:21 +0200 From: Csaba Henk To: Anish Mistry Message-ID: <20070502110721.GG79199@beastie.creo.hu> References: <4630D572.1020204@omnisec.de> <20070428114243.N28395@fledge.watson.org> <200704281633.32639.h.schmalzbauer@omnisec.de> <200704281412.19978.amistry@am-productions.biz> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="XRI2XbIfl/05pQwm" Content-Disposition: inline In-Reply-To: <200704281412.19978.amistry@am-productions.biz> User-Agent: Mutt/1.5.9i X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-2.0.2 (beastie.creo.hu [127.0.0.1]); Wed, 02 May 2007 13:07:23 +0200 (CEST) X-Mailman-Approved-At: Wed, 02 May 2007 11:33:43 +0000 Cc: freebsd-current@freebsd.org, Robert Watson , Harald Schmalzbauer Subject: Re: Panic: fusefs crashes -current X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 02 May 2007 11:09:31 -0000 --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--