fusefs: fix "returning with lock held" panics in fuse_vnode_alloc

These panics all lie in the error path.  The only one I've hit is caused by
a buggy FUSE server unexpectedly changing the type of a vnode.

Sponsored by:	The FreeBSD Foundation
This commit is contained in:
Alan Somers 2019-05-01 17:27:04 +00:00
parent 93198e64fb
commit 72f03b7ccd
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/fuse2/; revision=346998

View File

@ -212,6 +212,7 @@ fuse_vnode_hash(uint64_t id)
return (fnv_32_buf(&id, sizeof(id), FNV1_32_INIT));
}
SDT_PROBE_DEFINE2(fusefs, , node, stale_vnode, "struct vnode*", "enum vtype");
static int
fuse_vnode_alloc(struct mount *mp,
struct thread *td,
@ -240,7 +241,10 @@ fuse_vnode_alloc(struct mount *mp,
* between FUSE_LOOKUP and another client's
* FUSE_UNLINK/FUSE_CREATE
*/
SDT_PROBE2(fusefs, , node, stale_vnode, *vpp, vtyp);
fuse_internal_vnode_disappear(*vpp);
lockmgr((*vpp)->v_vnlock, LK_RELEASE, NULL);
*vpp = NULL;
return (EAGAIN);
}
MPASS((*vpp)->v_data != NULL);
@ -265,14 +269,19 @@ fuse_vnode_alloc(struct mount *mp,
err = insmntque(*vpp, mp);
ASSERT_VOP_ELOCKED(*vpp, "fuse_vnode_alloc");
if (err) {
lockmgr((*vpp)->v_vnlock, LK_RELEASE, NULL);
free(fvdat, M_FUSEVN);
*vpp = NULL;
return (err);
}
err = vfs_hash_insert(*vpp, fuse_vnode_hash(nodeid), LK_EXCLUSIVE,
td, &vp2, fuse_vnode_cmp, &nodeid);
if (err)
if (err) {
lockmgr((*vpp)->v_vnlock, LK_RELEASE, NULL);
free(fvdat, M_FUSEVN);
*vpp = NULL;
return (err);
}
if (vp2 != NULL) {
*vpp = vp2;
return (0);