| 1947 | } |
| 1948 | |
| 1949 | static void |
| 1950 | bq_insert(struct bufqueue *bq, struct buf *bp, bool unlock) |
| 1951 | { |
| 1952 | struct bufdomain *bd; |
| 1953 | |
| 1954 | if (bp->b_qindex != QUEUE_NONE) |
| 1955 | panic("bq_insert: free buffer %p onto another queue?", bp); |
| 1956 | |
| 1957 | bd = bufdomain(bp); |
| 1958 | if (bp->b_flags & B_AGE) { |
| 1959 | /* Place this buf directly on the real queue. */ |
| 1960 | if (bq->bq_index == QUEUE_CLEAN) |
| 1961 | bq = bd->bd_cleanq; |
| 1962 | BQ_LOCK(bq); |
| 1963 | TAILQ_INSERT_HEAD(&bq->bq_queue, bp, b_freelist); |
| 1964 | } else { |
| 1965 | BQ_LOCK(bq); |
| 1966 | TAILQ_INSERT_TAIL(&bq->bq_queue, bp, b_freelist); |
| 1967 | } |
| 1968 | bp->b_flags &= ~(B_AGE | B_REUSE); |
| 1969 | bq->bq_len++; |
| 1970 | bp->b_qindex = bq->bq_index; |
| 1971 | bp->b_subqueue = bq->bq_subqueue; |
| 1972 | |
| 1973 | /* |
| 1974 | * Unlock before we notify so that we don't wakeup a waiter that |
| 1975 | * fails a trylock on the buf and sleeps again. |
| 1976 | */ |
| 1977 | if (unlock) |
| 1978 | BUF_UNLOCK(bp); |
| 1979 | |
| 1980 | if (bp->b_qindex == QUEUE_CLEAN) { |
| 1981 | /* |
| 1982 | * Flush the per-cpu queue and notify any waiters. |
| 1983 | */ |
| 1984 | if (bd->bd_wanted || (bq != bd->bd_cleanq && |
| 1985 | bq->bq_len >= bd->bd_lim)) |
| 1986 | bd_flush(bd, bq); |
| 1987 | } |
| 1988 | BQ_UNLOCK(bq); |
| 1989 | } |
| 1990 | |
| 1991 | /* |
| 1992 | * bufkva_free: |