* Allocate a free unr. */
| 599 | * Allocate a free unr. |
| 600 | */ |
| 601 | int |
| 602 | alloc_unrl(struct unrhdr *uh) |
| 603 | { |
| 604 | struct unr *up; |
| 605 | struct unrb *ub; |
| 606 | u_int x; |
| 607 | int y; |
| 608 | |
| 609 | mtx_assert(uh->mtx, MA_OWNED); |
| 610 | check_unrhdr(uh, __LINE__); |
| 611 | x = uh->low + uh->first; |
| 612 | |
| 613 | up = TAILQ_FIRST(&uh->head); |
| 614 | |
| 615 | /* |
| 616 | * If we have an ideal split, just adjust the first+last |
| 617 | */ |
| 618 | if (up == NULL && uh->last > 0) { |
| 619 | uh->first++; |
| 620 | uh->last--; |
| 621 | uh->busy++; |
| 622 | return (x); |
| 623 | } |
| 624 | |
| 625 | /* |
| 626 | * We can always allocate from the first list element, so if we have |
| 627 | * nothing on the list, we must have run out of unit numbers. |
| 628 | */ |
| 629 | if (up == NULL) |
| 630 | return (-1); |
| 631 | |
| 632 | KASSERT(up->ptr != uh, ("UNR first element is allocated")); |
| 633 | |
| 634 | if (up->ptr == NULL) { /* free run */ |
| 635 | uh->first++; |
| 636 | up->len--; |
| 637 | } else { /* bitmap */ |
| 638 | ub = up->ptr; |
| 639 | bit_ffc(ub->map, up->len, &y); |
| 640 | KASSERT(y != -1, ("UNR corruption: No clear bit in bitmap.")); |
| 641 | bit_set(ub->map, y); |
| 642 | x += y; |
| 643 | } |
| 644 | uh->busy++; |
| 645 | collapse_unr(uh, up); |
| 646 | return (x); |
| 647 | } |
| 648 | |
| 649 | int |
| 650 | alloc_unr(struct unrhdr *uh) |
no test coverage detected