diff --git a/sys/fs/tmpfs/tmpfs_subr.c b/sys/fs/tmpfs/tmpfs_subr.c index 10acd4b1716..e05853c2d12 100644 --- a/sys/fs/tmpfs/tmpfs_subr.c +++ b/sys/fs/tmpfs/tmpfs_subr.c @@ -362,7 +362,8 @@ tmpfs_free_node_locked(struct tmpfs_mount *tmp, struct tmpfs_node *node, panic("tmpfs_free_node: type %p %d", node, (int)node->tn_type); } - free_unr(tmp->tm_ino_unr, node->tn_id); + if (!detach) + free_unr(tmp->tm_ino_unr, node->tn_id); uma_zfree(tmp->tm_node_pool, node); TMPFS_LOCK(tmp); tmpfs_free_tmp(tmp); diff --git a/sys/fs/tmpfs/tmpfs_vfsops.c b/sys/fs/tmpfs/tmpfs_vfsops.c index 4b336ba150d..3db84460de7 100644 --- a/sys/fs/tmpfs/tmpfs_vfsops.c +++ b/sys/fs/tmpfs/tmpfs_vfsops.c @@ -317,6 +317,8 @@ tmpfs_unmount(struct mount *mp, int mntflags) TMPFS_NODE_UNLOCK(node); } + destroy_unrhdr(tmp->tm_ino_unr); + mp->mnt_data = NULL; tmpfs_free_tmp(tmp); vfs_write_resume(mp, VR_START_WRITE); diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c index 3d510775b9e..dd69de41efd 100644 --- a/sys/kern/subr_unit.c +++ b/sys/kern/subr_unit.c @@ -366,6 +366,24 @@ delete_unrhdr(struct unrhdr *uh) Free(uh); } +void +destroy_unrhdr(struct unrhdr *uh) +{ + struct unr *uf; + + while ((uf = TAILQ_FIRST(&uh->head)) != NULL) { + TAILQ_REMOVE(&uh->head, uf, list); + if (uf->ptr != uh) { + Free(uf->ptr); + } + Free(uf); + } + uh->busy = 0; + uh->alloc = 0; + KASSERT(TAILQ_EMPTY(&uh->ppfree), + ("unrhdr has postponed item for free")); +} + static __inline int is_bitmap(struct unrhdr *uh, struct unr *up) { diff --git a/sys/sys/systm.h b/sys/sys/systm.h index ddebe0a6843..35d902de3d9 100644 --- a/sys/sys/systm.h +++ b/sys/sys/systm.h @@ -450,6 +450,7 @@ struct unrhdr; struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex); void init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex); void delete_unrhdr(struct unrhdr *uh); +void destroy_unrhdr(struct unrhdr *uh); void clean_unrhdr(struct unrhdr *uh); void clean_unrhdrl(struct unrhdr *uh); int alloc_unr(struct unrhdr *uh);