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); err = getnewvnode("fuse", mp, &fuse_vnops, &rvp); + if (! err) { + err = 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 = FUSE_ROOT_ID; + fmnt->rvp = rvp; + fuse_vnode_init(rvp, fvdat, FUSE_ROOT_ID, VNON); + rvp->v_vflag |= VV_ROOT; +#if NEW_VNODES_ADJUSTED_MANUALLY + err = insmntque(rvp, mp); +#endif + } 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 = FUSE_ROOT_ID; - fmnt->rvp = rvp; - fuse_vnode_init(rvp, fvdat, FUSE_ROOT_ID, VNON); - rvp->v_vflag |= VV_ROOT; + } else + VOP_UNLOCK(rvp, 0, td); rootdone: @@ -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 = 0; struct fuse_mnt_data *fmnt; struct fuse_vnode_data *fvdat; struct vnode *vp2; - int myflags = LK_EXCLUSIVE; 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); } +#if NEW_VNODES_ADJUSTED_MANUALLY + err = vn_lock(*vpp, myflags, td); + if (err) + printf("fuse4bsd: leaking vnode %p\n", *vpp); + else + err = 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 } @@ -3571,7 +3597,20 @@ bringup: bzero(fvdat, sizeof(*fvdat)); fuse_vnode_init(vp, fvdat, feo->nodeid, VREG); vp->v_op = &fuse_vnops; +#if NEW_VNODES_ADJUSTED_MANUALLY + { + struct mount *mp = vp->v_mount; + + vp->v_mount = NULL; + err = 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 = getnewvnode("fuse", dvp->v_mount, &fuse_vnops, vpp))) return (err); - if ((err = vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread))) + if ((err = vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, curthread))) { +#if NEW_VNODES_ADJUSTED_MANUALLY + printf("fuse4bsd: leaking vnode %p\n", *vpp); +#endif return (err); + } 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 = &fuse_germ_vnops; (*vpp)->v_data = fvdat; +#if NEW_VNODES_ADJUSTED_MANUALLY + (*vpp)->v_mount = dvp->v_mount; +#endif return (0); 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 >= 700000 && __FreeBSD_version < 700002 ) #define USE_OLD_CLONEHANDLER_API +#endif +#endif + +#ifndef NEW_VNODES_ADJUSTED_MANUALLY +#if __FreeBSD_version >= 700034 +#define NEW_VNODES_ADJUSTED_MANUALLY 1 +#else +#define NEW_VNODES_ADJUSTED_MANUALLY 0 #endif #endif