svn commit: r346998 - projects/fuse2/sys/fs/fuse
Alan Somers
asomers at FreeBSD.org
Wed May 1 17:27:06 UTC 2019
Author: asomers
Date: Wed May 1 17:27:04 2019
New Revision: 346998
URL: https://svnweb.freebsd.org/changeset/base/346998
Log:
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
Modified:
projects/fuse2/sys/fs/fuse/fuse_node.c
Modified: projects/fuse2/sys/fs/fuse/fuse_node.c
==============================================================================
--- projects/fuse2/sys/fs/fuse/fuse_node.c Wed May 1 17:24:53 2019 (r346997)
+++ projects/fuse2/sys/fs/fuse/fuse_node.c Wed May 1 17:27:04 2019 (r346998)
@@ -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);
More information about the svn-src-projects
mailing list