diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile index bcfcb52b0152..1540bfa9d4dd 100644 --- a/share/man/man9/Makefile +++ b/share/man/man9/Makefile @@ -414,6 +414,7 @@ MAN= accept_filter.9 \ 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 diff --git a/share/man/man9/unr.9 b/share/man/man9/unr.9 index d8b9d9585352..fe1299d40e5d 100644 --- a/share/man/man9/unr.9 +++ b/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 @@ is not .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. diff --git a/sys/kern/subr_unit.c b/sys/kern/subr_unit.c index 3d510775b9ef..c2110d72169f 100644 --- a/sys/kern/subr_unit.c +++ b/sys/kern/subr_unit.c @@ -366,6 +366,27 @@ delete_unrhdr(struct unrhdr *uh) 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) { diff --git a/sys/sys/systm.h b/sys/sys/systm.h index ddebe0a68431..4fa3e6bb3444 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 clear_unrhdr(struct unrhdr *uh); void clean_unrhdr(struct unrhdr *uh); void clean_unrhdrl(struct unrhdr *uh); int alloc_unr(struct unrhdr *uh);