Index: head/share/man/man9/Makefile =================================================================== --- head/share/man/man9/Makefile +++ head/share/man/man9/Makefile @@ -414,6 +414,7 @@ MLINKS= unr.9 alloc_unr.9 \ unr.9 alloc_unrl.9 \ unr.9 alloc_unr_specific.9 \ + unr.9 clear_unrhdr.9 \ unr.9 delete_unrhdr.9 \ unr.9 free_unr.9 \ unr.9 new_unrhdr.9 Index: head/share/man/man9/unr.9 =================================================================== --- head/share/man/man9/unr.9 +++ head/share/man/man9/unr.9 @@ -24,11 +24,12 @@ .\" .\" $FreeBSD$ .\" -.Dd July 5, 2010 +.Dd October 4, 2017 .Dt UNR 9 .Os .Sh NAME .Nm new_unrhdr , +.Nm clear_unrhdr , .Nm delete_unrhdr , .Nm alloc_unr , .Nm alloc_unr_specific , @@ -39,6 +40,8 @@ .Ft "struct unrhdr *" .Fn new_unrhdr "int low" "int high" "struct mtx *mutex" .Ft void +.Fn clear_unrhdr "struct unrhdr *uh" +.Ft void .Fn delete_unrhdr "struct unrhdr *uh" .Ft int .Fn alloc_unr "struct unrhdr *uh" @@ -70,8 +73,16 @@ .Dv NULL , it is used for locking when allocating and freeing units. Otherwise, internal mutex is used. +.It Fn clear_unrhdr uh +Clear all units from the specified unit number allocator entity. +This function resets the entity as if it were just initialized with +.Fn new_unrhdr . .It Fn delete_unrhdr uh -Destroy specified unit number allocator entity. +Delete specified unit number allocator entity. +This function frees the memory associated with the entity, it does not free +any units. +To free all units use +.Fn clear_unrhdr . .It Fn alloc_unr uh Return a new unit number. The lowest free number is always allocated. Index: head/sys/kern/subr_unit.c =================================================================== --- head/sys/kern/subr_unit.c +++ head/sys/kern/subr_unit.c @@ -366,6 +366,27 @@ Free(uh); } +void +clear_unrhdr(struct unrhdr *uh) +{ + struct unr *up, *uq; + + KASSERT(TAILQ_EMPTY(&uh->ppfree), + ("unrhdr has postponed item for free")); + up = TAILQ_FIRST(&uh->head); + while (up != NULL) { + uq = TAILQ_NEXT(up, list); + if (up->ptr != uh) { + Free(up->ptr); + } + Free(up); + up = uq; + } + TAILQ_INIT(&uh->head); + uh->busy = 0; + uh->alloc = 0; +} + static __inline int is_bitmap(struct unrhdr *uh, struct unr *up) { Index: head/sys/sys/systm.h =================================================================== --- head/sys/sys/systm.h +++ head/sys/sys/systm.h @@ -450,6 +450,7 @@ 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 clear_unrhdr(struct unrhdr *uh); void clean_unrhdr(struct unrhdr *uh); void clean_unrhdrl(struct unrhdr *uh); int alloc_unr(struct unrhdr *uh);