aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMateusz Guzik <mjg@FreeBSD.org>2021-05-27 08:57:59 +0000
committerMateusz Guzik <mjg@FreeBSD.org>2021-05-31 23:21:15 +0000
commitf4aa64528e4557cd18cdb376b0f88f4a34d69912 (patch)
tree6b0e41c88e21fba069264817ccba3cffa6f0f216
parentb2f9575646f89cdddcad76acae3e9305535506a2 (diff)
downloadsrc-f4aa64528e4557cd18cdb376b0f88f4a34d69912.tar.gz
src-f4aa64528e4557cd18cdb376b0f88f4a34d69912.zip
tmpfs: save on relocking the allnode lock in tmpfs_free_node_locked
-rw-r--r--sys/fs/tmpfs/tmpfs_subr.c51
1 files changed, 32 insertions, 19 deletions
diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c
index 322641b5b853..b7dae82a71b4 100644
--- a/sys/fs/tmpfs/tmpfs_subr.c
+++ b/sys/fs/tmpfs/tmpfs_subr.c
@@ -578,53 +578,66 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node,
if (!last)
return (false);
+ TMPFS_NODE_UNLOCK(node);
+
#ifdef INVARIANTS
MPASS(node->tn_vnode == NULL);
MPASS((node->tn_vpstate & TMPFS_VNODE_ALLOCATING) == 0);
-#endif
- TMPFS_NODE_UNLOCK(node);
- TMPFS_UNLOCK(tmp);
+ /*
+ * Make sure this is a node type we can deal with. Everything is explicitly
+ * enumerated without the 'default' clause so the the compiler can throw an
+ * error in case a new type is added.
+ */
switch (node->tn_type) {
case VBLK:
- /* FALLTHROUGH */
case VCHR:
- /* FALLTHROUGH */
case VDIR:
- /* FALLTHROUGH */
case VFIFO:
- /* FALLTHROUGH */
case VSOCK:
- break;
-
case VLNK:
- symlink = node->tn_link_target;
- atomic_store_ptr(&node->tn_link_target, NULL);
- if (atomic_load_char(&node->tn_link_smr)) {
- cache_symlink_free(symlink, node->tn_size + 1);
- } else {
- free(symlink, M_TMPFSNAME);
- }
+ case VREG:
break;
+ case VNON:
+ case VBAD:
+ case VMARKER:
+ panic("%s: bad type %d for node %p", __func__, (int)node->tn_type, node);
+ }
+#endif
+ switch (node->tn_type) {
case VREG:
uobj = node->tn_reg.tn_aobj;
if (uobj != NULL) {
if (uobj->size != 0)
atomic_subtract_long(&tmp->tm_pages_used, uobj->size);
+ }
+
+ tmpfs_free_tmp(tmp);
+
+ if (uobj != NULL) {
KASSERT((uobj->flags & OBJ_TMPFS) == 0,
("leaked OBJ_TMPFS node %p vm_obj %p", node, uobj));
vm_object_deallocate(uobj);
}
break;
+ case VLNK:
+ tmpfs_free_tmp(tmp);
+ symlink = node->tn_link_target;
+ atomic_store_ptr(&node->tn_link_target, NULL);
+ if (atomic_load_char(&node->tn_link_smr)) {
+ cache_symlink_free(symlink, node->tn_size + 1);
+ } else {
+ free(symlink, M_TMPFSNAME);
+ }
+ break;
default:
- panic("tmpfs_free_node: type %p %d", node, (int)node->tn_type);
+ tmpfs_free_tmp(tmp);
+ break;
}
uma_zfree_smr(tmpfs_node_pool, node);
- TMPFS_LOCK(tmp);
- tmpfs_free_tmp(tmp);
return (true);
}