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:
parent
93198e64fb
commit
72f03b7ccd
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user