Date: Thu, 13 Oct 2005 22:00:53 GMT From: soc-chenk <soc-chenk@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 85236 for review Message-ID: <200510132200.j9DM0r7D088918@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=85236 Change 85236 by soc-chenk@soc-chenk_leavemealone on 2005/10/13 22:00:13 fixed panics related to stale vnodes Submitted by: soc-chenk Affected files ... .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#15 edit .. //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.h#8 edit Differences ... ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.c#15 (text+ko) ==== @@ -1514,7 +1514,7 @@ static void fuse_filehandle_gc(struct vnode *vp, struct thread *td, struct ucred *cred); static vop_reclaim_t fuse_reclaim; static vop_inactive_t fuse_inactive; -static __inline void fuse_vnode_kick(struct vnode *vp); +static __inline void fuse_vnode_kick(struct vnode *vp, struct thread *td); static vop_access_t fuse_access; static __inline int fuse_access_by_attr(struct mount *mp, struct vattr *vap, mode_t mode, struct ucred *cred); /* static vop_cachedlookup_t fuse_lookup; */ @@ -1844,6 +1844,7 @@ * without resorting to the vfs hashing mechanism, thus it also * can be inserted directly to the v_hash slot. */ + rvp->v_hash = FUSE_ROOT_INODE; fmnt->rvp = rvp; fuse_vnode_init(rvp, fvdat, FUSE_ROOT_INODE, VDIR); rvp->v_vflag |= VV_ROOT; @@ -2113,7 +2114,7 @@ DEBUG2G("mp %p: %s\n", mp, mp->mnt_stat.f_mntfromname); - if ((err = vfs_hash_get(mp, 0, /*flags*/ myflags, td, vpp, fuse_vnode_cmp, &nodeid))) + if ((err = vfs_hash_get(mp, nodeid, /*flags*/ myflags, td, vpp, fuse_vnode_cmp, &nodeid))) return (err); audit: @@ -2122,7 +2123,7 @@ if ((*vpp)->v_type == vtyp) { return (0); } else - fuse_vnode_kick(*vpp); + fuse_vnode_kick(*vpp, td); } /* as the big guys say, malloc for your data before getnewvnode() */ @@ -2142,8 +2143,7 @@ return (err); } - /* XXX nodeid: cast from 64 bytes to 32 */ - err = vfs_hash_insert(*vpp, 0, /*flags*/ myflags, td, &vp2, fuse_vnode_cmp, &nodeid); + err = vfs_hash_insert(*vpp, nodeid, /*flags*/ myflags, td, &vp2, fuse_vnode_cmp, &nodeid); if (err) { FREE(fvdat, M_FUSEFS); @@ -2204,7 +2204,7 @@ return (0); } - DEBUG("getting at vnode of ino %llu\n", VTOI(vp)); + DEBUG("getting at vnode of ino %llu\n", VTOI32(vp)); fvdat = vp->v_data; @@ -2247,7 +2247,7 @@ KASSERT(fufh->useco >= 0, ("negative use count for fuse filehandle")); KASSERT(! fufh->fp || fufh->useco > 0, ("filehandle bound with 0 use counter")); - DEBUG2G("vnode #%llu, fufh owner %p, useco %d\n", VTOI(vp), fufh->fp, fufh->useco); + DEBUG2G("vnode #%llu, fufh owner %p, useco %d\n", VTOI32(vp), fufh->fp, fufh->useco); if (! fufh->fp && fufh->useco == 0) { LIST_REMOVE(fufh, fh_link); fuse_send_release(vp, td, cred, fufh, fufh->mode); @@ -2292,7 +2292,7 @@ int err; - DEBUG("getting at vnode of ino %llu\n", VTOI(vp)); + DEBUG("getting at vnode of ino %llu\n", VTOI32(vp)); #if _DEBUG DEBUG2G("=============>\n"); kdb_backtrace(); @@ -2342,12 +2342,22 @@ } static __inline void -fuse_vnode_kick(struct vnode *vp) +fuse_vnode_kick(struct vnode *vp, struct thread *td) { struct fuse_vnode_data *fvdat; + if (! td) + td = curthread; + + if (vp->v_vflag & VV_ROOT) { + fdata_kick_set(fusedev_get_data(((struct fuse_mnt_data *)vp->v_mount->mnt_data)->fdev)); + return; + } fvdat = vp->v_data; fvdat->nlookup = 0; + DEBUG("pfft...\n"); + fuse_filehandle_gc(vp, td, NULL); + vnode_destroy_vobject(vp); /* * this implies we won't get feedback on recycling * (other than panicking, or the lack of that) @@ -2355,8 +2365,7 @@ * would be too much hassle... */ vp->v_op = &dead_vnodeops; - DEBUG("pfft...\n"); - fuse_recyc_backend(vp, curthread); + fuse_recyc_backend(vp, td); vput(vp); } @@ -2458,12 +2467,13 @@ if (vp->v_type != vap->va_type) { /* stale vnode */ - DEBUG("node #%lu got stale, kicking...\n", vap->va_fileid); - fuse_vnode_kick(vp); + DEBUG("node #%lu got stale (old type 0x%x, new type 0x%x), kicking...\n", + vap->va_fileid, vp->v_type, vap->va_type); + fuse_vnode_kick(vp, td); return (EIO); } - DEBUG("node #%llu, type %d\n", VTOI(vp), vap->va_type); + DEBUG("node #%llu, type %d\n", VTOI32(vp), vap->va_type); #if _DEBUG DEBUG2G("\n"); vn_printf(vp, " * "); @@ -2567,7 +2577,7 @@ #endif if (dvp->v_type != VDIR) { - DEBUG("vnode #%llu of vtype %d is not a dir\n", VTOI(dvp), + DEBUG("vnode #%llu of vtype %d is not a dir\n", VTOI32(dvp), dvp->v_type); return (ENOTDIR); } @@ -2594,7 +2604,7 @@ return (err); } - DEBUG2G("lookup in #%llu, with flags 0x%x\n", VTOI(dvp), flags); + DEBUG2G("lookup in #%llu, with flags 0x%x\n", VTOI32(dvp), flags); /* fetching data from "storage" */ @@ -2978,13 +2988,13 @@ sx_sunlock(&fvdat->fh_lock); if (err == -1) { - DEBUG2G("suitable fh of vnode #%llu found\n", VTOI(vp)); + DEBUG2G("suitable fh of vnode #%llu found\n", VTOI32(vp)); return (fufh); } else if (err) return (NULL); - DEBUG2G("we need to fetch a new filehandle for vnode #%llu\n", VTOI(vp)); + DEBUG2G("we need to fetch a new filehandle for vnode #%llu\n", VTOI32(vp)); fdi.iosize = sizeof(*foi); if ((err = fdisp_prepare_all(&fdi, @@ -3241,7 +3251,7 @@ fvdat->fh_counter--; DEBUG2G("filehandle of vnode #%llu being released, fh counter now is %d\n", - VTOI(vp), fvdat->fh_counter); + VTOI32(vp), fvdat->fh_counter); fdi.iosize = sizeof(*fri); if ((err = fdisp_prepare_all(&fdi, @@ -3272,7 +3282,7 @@ */ #define BREAK_IF_BAD(fp) \ if (! (fp)->f_vnode->v_data) { \ - DEBUG("bad fileop on vnode no. %llu\n", VTOI((fp)->f_vnode)); \ + DEBUG("bad fileop on vnode no. %llu\n", VTOI32((fp)->f_vnode)); \ return (EBADF); \ } @@ -3305,7 +3315,7 @@ fufh = fp->f_data; KASSERT(fufh->fp == fp, ("file's filehandle is stolen")); DEBUG2G("vnode #%llu, fufh owner %p, useco %d\n", - VTOI(fp->f_vnode), fp, fufh->useco); + VTOI32(fp->f_vnode), fp, fufh->useco); fufh->useco--; sx_xlock(&fvdat->fh_lock); @@ -3504,6 +3514,7 @@ if (! FILE_IS_FAT(fp)) panic("non-fat file passed to read routine"); + vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td); if ((flags & FOF_OFFSET) == 0) uio->uio_offset = fp->f_offset; @@ -3522,12 +3533,12 @@ if (fp->f_flag & O_DIRECT || fufh->flags & FUSEFH_DIRECTIO) { DEBUG2G("direct read of vnode %llu via file handle %llu\n", - VTOI(fp->f_vnode), fufh->fh_id); + VTOI32(fp->f_vnode), fufh->fh_id); err = fuse_read_directbackend(fp->f_vnode, fufh, uio, cred, td, FUSE_READ, fuse_std_buffeater, NULL); } else { - DEBUG2G("buffered read of vnode %llu\n", VTOI(fp->f_vnode)); + DEBUG2G("buffered read of vnode %llu\n", VTOI32(fp->f_vnode)); err = fuse_read_biobackend(fp->f_vnode, fufh, uio, cred, td, FUSE_READ, fuse_std_buffeater, NULL); } @@ -3535,6 +3546,7 @@ if ((flags & FOF_OFFSET) == 0) fp->f_offset = uio->uio_offset; fp->f_nextoff = uio->uio_offset; + VOP_UNLOCK(fp->f_vnode, 0, td); return (err); } @@ -3974,7 +3986,7 @@ * XXX: handling of this case is untested. */ DEBUG("weird, file changed type during linking\n"); - fuse_vnode_kick(vp); + fuse_vnode_kick(vp, NULL); err = EBADF; } @@ -4199,7 +4211,7 @@ struct vnode *pdp2; DEBUG("trying at chenkpath\n"); do { - DEBUG("checkpath bumped into node %llu\n", VTOI(pdp)); + DEBUG("checkpath bumped into node %llu\n", VTOI32(pdp)); if (pdp->v_vflag & VV_ROOT) err = -1; if (pdp == fvp) { @@ -4421,7 +4433,7 @@ return (err); if (vp->v_type != IFTOVT(((struct fuse_attr_out *)fdi.answ)->attr.mode)) { - fuse_vnode_kick(vp); + fuse_vnode_kick(vp, td); err = EIO; } @@ -4827,6 +4839,7 @@ if (uio->uio_resid == 0) return (0); + vn_lock(fp->f_vnode, LK_EXCLUSIVE | LK_RETRY, td); if (fp->f_flag & O_APPEND) { VOP_GETATTR(fp->f_vnode, &va, cred, td); uio->uio_offset = va.va_size; @@ -4836,17 +4849,18 @@ if (fp->f_flag & O_DIRECT || fufh->flags & FUSEFH_DIRECTIO) { DEBUG2G("direct write of vnode %llu via file handle %llu\n", - VTOI(fp->f_vnode), fufh->fh_id); + VTOI32(fp->f_vnode), fufh->fh_id); err = fuse_write_directbackend(fp->f_vnode, fufh->fh_id, uio, cred, td); } else { - DEBUG2G("buffered write of vnode %llu\n", VTOI(fp->f_vnode)); + DEBUG2G("buffered write of vnode %llu\n", VTOI32(fp->f_vnode)); err = fuse_write_biobackend(fp->f_vnode, uio, cred, td); } if ((flags & FOF_OFFSET) == 0) fp->f_offset = uio->uio_offset; fp->f_nextoff = uio->uio_offset; + VOP_UNLOCK(fp->f_vnode, 0, td); DEBUG("leaving with %d\n", err); return (err); @@ -4879,13 +4893,13 @@ if (! (vp->v_type == VREG || vp->v_type == VDIR)) { DEBUG("for vnode #%llu v_type is %d, dropping\n", - VTOI(vp), vp->v_type); + VTOI32(vp), vp->v_type); return (EOPNOTSUPP); } if (bp->b_iocmd != BIO_READ && bp->b_iocmd != BIO_WRITE) { DEBUG("for vnode #%llu bio tried with biocmd 0x%x, dropping\n", - VTOI(vp), bp->b_iocmd); + VTOI32(vp), bp->b_iocmd); return (EOPNOTSUPP); } @@ -4924,7 +4938,7 @@ if (err) goto out; - DEBUG2G("vp #%llu, fufh #%llu\n", VTOI(vp), fufh->fh_id); + DEBUG2G("vp #%llu, fufh #%llu\n", VTOI32(vp), fufh->fh_id); if (bp->b_iocmd == BIO_READ) { struct fuse_read_in *fri; @@ -5077,7 +5091,7 @@ struct fuse_vnode_data *fvdat = ap->a_vp->v_data; printf("nodeid: %llu, fh_counter: %d, nlookup: %llu\n", - VTOI(ap->a_vp), fvdat->fh_counter, fvdat->nlookup); + VTOI32(ap->a_vp), fvdat->fh_counter, fvdat->nlookup); return (0); } @@ -5087,13 +5101,14 @@ struct vnode *vp; int rc; - DEBUG("vnode #%llu\n", VTOI((struct vnode *)bo->bo_private)); + DEBUG("vnode #%llu\n", VTOI32((struct vnode *)bo->bo_private)); vp = bo->bo_private; KASSERT(bo == &vp->v_bufobj, ("BO/VP mismatch: vp %p (#%llu) bo %p != %p", - vp, VTOI(vp), &vp->v_bufobj, bo)); + vp, VTOI32(vp), &vp->v_bufobj, bo)); rc = VOP_STRATEGY(vp, bp); - KASSERT(rc == 0, ("Fuse VOP_STRATEGY failed: bp=%p, " - "vp=%p, rc=%d", bp, vp, rc)); + KASSERT(vp->v_op == &dead_vnodeops || rc == 0, + ("Fuse VOP_STRATEGY failed: bp=%p, " + "vp=%p, rc=%d", bp, vp, rc)); } ==== //depot/projects/soc2005/fuse4bsd2/fuse_module/fuse.h#8 (text+ko) ==== @@ -137,6 +137,7 @@ #define FUSE_ROOT_INODE 1 /* Fuse convention: node id of root node is 1 */ #define VTOI(vp) ((struct fuse_vnode_data *)(vp)->v_data)->nid +#define VTOI32(vp) (uint64_t)(vp)->v_hash /** Max number of pages that can be used in a single read request */ /* (taken from Linux Fuse) */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200510132200.j9DM0r7D088918>