PERFORCE change 85236 for review
soc-chenk
soc-chenk at FreeBSD.org
Thu Oct 13 15:00:55 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=85236
Change 85236 by soc-chenk at 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) */
More information about the p4-projects
mailing list