2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_OSREFERENCE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. The rights granted to you under the
10 * License may not be used to create, or enable the creation or
11 * redistribution of, unlawful or unlicensed copies of an Apple operating
12 * system, or to circumvent, violate, or enable the circumvention or
13 * violation of, any terms of an Apple operating system software license
16 * Please obtain a copy of the License at
17 * http://www.opensource.apple.com/apsl/ and read it before using this
20 * The Original Code and all software distributed under the License are
21 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
22 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
23 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
25 * Please see the License for the specific language governing rights and
26 * limitations under the License.
28 * @APPLE_LICENSE_OSREFERENCE_HEADER_END@
30 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
32 * Copyright (c) 1994 Christopher G. Demetriou
33 * Copyright (c) 1982, 1986, 1989, 1993
34 * The Regents of the University of California. All rights reserved.
35 * (c) UNIX System Laboratories, Inc.
36 * All or some portions of this file are derived from material licensed
37 * to the University of California by American Telephone and Telegraph
38 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
39 * the permission of UNIX System Laboratories, Inc.
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
44 * 1. Redistributions of source code must retain the above copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * This product includes software developed by the University of
52 * California, Berkeley and its contributors.
53 * 4. Neither the name of the University nor the names of its contributors
54 * may be used to endorse or promote products derived from this software
55 * without specific prior written permission.
57 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
58 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
59 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
60 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
61 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
62 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
63 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
64 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
65 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
66 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94
74 * Bach: The Design of the UNIX Operating System (Prentice Hall, 1986)
75 * Leffler, et al.: The Design and Implementation of the 4.3BSD
76 * UNIX Operating System (Addison Welley, 1989)
79 #include <sys/param.h>
80 #include <sys/systm.h>
81 #include <sys/proc_internal.h>
82 #include <sys/buf_internal.h>
83 #include <sys/vnode_internal.h>
84 #include <sys/mount_internal.h>
85 #include <sys/trace.h>
86 #include <sys/malloc.h>
87 #include <sys/resourcevar.h>
88 #include <miscfs/specfs/specdev.h>
90 #include <sys/kauth.h>
92 #include <kern/assert.h>
93 #endif /* DIAGNOSTIC */
94 #include <kern/task.h>
95 #include <kern/zalloc.h>
96 #include <kern/lock.h>
98 #include <vm/vm_kern.h>
100 #include <sys/kdebug.h>
101 #include <machine/spl.h>
104 static __inline__
void bufqinc(int q
);
105 static __inline__
void bufqdec(int q
);
108 static int bcleanbuf(buf_t bp
);
109 static int brecover_data(buf_t bp
);
110 static boolean_t
incore(vnode_t vp
, daddr64_t blkno
);
111 static buf_t
incore_locked(vnode_t vp
, daddr64_t blkno
);
112 /* timeout is in msecs */
113 static buf_t
getnewbuf(int slpflag
, int slptimeo
, int *queue
);
114 static void bremfree_locked(buf_t bp
);
115 static void buf_reassign(buf_t bp
, vnode_t newvp
);
116 static errno_t
buf_acquire_locked(buf_t bp
, int flags
, int slpflag
, int slptimeo
);
117 static int buf_iterprepare(vnode_t vp
, struct buflists
*, int flags
);
118 static void buf_itercomplete(vnode_t vp
, struct buflists
*, int flags
);
120 __private_extern__
int bdwrite_internal(buf_t
, int);
122 /* zone allocated buffer headers */
123 static void bufzoneinit(void);
124 static void bcleanbuf_thread_init(void);
125 static void bcleanbuf_thread(void);
127 static zone_t buf_hdr_zone
;
128 static int buf_hdr_count
;
132 * Definitions for the buffer hash lists.
134 #define BUFHASH(dvp, lbn) \
135 (&bufhashtbl[((long)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash])
136 LIST_HEAD(bufhashhdr
, buf
) *bufhashtbl
, invalhash
;
139 /* Definitions for the buffer stats. */
140 struct bufstats bufstats
;
142 /* Number of delayed write buffers */
147 static TAILQ_HEAD(ioqueue
, buf
) iobufqueue
;
148 static TAILQ_HEAD(bqueues
, buf
) bufqueues
[BQUEUES
];
149 static int needbuffer
;
150 static int need_iobuffer
;
152 static lck_grp_t
*buf_mtx_grp
;
153 static lck_attr_t
*buf_mtx_attr
;
154 static lck_grp_attr_t
*buf_mtx_grp_attr
;
155 static lck_mtx_t
*iobuffer_mtxp
;
156 static lck_mtx_t
*buf_mtxp
;
158 static __inline__
int
167 * Insq/Remq for the buffer free lists.
170 #define binsheadfree(bp, dp, whichq) do { \
171 TAILQ_INSERT_HEAD(dp, bp, b_freelist); \
173 (bp)->b_whichq = whichq; \
174 (bp)->b_timestamp = buf_timestamp(); \
177 #define binstailfree(bp, dp, whichq) do { \
178 TAILQ_INSERT_TAIL(dp, bp, b_freelist); \
180 (bp)->b_whichq = whichq; \
181 (bp)->b_timestamp = buf_timestamp(); \
184 #define binsheadfree(bp, dp, whichq) do { \
185 TAILQ_INSERT_HEAD(dp, bp, b_freelist); \
186 (bp)->b_whichq = whichq; \
187 (bp)->b_timestamp = buf_timestamp(); \
190 #define binstailfree(bp, dp, whichq) do { \
191 TAILQ_INSERT_TAIL(dp, bp, b_freelist); \
192 (bp)->b_whichq = whichq; \
193 (bp)->b_timestamp = buf_timestamp(); \
198 #define BHASHENTCHECK(bp) \
199 if ((bp)->b_hash.le_prev != (struct buf **)0xdeadbeef) \
200 panic("%x: b_hash.le_prev is not deadbeef", (bp));
202 #define BLISTNONE(bp) \
203 (bp)->b_hash.le_next = (struct buf *)0; \
204 (bp)->b_hash.le_prev = (struct buf **)0xdeadbeef;
207 * Insq/Remq for the vnode usage lists.
209 #define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs)
210 #define bufremvn(bp) { \
211 LIST_REMOVE(bp, b_vnbufs); \
212 (bp)->b_vnbufs.le_next = NOLIST; \
216 * Time in seconds before a buffer on a list is
217 * considered as a stale buffer
219 #define LRU_IS_STALE 120 /* default value for the LRU */
220 #define AGE_IS_STALE 60 /* default value for the AGE */
221 #define META_IS_STALE 180 /* default value for the BQ_META */
223 int lru_is_stale
= LRU_IS_STALE
;
224 int age_is_stale
= AGE_IS_STALE
;
225 int meta_is_stale
= META_IS_STALE
;
226 static int boot_nbuf
= 0;
229 /* LIST_INSERT_HEAD() with assertions */
230 static __inline__
void
231 blistenterhead(struct bufhashhdr
* head
, buf_t bp
)
233 if ((bp
->b_hash
.le_next
= (head
)->lh_first
) != NULL
)
234 (head
)->lh_first
->b_hash
.le_prev
= &(bp
)->b_hash
.le_next
;
235 (head
)->lh_first
= bp
;
236 bp
->b_hash
.le_prev
= &(head
)->lh_first
;
237 if (bp
->b_hash
.le_prev
== (struct buf
**)0xdeadbeef)
238 panic("blistenterhead: le_prev is deadbeef");
241 static __inline__
void
242 binshash(buf_t bp
, struct bufhashhdr
*dp
)
246 #endif /* DIAGNOSTIC */
252 for(; nbp
!= NULL
; nbp
= nbp
->b_hash
.le_next
) {
254 panic("buf already in hashlist");
256 #endif /* DIAGNOSTIC */
258 blistenterhead(dp
, bp
);
261 static __inline__
void
264 if (bp
->b_hash
.le_prev
== (struct buf
**)0xdeadbeef)
265 panic("bremhash le_prev is deadbeef");
266 if (bp
->b_hash
.le_next
== bp
)
267 panic("bremhash: next points to self");
269 if (bp
->b_hash
.le_next
!= NULL
)
270 bp
->b_hash
.le_next
->b_hash
.le_prev
= bp
->b_hash
.le_prev
;
271 *bp
->b_hash
.le_prev
= (bp
)->b_hash
.le_next
;
278 buf_valid(buf_t bp
) {
280 if ( (bp
->b_flags
& (B_DONE
| B_DELWRI
)) )
286 buf_fromcache(buf_t bp
) {
288 if ( (bp
->b_flags
& B_CACHE
) )
294 buf_markinvalid(buf_t bp
) {
296 SET(bp
->b_flags
, B_INVAL
);
300 buf_markdelayed(buf_t bp
) {
302 SET(bp
->b_flags
, B_DELWRI
);
303 buf_reassign(bp
, bp
->b_vp
);
307 buf_markeintr(buf_t bp
) {
309 SET(bp
->b_flags
, B_EINTR
);
313 buf_markaged(buf_t bp
) {
315 SET(bp
->b_flags
, B_AGE
);
319 buf_error(buf_t bp
) {
321 return (bp
->b_error
);
325 buf_seterror(buf_t bp
, errno_t error
) {
327 if ((bp
->b_error
= error
))
328 SET(bp
->b_flags
, B_ERROR
);
330 CLR(bp
->b_flags
, B_ERROR
);
334 buf_setflags(buf_t bp
, int32_t flags
) {
336 SET(bp
->b_flags
, (flags
& BUF_X_WRFLAGS
));
340 buf_clearflags(buf_t bp
, int32_t flags
) {
342 CLR(bp
->b_flags
, (flags
& BUF_X_WRFLAGS
));
346 buf_flags(buf_t bp
) {
348 return ((bp
->b_flags
& BUF_X_RDFLAGS
));
352 buf_reset(buf_t bp
, int32_t io_flags
) {
354 CLR(bp
->b_flags
, (B_READ
| B_WRITE
| B_ERROR
| B_DONE
| B_INVAL
| B_ASYNC
| B_NOCACHE
));
355 SET(bp
->b_flags
, (io_flags
& (B_ASYNC
| B_READ
| B_WRITE
| B_NOCACHE
)));
361 buf_count(buf_t bp
) {
363 return (bp
->b_bcount
);
367 buf_setcount(buf_t bp
, uint32_t bcount
) {
369 bp
->b_bcount
= bcount
;
375 return (bp
->b_bufsize
);
379 buf_setsize(buf_t bp
, uint32_t bufsize
) {
381 bp
->b_bufsize
= bufsize
;
385 buf_resid(buf_t bp
) {
387 return (bp
->b_resid
);
391 buf_setresid(buf_t bp
, uint32_t resid
) {
397 buf_dirtyoff(buf_t bp
) {
399 return (bp
->b_dirtyoff
);
403 buf_dirtyend(buf_t bp
) {
405 return (bp
->b_dirtyend
);
409 buf_setdirtyoff(buf_t bp
, uint32_t dirtyoff
) {
411 bp
->b_dirtyoff
= dirtyoff
;
415 buf_setdirtyend(buf_t bp
, uint32_t dirtyend
) {
417 bp
->b_dirtyend
= dirtyend
;
421 buf_dataptr(buf_t bp
) {
423 return (bp
->b_datap
);
427 buf_setdataptr(buf_t bp
, uintptr_t data
) {
433 buf_vnode(buf_t bp
) {
439 buf_setvnode(buf_t bp
, vnode_t vp
) {
446 buf_callback(buf_t bp
)
448 if ( !(bp
->b_lflags
& BL_IOBUF
) )
449 return ((void *) NULL
);
450 if ( !(bp
->b_flags
& B_CALL
) )
451 return ((void *) NULL
);
453 return ((void *)bp
->b_iodone
);
458 buf_setcallback(buf_t bp
, void (*callback
)(buf_t
, void *), void *transaction
)
461 if ( !(bp
->b_lflags
& BL_IOBUF
) )
465 bp
->b_flags
|= (B_CALL
| B_ASYNC
);
467 bp
->b_flags
&= ~B_CALL
;
468 bp
->b_transaction
= transaction
;
469 bp
->b_iodone
= callback
;
475 buf_setupl(buf_t bp
, upl_t upl
, uint32_t offset
)
478 if ( !(bp
->b_lflags
& BL_IOBUF
) )
482 bp
->b_flags
|= B_CLUSTER
;
484 bp
->b_flags
&= ~B_CLUSTER
;
486 bp
->b_uploffset
= offset
;
492 buf_clone(buf_t bp
, int io_offset
, int io_size
, void (*iodone
)(buf_t
, void *), void *arg
)
496 if (io_offset
< 0 || io_size
< 0)
499 if ((unsigned)(io_offset
+ io_size
) > (unsigned)bp
->b_bcount
)
502 if (bp
->b_flags
& B_CLUSTER
) {
503 if (io_offset
&& ((bp
->b_uploffset
+ io_offset
) & PAGE_MASK
))
506 if (((bp
->b_uploffset
+ io_offset
+ io_size
) & PAGE_MASK
) && ((io_offset
+ io_size
) < bp
->b_bcount
))
509 io_bp
= alloc_io_buf(bp
->b_vp
, 0);
511 io_bp
->b_flags
= bp
->b_flags
& (B_COMMIT_UPL
| B_META
| B_PAGEIO
| B_CLUSTER
| B_PHYS
| B_ASYNC
| B_READ
);
514 io_bp
->b_transaction
= arg
;
515 io_bp
->b_iodone
= iodone
;
516 io_bp
->b_flags
|= B_CALL
;
518 if (bp
->b_flags
& B_CLUSTER
) {
519 io_bp
->b_upl
= bp
->b_upl
;
520 io_bp
->b_uploffset
= bp
->b_uploffset
+ io_offset
;
522 io_bp
->b_datap
= (uintptr_t)(((char *)bp
->b_datap
) + io_offset
);
524 io_bp
->b_bcount
= io_size
;
532 buf_setfilter(buf_t bp
, void (*filter
)(buf_t
, void *), void *transaction
,
533 void **old_iodone
, void **old_transaction
)
536 *old_iodone
= (void *)(bp
->b_iodone
);
538 *old_transaction
= (void *)(bp
->b_transaction
);
540 bp
->b_transaction
= transaction
;
541 bp
->b_iodone
= filter
;
542 bp
->b_flags
|= B_FILTER
;
547 buf_blkno(buf_t bp
) {
549 return (bp
->b_blkno
);
553 buf_lblkno(buf_t bp
) {
555 return (bp
->b_lblkno
);
559 buf_setblkno(buf_t bp
, daddr64_t blkno
) {
565 buf_setlblkno(buf_t bp
, daddr64_t lblkno
) {
567 bp
->b_lblkno
= lblkno
;
571 buf_device(buf_t bp
) {
577 buf_setdevice(buf_t bp
, vnode_t vp
) {
579 if ((vp
->v_type
!= VBLK
) && (vp
->v_type
!= VCHR
))
581 bp
->b_dev
= vp
->v_rdev
;
588 buf_drvdata(buf_t bp
) {
590 return (bp
->b_drvdata
);
594 buf_setdrvdata(buf_t bp
, void *drvdata
) {
596 bp
->b_drvdata
= drvdata
;
600 buf_fsprivate(buf_t bp
) {
602 return (bp
->b_fsprivate
);
606 buf_setfsprivate(buf_t bp
, void *fsprivate
) {
608 bp
->b_fsprivate
= fsprivate
;
612 buf_rcred(buf_t bp
) {
614 return (bp
->b_rcred
);
618 buf_wcred(buf_t bp
) {
620 return (bp
->b_wcred
);
630 buf_uploffset(buf_t bp
) {
632 return ((uint32_t)(bp
->b_uploffset
));
643 buf_map(buf_t bp
, caddr_t
*io_addr
)
649 if ( !(bp
->b_flags
& B_CLUSTER
)) {
650 *io_addr
= (caddr_t
)bp
->b_datap
;
653 real_bp
= (buf_t
)(bp
->b_real_bp
);
655 if (real_bp
&& real_bp
->b_datap
) {
657 * b_real_bp is only valid if B_CLUSTER is SET
658 * if it's non-zero, than someone did a cluster_bp call
659 * if the backing physical pages were already mapped
660 * in before the call to cluster_bp (non-zero b_datap),
661 * than we just use that mapping
663 *io_addr
= (caddr_t
)real_bp
->b_datap
;
666 kret
= ubc_upl_map(bp
->b_upl
, &vaddr
); /* Map it in */
668 if (kret
!= KERN_SUCCESS
) {
673 vaddr
+= bp
->b_uploffset
;
675 *io_addr
= (caddr_t
)vaddr
;
686 if ( !(bp
->b_flags
& B_CLUSTER
))
689 * see buf_map for the explanation
691 real_bp
= (buf_t
)(bp
->b_real_bp
);
693 if (real_bp
&& real_bp
->b_datap
)
696 if (bp
->b_lflags
& BL_IOBUF
) {
698 * when we commit these pages, we'll hit
699 * it with UPL_COMMIT_INACTIVE which
700 * will clear the reference bit that got
701 * turned on when we touched the mapping
703 bp
->b_flags
|= B_AGE
;
705 kret
= ubc_upl_unmap(bp
->b_upl
);
707 if (kret
!= KERN_SUCCESS
)
714 buf_clear(buf_t bp
) {
717 if (buf_map(bp
, &baddr
) == 0) {
718 bzero(baddr
, bp
->b_bcount
);
727 * Read or write a buffer that is not contiguous on disk.
728 * buffer is marked done/error at the conclusion
731 buf_strategy_fragmented(vnode_t devvp
, buf_t bp
, off_t f_offset
, size_t contig_bytes
)
733 vnode_t vp
= buf_vnode(bp
);
734 buf_t io_bp
; /* For reading or writing a single block */
737 size_t io_contig_bytes
;
743 * save our starting point... the bp was already mapped
744 * in buf_strategy before we got called
745 * no sense doing it again.
747 io_blkno
= bp
->b_blkno
;
749 * Make sure we redo this mapping for the next I/O
750 * i.e. this can never be a 'permanent' mapping
752 bp
->b_blkno
= bp
->b_lblkno
;
755 * Get an io buffer to do the deblocking
757 io_bp
= alloc_io_buf(devvp
, 0);
759 io_bp
->b_lblkno
= bp
->b_lblkno
;
760 io_bp
->b_datap
= bp
->b_datap
;
761 io_resid
= bp
->b_bcount
;
762 io_direction
= bp
->b_flags
& B_READ
;
763 io_contig_bytes
= contig_bytes
;
765 if (bp
->b_flags
& B_READ
)
766 bmap_flags
= VNODE_READ
;
768 bmap_flags
= VNODE_WRITE
;
773 * this is unexepected, but we'll allow for it
775 bzero((caddr_t
)io_bp
->b_datap
, (int)io_contig_bytes
);
777 io_bp
->b_bcount
= io_contig_bytes
;
778 io_bp
->b_bufsize
= io_contig_bytes
;
779 io_bp
->b_resid
= io_contig_bytes
;
780 io_bp
->b_blkno
= io_blkno
;
782 buf_reset(io_bp
, io_direction
);
784 * Call the device to do the I/O and wait for it
786 if ((error
= VNOP_STRATEGY(io_bp
)))
788 if ((error
= (int)buf_biowait(io_bp
)))
790 if (io_bp
->b_resid
) {
791 io_resid
-= (io_contig_bytes
- io_bp
->b_resid
);
795 if ((io_resid
-= io_contig_bytes
) == 0)
797 f_offset
+= io_contig_bytes
;
798 io_bp
->b_datap
+= io_contig_bytes
;
801 * Map the current position to a physical block number
803 if ((error
= VNOP_BLOCKMAP(vp
, f_offset
, io_resid
, &io_blkno
, &io_contig_bytes
, NULL
, bmap_flags
, NULL
)))
809 buf_seterror(bp
, error
);
810 bp
->b_resid
= io_resid
;
812 * This I/O is now complete
821 * struct vnop_strategy_args {
826 buf_strategy(vnode_t devvp
, void *ap
)
828 buf_t bp
= ((struct vnop_strategy_args
*)ap
)->a_bp
;
829 vnode_t vp
= bp
->b_vp
;
833 if (vp
== NULL
|| vp
->v_type
== VCHR
|| vp
->v_type
== VBLK
)
834 panic("buf_strategy: b_vp == NULL || vtype == VCHR | VBLK\n");
836 * associate the physical device with
837 * with this buf_t even if we don't
838 * end up issuing the I/O...
840 bp
->b_dev
= devvp
->v_rdev
;
842 if (bp
->b_flags
& B_READ
)
843 bmap_flags
= VNODE_READ
;
845 bmap_flags
= VNODE_WRITE
;
847 if ( !(bp
->b_flags
& B_CLUSTER
)) {
851 * we have a UPL associated with this bp
852 * go through cluster_bp which knows how
853 * to deal with filesystem block sizes
854 * that aren't equal to the page size
856 return (cluster_bp(bp
));
858 if (bp
->b_blkno
== bp
->b_lblkno
) {
862 if ((error
= VNOP_BLKTOOFF(vp
, bp
->b_lblkno
, &f_offset
))) {
863 buf_seterror(bp
, error
);
868 if ((error
= VNOP_BLOCKMAP(vp
, f_offset
, bp
->b_bcount
, &bp
->b_blkno
, &contig_bytes
, NULL
, bmap_flags
, NULL
))) {
869 buf_seterror(bp
, error
);
874 if (bp
->b_blkno
== -1)
876 else if ((long)contig_bytes
< bp
->b_bcount
)
877 return (buf_strategy_fragmented(devvp
, bp
, f_offset
, contig_bytes
));
879 if (bp
->b_blkno
== -1) {
885 * we can issue the I/O because...
886 * either B_CLUSTER is set which
887 * means that the I/O is properly set
888 * up to be a multiple of the page size, or
889 * we were able to successfully set up the
890 * phsyical block mapping
892 return (VOCALL(devvp
->v_op
, VOFFSET(vnop_strategy
), ap
));
898 buf_alloc(vnode_t vp
)
900 return(alloc_io_buf(vp
, 0));
912 buf_iterate(vnode_t vp
, int (*callout
)(buf_t
, void *), int flags
, void *arg
) {
915 struct buflists local_iterblkhd
;
916 int lock_flags
= BAC_NOWAIT
| BAC_REMOVE
;
918 if (flags
& BUF_SKIP_LOCKED
)
919 lock_flags
|= BAC_SKIP_LOCKED
;
920 if (flags
& BUF_SKIP_NONLOCKED
)
921 lock_flags
|= BAC_SKIP_NONLOCKED
;
923 lck_mtx_lock(buf_mtxp
);
925 if (buf_iterprepare(vp
, &local_iterblkhd
, VBI_DIRTY
)) {
926 lck_mtx_unlock(buf_mtxp
);
929 while (!LIST_EMPTY(&local_iterblkhd
)) {
930 bp
= LIST_FIRST(&local_iterblkhd
);
931 LIST_REMOVE(bp
, b_vnbufs
);
932 LIST_INSERT_HEAD(&vp
->v_dirtyblkhd
, bp
, b_vnbufs
);
934 if (buf_acquire_locked(bp
, lock_flags
, 0, 0))
937 lck_mtx_unlock(buf_mtxp
);
939 retval
= callout(bp
, arg
);
947 case BUF_RETURNED_DONE
:
949 lck_mtx_lock(buf_mtxp
);
951 case BUF_CLAIMED_DONE
:
952 lck_mtx_lock(buf_mtxp
);
955 lck_mtx_lock(buf_mtxp
);
958 buf_itercomplete(vp
, &local_iterblkhd
, VBI_DIRTY
);
960 lck_mtx_unlock(buf_mtxp
);
965 * Flush out and invalidate all buffers associated with a vnode.
968 buf_invalidateblks(vnode_t vp
, int flags
, int slpflag
, int slptimeo
)
973 struct buflists local_iterblkhd
;
975 lck_mtx_lock(buf_mtxp
);
978 if (must_rescan
== 0)
980 * the lists may not be empty, but all that's left at this
981 * point are metadata or B_LOCKED buffers which are being
982 * skipped... we know this because we made it through both
983 * the clean and dirty lists without dropping buf_mtxp...
984 * each time we drop buf_mtxp we bump "must_rescan"
987 if (LIST_EMPTY(&vp
->v_cleanblkhd
) && LIST_EMPTY(&vp
->v_dirtyblkhd
))
991 * iterate the clean list
993 if (buf_iterprepare(vp
, &local_iterblkhd
, VBI_CLEAN
)) {
996 while (!LIST_EMPTY(&local_iterblkhd
)) {
997 bp
= LIST_FIRST(&local_iterblkhd
);
999 LIST_REMOVE(bp
, b_vnbufs
);
1000 LIST_INSERT_HEAD(&vp
->v_cleanblkhd
, bp
, b_vnbufs
);
1003 * some filesystems distinguish meta data blocks with a negative logical block #
1005 if ((flags
& BUF_SKIP_META
) && (bp
->b_lblkno
< 0 || ISSET(bp
->b_flags
, B_META
)))
1008 if ( (error
= (int)buf_acquire_locked(bp
, BAC_REMOVE
| BAC_SKIP_LOCKED
, slpflag
, slptimeo
)) ) {
1009 if (error
== EDEADLK
)
1011 * this buffer was marked B_LOCKED...
1012 * we didn't drop buf_mtxp, so we
1013 * we don't need to rescan
1016 if (error
== EAGAIN
) {
1018 * found a busy buffer... we blocked and
1019 * dropped buf_mtxp, so we're going to
1020 * need to rescan after this pass is completed
1026 * got some kind of 'real' error out of the msleep
1027 * in buf_acquire_locked, terminate the scan and return the error
1029 buf_itercomplete(vp
, &local_iterblkhd
, VBI_CLEAN
);
1031 lck_mtx_unlock(buf_mtxp
);
1034 lck_mtx_unlock(buf_mtxp
);
1036 SET(bp
->b_flags
, B_INVAL
);
1039 lck_mtx_lock(buf_mtxp
);
1042 * by dropping buf_mtxp, we allow new
1043 * buffers to be added to the vnode list(s)
1044 * we'll have to rescan at least once more
1045 * if the queues aren't empty
1049 buf_itercomplete(vp
, &local_iterblkhd
, VBI_CLEAN
);
1053 * Now iterate on dirty blks
1055 if (buf_iterprepare(vp
, &local_iterblkhd
, VBI_DIRTY
)) {
1058 while (!LIST_EMPTY(&local_iterblkhd
)) {
1059 bp
= LIST_FIRST(&local_iterblkhd
);
1061 LIST_REMOVE(bp
, b_vnbufs
);
1062 LIST_INSERT_HEAD(&vp
->v_dirtyblkhd
, bp
, b_vnbufs
);
1065 * some filesystems distinguish meta data blocks with a negative logical block #
1067 if ((flags
& BUF_SKIP_META
) && (bp
->b_lblkno
< 0 || ISSET(bp
->b_flags
, B_META
)))
1070 if ( (error
= (int)buf_acquire_locked(bp
, BAC_REMOVE
| BAC_SKIP_LOCKED
, slpflag
, slptimeo
)) ) {
1071 if (error
== EDEADLK
)
1073 * this buffer was marked B_LOCKED...
1074 * we didn't drop buf_mtxp, so we
1075 * we don't need to rescan
1078 if (error
== EAGAIN
) {
1080 * found a busy buffer... we blocked and
1081 * dropped buf_mtxp, so we're going to
1082 * need to rescan after this pass is completed
1088 * got some kind of 'real' error out of the msleep
1089 * in buf_acquire_locked, terminate the scan and return the error
1091 buf_itercomplete(vp
, &local_iterblkhd
, VBI_DIRTY
);
1093 lck_mtx_unlock(buf_mtxp
);
1096 lck_mtx_unlock(buf_mtxp
);
1098 SET(bp
->b_flags
, B_INVAL
);
1100 if (ISSET(bp
->b_flags
, B_DELWRI
) && (flags
& BUF_WRITE_DATA
))
1101 (void) VNOP_BWRITE(bp
);
1105 lck_mtx_lock(buf_mtxp
);
1107 * by dropping buf_mtxp, we allow new
1108 * buffers to be added to the vnode list(s)
1109 * we'll have to rescan at least once more
1110 * if the queues aren't empty
1114 buf_itercomplete(vp
, &local_iterblkhd
, VBI_DIRTY
);
1116 lck_mtx_unlock(buf_mtxp
);
1122 buf_flushdirtyblks(vnode_t vp
, int wait
, int flags
, char *msg
) {
1124 int writes_issued
= 0;
1127 struct buflists local_iterblkhd
;
1128 int lock_flags
= BAC_NOWAIT
| BAC_REMOVE
;
1130 if (flags
& BUF_SKIP_LOCKED
)
1131 lock_flags
|= BAC_SKIP_LOCKED
;
1132 if (flags
& BUF_SKIP_NONLOCKED
)
1133 lock_flags
|= BAC_SKIP_NONLOCKED
;
1135 lck_mtx_lock(buf_mtxp
);
1137 if (buf_iterprepare(vp
, &local_iterblkhd
, VBI_DIRTY
) == 0) {
1138 while (!LIST_EMPTY(&local_iterblkhd
)) {
1139 bp
= LIST_FIRST(&local_iterblkhd
);
1140 LIST_REMOVE(bp
, b_vnbufs
);
1141 LIST_INSERT_HEAD(&vp
->v_dirtyblkhd
, bp
, b_vnbufs
);
1143 if ((error
= buf_acquire_locked(bp
, lock_flags
, 0, 0)) == EBUSY
)
1147 lck_mtx_unlock(buf_mtxp
);
1149 bp
->b_flags
&= ~B_LOCKED
;
1152 * Wait for I/O associated with indirect blocks to complete,
1153 * since there is no way to quickly wait for them below.
1155 if ((bp
->b_vp
== vp
) || (wait
== 0))
1156 (void) buf_bawrite(bp
);
1158 (void) VNOP_BWRITE(bp
);
1161 lck_mtx_lock(buf_mtxp
);
1163 buf_itercomplete(vp
, &local_iterblkhd
, VBI_DIRTY
);
1165 lck_mtx_unlock(buf_mtxp
);
1168 (void)vnode_waitforwrites(vp
, 0, 0, 0, msg
);
1170 if (vp
->v_dirtyblkhd
.lh_first
&& busy
) {
1172 * we had one or more BUSY buffers on
1173 * the dirtyblock list... most likely
1174 * these are due to delayed writes that
1175 * were moved to the bclean queue but
1176 * have not yet been 'written'.
1177 * if we issued some writes on the
1178 * previous pass, we try again immediately
1179 * if we didn't, we'll sleep for some time
1180 * to allow the state to change...
1182 if (writes_issued
== 0) {
1183 (void)tsleep((caddr_t
)&vp
->v_numoutput
,
1184 PRIBIO
+ 1, "vnode_flushdirtyblks", hz
/20);
1196 * called with buf_mtxp held...
1197 * this lock protects the queue manipulation
1200 buf_iterprepare(vnode_t vp
, struct buflists
*iterheadp
, int flags
)
1202 struct buflists
* listheadp
;
1204 if (flags
& VBI_DIRTY
)
1205 listheadp
= &vp
->v_dirtyblkhd
;
1207 listheadp
= &vp
->v_cleanblkhd
;
1209 while (vp
->v_iterblkflags
& VBI_ITER
) {
1210 vp
->v_iterblkflags
|= VBI_ITERWANT
;
1211 msleep(&vp
->v_iterblkflags
, buf_mtxp
, 0, "buf_iterprepare", 0);
1213 if (LIST_EMPTY(listheadp
)) {
1214 LIST_INIT(iterheadp
);
1217 vp
->v_iterblkflags
|= VBI_ITER
;
1219 iterheadp
->lh_first
= listheadp
->lh_first
;
1220 listheadp
->lh_first
->b_vnbufs
.le_prev
= &iterheadp
->lh_first
;
1221 LIST_INIT(listheadp
);
1227 * called with buf_mtxp held...
1228 * this lock protects the queue manipulation
1231 buf_itercomplete(vnode_t vp
, struct buflists
*iterheadp
, int flags
)
1233 struct buflists
* listheadp
;
1236 if (flags
& VBI_DIRTY
)
1237 listheadp
= &vp
->v_dirtyblkhd
;
1239 listheadp
= &vp
->v_cleanblkhd
;
1241 while (!LIST_EMPTY(iterheadp
)) {
1242 bp
= LIST_FIRST(iterheadp
);
1243 LIST_REMOVE(bp
, b_vnbufs
);
1244 LIST_INSERT_HEAD(listheadp
, bp
, b_vnbufs
);
1246 vp
->v_iterblkflags
&= ~VBI_ITER
;
1248 if (vp
->v_iterblkflags
& VBI_ITERWANT
) {
1249 vp
->v_iterblkflags
&= ~VBI_ITERWANT
;
1250 wakeup(&vp
->v_iterblkflags
);
1256 bremfree_locked(buf_t bp
)
1258 struct bqueues
*dp
= NULL
;
1262 * We only calculate the head of the freelist when removing
1263 * the last element of the list as that is the only time that
1264 * it is needed (e.g. to reset the tail pointer).
1266 * NB: This makes an assumption about how tailq's are implemented.
1268 if (bp
->b_freelist
.tqe_next
== NULL
) {
1269 for (dp
= bufqueues
; dp
< &bufqueues
[BQUEUES
]; dp
++)
1270 if (dp
->tqh_last
== &bp
->b_freelist
.tqe_next
)
1272 if (dp
== &bufqueues
[BQUEUES
])
1273 panic("bremfree: lost tail");
1275 TAILQ_REMOVE(dp
, bp
, b_freelist
);
1276 whichq
= bp
->b_whichq
;
1281 bp
->b_timestamp
= 0;
1285 * Associate a buffer with a vnode.
1288 bgetvp(vnode_t vp
, buf_t bp
)
1292 panic("bgetvp: not free");
1294 if (vp
->v_type
== VBLK
|| vp
->v_type
== VCHR
)
1295 bp
->b_dev
= vp
->v_rdev
;
1299 * Insert onto list for new vnode.
1301 lck_mtx_lock(buf_mtxp
);
1302 bufinsvn(bp
, &vp
->v_cleanblkhd
);
1303 lck_mtx_unlock(buf_mtxp
);
1307 * Disassociate a buffer from a vnode.
1314 if ((vp
= bp
->b_vp
) == (vnode_t
)NULL
)
1315 panic("brelvp: NULL vp");
1317 * Delete from old vnode list, if on one.
1319 lck_mtx_lock(buf_mtxp
);
1320 if (bp
->b_vnbufs
.le_next
!= NOLIST
)
1322 lck_mtx_unlock(buf_mtxp
);
1324 bp
->b_vp
= (vnode_t
)NULL
;
1328 * Reassign a buffer from one vnode to another.
1329 * Used to assign file specific control information
1330 * (indirect blocks) to the vnode to which they belong.
1333 buf_reassign(buf_t bp
, vnode_t newvp
)
1335 register struct buflists
*listheadp
;
1337 if (newvp
== NULL
) {
1338 printf("buf_reassign: NULL");
1341 lck_mtx_lock(buf_mtxp
);
1344 * Delete from old vnode list, if on one.
1346 if (bp
->b_vnbufs
.le_next
!= NOLIST
)
1349 * If dirty, put on list of dirty buffers;
1350 * otherwise insert onto list of clean buffers.
1352 if (ISSET(bp
->b_flags
, B_DELWRI
))
1353 listheadp
= &newvp
->v_dirtyblkhd
;
1355 listheadp
= &newvp
->v_cleanblkhd
;
1356 bufinsvn(bp
, listheadp
);
1358 lck_mtx_unlock(buf_mtxp
);
1361 static __inline__
void
1362 bufhdrinit(buf_t bp
)
1364 bzero((char *)bp
, sizeof *bp
);
1366 bp
->b_rcred
= NOCRED
;
1367 bp
->b_wcred
= NOCRED
;
1368 bp
->b_vnbufs
.le_next
= NOLIST
;
1369 bp
->b_flags
= B_INVAL
;
1375 * Initialize buffers and hash links for buffers.
1377 __private_extern__
void
1387 /* Initialize the buffer queues ('freelists') and the hash table */
1388 for (dp
= bufqueues
; dp
< &bufqueues
[BQUEUES
]; dp
++)
1390 bufhashtbl
= hashinit(nbuf_hashelements
, M_CACHE
, &bufhash
);
1392 metabuf
= max_nbuf_headers
/8; /* reserved for meta buf */
1394 /* Initialize the buffer headers */
1395 for (i
= 0; i
< max_nbuf_headers
; i
++) {
1401 * metabuf buffer headers on the meta-data list and
1402 * rest of the buffer headers on the empty list
1410 dp
= &bufqueues
[whichq
];
1411 binsheadfree(bp
, dp
, whichq
);
1412 binshash(bp
, &invalhash
);
1417 for (; i
< nbuf
+ niobuf
; i
++) {
1420 binsheadfree(bp
, &iobufqueue
, -1);
1424 * allocate lock group attribute and group
1426 buf_mtx_grp_attr
= lck_grp_attr_alloc_init();
1427 buf_mtx_grp
= lck_grp_alloc_init("buffer cache", buf_mtx_grp_attr
);
1430 * allocate the lock attribute
1432 buf_mtx_attr
= lck_attr_alloc_init();
1435 * allocate and initialize mutex's for the buffer and iobuffer pools
1437 buf_mtxp
= lck_mtx_alloc_init(buf_mtx_grp
, buf_mtx_attr
);
1438 iobuffer_mtxp
= lck_mtx_alloc_init(buf_mtx_grp
, buf_mtx_attr
);
1440 if (iobuffer_mtxp
== NULL
)
1441 panic("couldn't create iobuffer mutex");
1443 if (buf_mtxp
== NULL
)
1444 panic("couldn't create buf mutex");
1447 * allocate and initialize cluster specific global locks...
1451 printf("using %d buffer headers and %d cluster IO buffer headers\n",
1454 /* Set up zones used by the buffer cache */
1457 /* start the bcleanbuf() thread */
1458 bcleanbuf_thread_init();
1462 static void bufq_balance_thread_init();
1463 /* create a thread to do dynamic buffer queue balancing */
1464 bufq_balance_thread_init();
1470 bio_doread(vnode_t vp
, daddr64_t blkno
, int size
, ucred_t cred
, int async
, int queuetype
)
1474 bp
= buf_getblk(vp
, blkno
, size
, 0, 0, queuetype
);
1477 * If buffer does not have data valid, start a read.
1478 * Note that if buffer is B_INVAL, buf_getblk() won't return it.
1479 * Therefore, it's valid if it's I/O has completed or been delayed.
1481 if (!ISSET(bp
->b_flags
, (B_DONE
| B_DELWRI
))) {
1486 /* Start I/O for the buffer (keeping credentials). */
1487 SET(bp
->b_flags
, B_READ
| async
);
1488 if (cred
!= NOCRED
&& bp
->b_rcred
== NOCRED
) {
1489 kauth_cred_ref(cred
);
1495 trace(TR_BREADMISS
, pack(vp
, size
), blkno
);
1497 /* Pay for the read. */
1498 if (p
&& p
->p_stats
)
1499 p
->p_stats
->p_ru
.ru_inblock
++; /* XXX */
1503 * since we asked for an ASYNC I/O
1504 * the biodone will do the brelse
1505 * we don't want to pass back a bp
1506 * that we don't 'own'
1515 trace(TR_BREADHIT
, pack(vp
, size
), blkno
);
1521 * Perform the reads for buf_breadn() and buf_meta_breadn().
1522 * Trivial modification to the breada algorithm presented in Bach (p.55).
1525 do_breadn_for_type(vnode_t vp
, daddr64_t blkno
, int size
, daddr64_t
*rablks
, int *rasizes
,
1526 int nrablks
, ucred_t cred
, buf_t
*bpp
, int queuetype
)
1531 bp
= *bpp
= bio_doread(vp
, blkno
, size
, cred
, 0, queuetype
);
1534 * For each of the read-ahead blocks, start a read, if necessary.
1536 for (i
= 0; i
< nrablks
; i
++) {
1537 /* If it's in the cache, just go on to next one. */
1538 if (incore(vp
, rablks
[i
]))
1541 /* Get a buffer for the read-ahead block */
1542 (void) bio_doread(vp
, rablks
[i
], rasizes
[i
], cred
, B_ASYNC
, queuetype
);
1545 /* Otherwise, we had to start a read for it; wait until it's valid. */
1546 return (buf_biowait(bp
));
1551 * Read a disk block.
1552 * This algorithm described in Bach (p.54).
1555 buf_bread(vnode_t vp
, daddr64_t blkno
, int size
, ucred_t cred
, buf_t
*bpp
)
1559 /* Get buffer for block. */
1560 bp
= *bpp
= bio_doread(vp
, blkno
, size
, cred
, 0, BLK_READ
);
1562 /* Wait for the read to complete, and return result. */
1563 return (buf_biowait(bp
));
1567 * Read a disk block. [bread() for meta-data]
1568 * This algorithm described in Bach (p.54).
1571 buf_meta_bread(vnode_t vp
, daddr64_t blkno
, int size
, ucred_t cred
, buf_t
*bpp
)
1575 /* Get buffer for block. */
1576 bp
= *bpp
= bio_doread(vp
, blkno
, size
, cred
, 0, BLK_META
);
1578 /* Wait for the read to complete, and return result. */
1579 return (buf_biowait(bp
));
1583 * Read-ahead multiple disk blocks. The first is sync, the rest async.
1586 buf_breadn(vnode_t vp
, daddr64_t blkno
, int size
, daddr64_t
*rablks
, int *rasizes
, int nrablks
, ucred_t cred
, buf_t
*bpp
)
1588 return (do_breadn_for_type(vp
, blkno
, size
, rablks
, rasizes
, nrablks
, cred
, bpp
, BLK_READ
));
1592 * Read-ahead multiple disk blocks. The first is sync, the rest async.
1593 * [buf_breadn() for meta-data]
1596 buf_meta_breadn(vnode_t vp
, daddr64_t blkno
, int size
, daddr64_t
*rablks
, int *rasizes
, int nrablks
, ucred_t cred
, buf_t
*bpp
)
1598 return (do_breadn_for_type(vp
, blkno
, size
, rablks
, rasizes
, nrablks
, cred
, bpp
, BLK_META
));
1602 * Block write. Described in Bach (p.56)
1605 buf_bwrite(buf_t bp
)
1607 int sync
, wasdelayed
;
1609 proc_t p
= current_proc();
1610 vnode_t vp
= bp
->b_vp
;
1612 if (bp
->b_datap
== 0) {
1613 if (brecover_data(bp
) == 0)
1616 /* Remember buffer type, to switch on it later. */
1617 sync
= !ISSET(bp
->b_flags
, B_ASYNC
);
1618 wasdelayed
= ISSET(bp
->b_flags
, B_DELWRI
);
1619 CLR(bp
->b_flags
, (B_READ
| B_DONE
| B_ERROR
| B_DELWRI
));
1622 OSAddAtomic(-1, &nbdwrite
);
1626 * If not synchronous, pay for the I/O operation and make
1627 * sure the buf is on the correct vnode queue. We have
1628 * to do this now, because if we don't, the vnode may not
1629 * be properly notified that its I/O has completed.
1632 buf_reassign(bp
, vp
);
1634 if (p
&& p
->p_stats
)
1635 p
->p_stats
->p_ru
.ru_oublock
++; /* XXX */
1637 trace(TR_BUFWRITE
, pack(vp
, bp
->b_bcount
), bp
->b_lblkno
);
1639 /* Initiate disk write. Make sure the appropriate party is charged. */
1641 OSAddAtomic(1, &vp
->v_numoutput
);
1647 * If I/O was synchronous, wait for it to complete.
1649 rv
= buf_biowait(bp
);
1652 * Pay for the I/O operation, if it's not been paid for, and
1653 * make sure it's on the correct vnode queue. (async operatings
1654 * were payed for above.)
1657 buf_reassign(bp
, vp
);
1659 if (p
&& p
->p_stats
)
1660 p
->p_stats
->p_ru
.ru_oublock
++; /* XXX */
1662 /* Release the buffer. */
1663 // XXXdbg - only if the unused bit is set
1664 if (!ISSET(bp
->b_flags
, B_NORELSE
)) {
1667 CLR(bp
->b_flags
, B_NORELSE
);
1678 struct vnop_bwrite_args
*ap
;
1680 return (buf_bwrite(ap
->a_bp
));
1686 * The buffer is marked dirty, but is not queued for I/O.
1687 * This routine should be used when the buffer is expected
1688 * to be modified again soon, typically a small write that
1689 * partially fills a buffer.
1691 * NB: magnetic tapes cannot be delayed; they must be
1692 * written in the order that the writes are requested.
1694 * Described in Leffler, et al. (pp. 208-213).
1696 * Note: With the abilitty to allocate additional buffer
1697 * headers, we can get in to the situation where "too" many
1698 * buf_bdwrite()s can create situation where the kernel can create
1699 * buffers faster than the disks can service. Doing a buf_bawrite() in
1700 * cases were we have "too many" outstanding buf_bdwrite()s avoids that.
1702 __private_extern__
int
1703 bdwrite_internal(buf_t bp
, int return_error
)
1705 proc_t p
= current_proc();
1706 vnode_t vp
= bp
->b_vp
;
1709 * If the block hasn't been seen before:
1710 * (1) Mark it as having been seen,
1711 * (2) Charge for the write.
1712 * (3) Make sure it's on its vnode's correct block list,
1714 if (!ISSET(bp
->b_flags
, B_DELWRI
)) {
1715 SET(bp
->b_flags
, B_DELWRI
);
1716 if (p
&& p
->p_stats
)
1717 p
->p_stats
->p_ru
.ru_oublock
++; /* XXX */
1718 OSAddAtomic(1, &nbdwrite
);
1719 buf_reassign(bp
, vp
);
1722 /* If this is a tape block, write it the block now. */
1723 if (ISSET(bp
->b_flags
, B_TAPE
)) {
1729 * if we're not LOCKED, but the total number of delayed writes
1730 * has climbed above 75% of the total buffers in the system
1731 * return an error if the caller has indicated that it can
1732 * handle one in this case, otherwise schedule the I/O now
1733 * this is done to prevent us from allocating tons of extra
1734 * buffers when dealing with virtual disks (i.e. DiskImages),
1735 * because additional buffers are dynamically allocated to prevent
1736 * deadlocks from occurring
1738 * however, can't do a buf_bawrite() if the LOCKED bit is set because the
1739 * buffer is part of a transaction and can't go to disk until
1740 * the LOCKED bit is cleared.
1742 if (!ISSET(bp
->b_flags
, B_LOCKED
) && nbdwrite
> ((nbuf
/4)*3)) {
1746 * If the vnode has "too many" write operations in progress
1747 * wait for them to finish the IO
1749 (void)vnode_waitforwrites(vp
, VNODE_ASYNC_THROTTLE
, 0, 0, (char *)"buf_bdwrite");
1751 return (buf_bawrite(bp
));
1754 /* Otherwise, the "write" is done, so mark and release the buffer. */
1755 SET(bp
->b_flags
, B_DONE
);
1761 buf_bdwrite(buf_t bp
)
1763 return (bdwrite_internal(bp
, 0));
1768 * Asynchronous block write; just an asynchronous buf_bwrite().
1770 * Note: With the abilitty to allocate additional buffer
1771 * headers, we can get in to the situation where "too" many
1772 * buf_bawrite()s can create situation where the kernel can create
1773 * buffers faster than the disks can service.
1774 * We limit the number of "in flight" writes a vnode can have to
1778 bawrite_internal(buf_t bp
, int throttle
)
1780 vnode_t vp
= bp
->b_vp
;
1785 * If the vnode has "too many" write operations in progress
1786 * wait for them to finish the IO
1788 (void)vnode_waitforwrites(vp
, VNODE_ASYNC_THROTTLE
, 0, 0, (const char *)"buf_bawrite");
1789 else if (vp
->v_numoutput
>= VNODE_ASYNC_THROTTLE
)
1791 * return to the caller and
1792 * let him decide what to do
1794 return (EWOULDBLOCK
);
1796 SET(bp
->b_flags
, B_ASYNC
);
1798 return (VNOP_BWRITE(bp
));
1802 buf_bawrite(buf_t bp
)
1804 return (bawrite_internal(bp
, 1));
1809 * Release a buffer on to the free lists.
1810 * Described in Bach (p. 46).
1813 buf_brelse(buf_t bp
)
1815 struct bqueues
*bufq
;
1818 int need_wakeup
= 0;
1819 int need_bp_wakeup
= 0;
1822 if (bp
->b_whichq
!= -1 || !(bp
->b_lflags
& BL_BUSY
))
1823 panic("buf_brelse: bad buffer = %x\n", bp
);
1826 bp
->b_stackbrelse
[0] = __builtin_return_address(0);
1827 bp
->b_stackbrelse
[1] = __builtin_return_address(1);
1828 bp
->b_stackbrelse
[2] = __builtin_return_address(2);
1829 bp
->b_stackbrelse
[3] = __builtin_return_address(3);
1830 bp
->b_stackbrelse
[4] = __builtin_return_address(4);
1831 bp
->b_stackbrelse
[5] = __builtin_return_address(5);
1833 bp
->b_lastbrelse
= current_thread();
1836 if (bp
->b_lflags
& BL_IOBUF
) {
1841 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 388)) | DBG_FUNC_START
,
1842 bp
->b_lblkno
* PAGE_SIZE
, (int)bp
, (int)bp
->b_datap
,
1845 trace(TR_BRELSE
, pack(bp
->b_vp
, bp
->b_bufsize
), bp
->b_lblkno
);
1848 * if we're invalidating a buffer that has the B_FILTER bit
1849 * set then call the b_iodone function so it gets cleaned
1852 * the HFS journal code depends on this
1854 if (ISSET(bp
->b_flags
, B_META
) && ISSET(bp
->b_flags
, B_INVAL
)) {
1855 if (ISSET(bp
->b_flags
, B_FILTER
)) { /* if necessary, call out */
1856 void (*iodone_func
)(struct buf
*, void *) = bp
->b_iodone
;
1857 void *arg
= (void *)bp
->b_transaction
;
1859 CLR(bp
->b_flags
, B_FILTER
); /* but note callout done */
1860 bp
->b_iodone
= NULL
;
1861 bp
->b_transaction
= NULL
;
1863 if (iodone_func
== NULL
) {
1864 panic("brelse: bp @ 0x%x has NULL b_iodone!\n", bp
);
1866 (*iodone_func
)(bp
, arg
);
1870 * I/O is done. Cleanup the UPL state
1874 if ( !ISSET(bp
->b_flags
, B_META
) && UBCINFOEXISTS(bp
->b_vp
) && bp
->b_bufsize
) {
1878 if ( (upl
== NULL
) ) {
1879 if ( !ISSET(bp
->b_flags
, B_INVAL
)) {
1880 kret
= ubc_create_upl(bp
->b_vp
,
1881 ubc_blktooff(bp
->b_vp
, bp
->b_lblkno
),
1887 if (kret
!= KERN_SUCCESS
)
1888 panic("brelse: Failed to create UPL");
1890 upl_ubc_alias_set(upl
, bp
, 5);
1891 #endif /* UPL_DEBUG */
1895 kret
= ubc_upl_unmap(upl
);
1897 if (kret
!= KERN_SUCCESS
)
1898 panic("ubc_upl_unmap failed");
1899 bp
->b_datap
= (uintptr_t)NULL
;
1903 if (bp
->b_flags
& (B_ERROR
| B_INVAL
)) {
1904 if (bp
->b_flags
& (B_READ
| B_INVAL
))
1905 upl_flags
= UPL_ABORT_DUMP_PAGES
;
1909 ubc_upl_abort(upl
, upl_flags
);
1911 if (ISSET(bp
->b_flags
, B_DELWRI
| B_WASDIRTY
))
1912 upl_flags
= UPL_COMMIT_SET_DIRTY
;
1914 upl_flags
= UPL_COMMIT_CLEAR_DIRTY
;
1916 ubc_upl_commit_range(upl
, 0, bp
->b_bufsize
, upl_flags
|
1917 UPL_COMMIT_INACTIVATE
| UPL_COMMIT_FREE_ON_EMPTY
);
1923 panic("brelse: UPL set for non VREG; vp=%x", bp
->b_vp
);
1927 * If it's locked, don't report an error; try again later.
1929 if (ISSET(bp
->b_flags
, (B_LOCKED
|B_ERROR
)) == (B_LOCKED
|B_ERROR
))
1930 CLR(bp
->b_flags
, B_ERROR
);
1932 * If it's not cacheable, or an error, mark it invalid.
1934 if (ISSET(bp
->b_flags
, (B_NOCACHE
|B_ERROR
)))
1935 SET(bp
->b_flags
, B_INVAL
);
1937 if ((bp
->b_bufsize
<= 0) || ISSET(bp
->b_flags
, B_INVAL
)) {
1939 * If it's invalid or empty, dissociate it from its vnode
1940 * and put on the head of the appropriate queue.
1945 if (ISSET(bp
->b_flags
, B_DELWRI
))
1946 OSAddAtomic(-1, &nbdwrite
);
1948 CLR(bp
->b_flags
, (B_DELWRI
| B_LOCKED
| B_AGE
| B_ASYNC
| B_NOCACHE
));
1950 * Determine which queue the buffer should be on, then put it there.
1952 if (bp
->b_bufsize
<= 0)
1953 whichq
= BQ_EMPTY
; /* no data */
1954 else if (ISSET(bp
->b_flags
, B_META
))
1955 whichq
= BQ_META
; /* meta-data */
1957 whichq
= BQ_AGE
; /* invalid data */
1958 bufq
= &bufqueues
[whichq
];
1960 lck_mtx_lock(buf_mtxp
);
1962 binsheadfree(bp
, bufq
, whichq
);
1965 * It has valid data. Put it on the end of the appropriate
1966 * queue, so that it'll stick around for as long as possible.
1968 if (ISSET(bp
->b_flags
, B_LOCKED
))
1969 whichq
= BQ_LOCKED
; /* locked in core */
1970 else if (ISSET(bp
->b_flags
, B_META
))
1971 whichq
= BQ_META
; /* meta-data */
1972 else if (ISSET(bp
->b_flags
, B_AGE
))
1973 whichq
= BQ_AGE
; /* stale but valid data */
1975 whichq
= BQ_LRU
; /* valid data */
1976 bufq
= &bufqueues
[whichq
];
1978 CLR(bp
->b_flags
, (B_AGE
| B_ASYNC
| B_NOCACHE
));
1980 lck_mtx_lock(buf_mtxp
);
1982 binstailfree(bp
, bufq
, whichq
);
1986 * needbuffer is a global
1987 * we're currently using buf_mtxp to protect it
1988 * delay doing the actual wakeup until after
1994 if (ISSET(bp
->b_lflags
, BL_WANTED
)) {
1996 * delay the actual wakeup until after we
1997 * clear BL_BUSY and we've dropped buf_mtxp
2002 * Unlock the buffer.
2004 CLR(bp
->b_lflags
, (BL_BUSY
| BL_WANTED
));
2006 lck_mtx_unlock(buf_mtxp
);
2010 * Wake up any processes waiting for any buffer to become free.
2012 wakeup(&needbuffer
);
2014 if (need_bp_wakeup
) {
2016 * Wake up any proceeses waiting for _this_ buffer to become free.
2020 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 388)) | DBG_FUNC_END
,
2021 (int)bp
, (int)bp
->b_datap
, bp
->b_flags
, 0, 0);
2025 * Determine if a block is in the cache.
2026 * Just look on what would be its hash chain. If it's there, return
2027 * a pointer to it, unless it's marked invalid. If it's marked invalid,
2028 * we normally don't return the buffer, unless the caller explicitly
2032 incore(vnode_t vp
, daddr64_t blkno
)
2036 lck_mtx_lock(buf_mtxp
);
2038 if (incore_locked(vp
, blkno
))
2042 lck_mtx_unlock(buf_mtxp
);
2049 incore_locked(vnode_t vp
, daddr64_t blkno
)
2053 bp
= BUFHASH(vp
, blkno
)->lh_first
;
2055 /* Search hash chain */
2056 for (; bp
!= NULL
; bp
= bp
->b_hash
.le_next
) {
2057 if (bp
->b_lblkno
== blkno
&& bp
->b_vp
== vp
&&
2058 !ISSET(bp
->b_flags
, B_INVAL
)) {
2066 /* XXX FIXME -- Update the comment to reflect the UBC changes (please) -- */
2068 * Get a block of requested size that is associated with
2069 * a given vnode and block offset. If it is found in the
2070 * block cache, mark it as having been found, make it busy
2071 * and return it. Otherwise, return an empty block of the
2072 * correct size. It is up to the caller to insure that the
2073 * cached blocks be of the correct size.
2076 buf_getblk(vnode_t vp
, daddr64_t blkno
, int size
, int slpflag
, int slptimeo
, int operation
)
2081 upl_page_info_t
*pl
;
2087 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 386)) | DBG_FUNC_START
,
2088 (int)(blkno
* PAGE_SIZE
), size
, operation
, 0, 0);
2090 ret_only_valid
= operation
& BLK_ONLYVALID
;
2091 operation
&= ~BLK_ONLYVALID
;
2093 lck_mtx_lock(buf_mtxp
);
2095 if ((bp
= incore_locked(vp
, blkno
))) {
2097 * Found in the Buffer Cache
2099 if (ISSET(bp
->b_lflags
, BL_BUSY
)) {
2103 switch (operation
) {
2107 SET(bp
->b_lflags
, BL_WANTED
);
2108 bufstats
.bufs_busyincore
++;
2111 * don't retake the mutex after being awakened...
2112 * the time out is in msecs
2114 ts
.tv_sec
= (slptimeo
/1000);
2115 ts
.tv_nsec
= (slptimeo
% 1000) * 10 * NSEC_PER_USEC
* 1000;
2117 err
= msleep(bp
, buf_mtxp
, slpflag
| PDROP
| (PRIBIO
+ 1), "buf_getblk", &ts
);
2120 * Callers who call with PCATCH or timeout are
2121 * willing to deal with the NULL pointer
2123 if (err
&& ((slpflag
& PCATCH
) || ((err
== EWOULDBLOCK
) && slptimeo
)))
2131 * unknown operation requested
2133 panic("getblk: paging or unknown operation for incore busy buffer - %x\n", operation
);
2139 * buffer in core and not busy
2142 panic("buffer has UPL, but not marked BUSY: %x", bp
);
2143 SET(bp
->b_lflags
, BL_BUSY
);
2144 SET(bp
->b_flags
, B_CACHE
);
2146 bp
->b_owner
= current_thread();
2149 bremfree_locked(bp
);
2150 bufstats
.bufs_incore
++;
2152 lck_mtx_unlock(buf_mtxp
);
2154 if ( !ret_only_valid
)
2158 switch (operation
) {
2161 * "write" operation: let the UPL subsystem
2162 * know that we intend to modify the buffer
2163 * cache pages we're gathering.
2165 upl_flags
|= UPL_WILL_MODIFY
;
2167 upl_flags
|= UPL_PRECIOUS
;
2168 if (UBCINFOEXISTS(bp
->b_vp
) && bp
->b_bufsize
) {
2169 kret
= ubc_create_upl(vp
,
2170 ubc_blktooff(vp
, bp
->b_lblkno
),
2175 if (kret
!= KERN_SUCCESS
)
2176 panic("Failed to create UPL");
2180 if (upl_valid_page(pl
, 0)) {
2181 if (upl_dirty_page(pl
, 0))
2182 SET(bp
->b_flags
, B_WASDIRTY
);
2184 CLR(bp
->b_flags
, B_WASDIRTY
);
2186 CLR(bp
->b_flags
, (B_DONE
| B_CACHE
| B_WASDIRTY
| B_DELWRI
));
2188 kret
= ubc_upl_map(upl
, (vm_address_t
*)&(bp
->b_datap
));
2190 if (kret
!= KERN_SUCCESS
)
2191 panic("getblk: ubc_upl_map() failed with (%d)", kret
);
2197 * VM is not involved in IO for the meta data
2198 * buffer already has valid data
2203 panic("getblk: paging or unknown operation for incore buffer- %d\n", operation
);
2208 } else { /* not incore() */
2209 int queue
= BQ_EMPTY
; /* Start with no preference */
2211 if (ret_only_valid
) {
2212 lck_mtx_unlock(buf_mtxp
);
2216 if ((UBCINVALID(vp
)) || !(UBCINFOEXISTS(vp
)))
2217 operation
= BLK_META
;
2219 if ((bp
= getnewbuf(slpflag
, slptimeo
, &queue
)) == NULL
)
2223 * getnewbuf may block for a number of different reasons...
2224 * if it does, it's then possible for someone else to
2225 * create a buffer for the same block and insert it into
2226 * the hash... if we see it incore at this point we dump
2227 * the buffer we were working on and start over
2229 if (incore_locked(vp
, blkno
)) {
2230 SET(bp
->b_flags
, B_INVAL
);
2231 binshash(bp
, &invalhash
);
2233 lck_mtx_unlock(buf_mtxp
);
2239 * NOTE: YOU CAN NOT BLOCK UNTIL binshash() HAS BEEN
2240 * CALLED! BE CAREFUL.
2244 * mark the buffer as B_META if indicated
2245 * so that when buffer is released it will goto META queue
2247 if (operation
== BLK_META
)
2248 SET(bp
->b_flags
, B_META
);
2250 bp
->b_blkno
= bp
->b_lblkno
= blkno
;
2254 * Insert in the hash so that incore() can find it
2256 binshash(bp
, BUFHASH(vp
, blkno
));
2258 lck_mtx_unlock(buf_mtxp
);
2265 switch (operation
) {
2268 * buffer data is invalid...
2270 * I don't want to have to retake buf_mtxp,
2271 * so the miss and vmhits counters are done
2272 * with Atomic updates... all other counters
2273 * in bufstats are protected with either
2274 * buf_mtxp or iobuffer_mtxp
2276 OSAddAtomic(1, &bufstats
.bufs_miss
);
2281 * "write" operation: let the UPL subsystem know
2282 * that we intend to modify the buffer cache pages
2285 upl_flags
|= UPL_WILL_MODIFY
;
2288 size_t contig_bytes
;
2292 panic("bp already has UPL: %x",bp
);
2294 f_offset
= ubc_blktooff(vp
, blkno
);
2296 upl_flags
|= UPL_PRECIOUS
;
2297 kret
= ubc_create_upl(vp
,
2304 if (kret
!= KERN_SUCCESS
)
2305 panic("Failed to create UPL");
2307 upl_ubc_alias_set(upl
, bp
, 4);
2308 #endif /* UPL_DEBUG */
2311 if (upl_valid_page(pl
, 0)) {
2313 if (operation
== BLK_READ
)
2314 bmap_flags
= VNODE_READ
;
2316 bmap_flags
= VNODE_WRITE
;
2318 SET(bp
->b_flags
, B_CACHE
| B_DONE
);
2320 OSAddAtomic(1, &bufstats
.bufs_vmhits
);
2325 if (upl_dirty_page(pl
, 0)) {
2327 SET(bp
->b_flags
, B_WASDIRTY
);
2329 bp
->b_validend
= bp
->b_bcount
;
2330 bp
->b_dirtyend
= bp
->b_bcount
;
2333 bp
->b_validend
= bp
->b_bcount
;
2337 * try to recreate the physical block number associated with
2340 if (VNOP_BLOCKMAP(vp
, f_offset
, bp
->b_bcount
, &bp
->b_blkno
, &contig_bytes
, NULL
, bmap_flags
, NULL
))
2341 panic("getblk: VNOP_BLOCKMAP failed");
2343 * if the extent represented by this buffer
2344 * is not completely physically contiguous on
2345 * disk, than we can't cache the physical mapping
2346 * in the buffer header
2348 if ((long)contig_bytes
< bp
->b_bcount
)
2349 bp
->b_blkno
= bp
->b_lblkno
;
2351 OSAddAtomic(1, &bufstats
.bufs_miss
);
2353 kret
= ubc_upl_map(upl
, (vm_address_t
*)&(bp
->b_datap
));
2355 if (kret
!= KERN_SUCCESS
)
2356 panic("getblk: ubc_upl_map() failed with (%d)", kret
);
2360 panic("getblk: paging or unknown operation - %x", operation
);
2365 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 386)) | DBG_FUNC_END
,
2366 (int)bp
, (int)bp
->b_datap
, bp
->b_flags
, 3, 0);
2369 bp
->b_stackgetblk
[0] = __builtin_return_address(0);
2370 bp
->b_stackgetblk
[1] = __builtin_return_address(1);
2371 bp
->b_stackgetblk
[2] = __builtin_return_address(2);
2372 bp
->b_stackgetblk
[3] = __builtin_return_address(3);
2373 bp
->b_stackgetblk
[4] = __builtin_return_address(4);
2374 bp
->b_stackgetblk
[5] = __builtin_return_address(5);
2380 * Get an empty, disassociated buffer of given size.
2387 int queue
= BQ_EMPTY
;
2389 lck_mtx_lock(buf_mtxp
);
2391 while ((bp
= getnewbuf(0, 0, &queue
)) == 0)
2393 SET(bp
->b_flags
, (B_META
|B_INVAL
));
2396 assert(queue
== BQ_EMPTY
);
2397 #endif /* DIAGNOSTIC */
2398 /* XXX need to implement logic to deal with other queues */
2400 binshash(bp
, &invalhash
);
2401 bufstats
.bufs_eblk
++;
2403 lck_mtx_unlock(buf_mtxp
);
2411 * Zones for the meta data buffers
2415 #define MAXMETA 4096
2417 struct meta_zone_entry
{
2424 struct meta_zone_entry meta_zones
[] = {
2425 {NULL
, (MINMETA
* 1), 128 * (MINMETA
* 1), "buf.512" },
2426 {NULL
, (MINMETA
* 2), 64 * (MINMETA
* 2), "buf.1024" },
2427 {NULL
, (MINMETA
* 4), 16 * (MINMETA
* 4), "buf.2048" },
2428 {NULL
, (MINMETA
* 8), 512 * (MINMETA
* 8), "buf.4096" },
2429 {NULL
, 0, 0, "" } /* End */
2433 * Initialize the meta data zones
2440 for (i
= 0; meta_zones
[i
].mz_size
!= 0; i
++) {
2441 meta_zones
[i
].mz_zone
=
2442 zinit(meta_zones
[i
].mz_size
,
2443 meta_zones
[i
].mz_max
,
2445 meta_zones
[i
].mz_name
);
2447 buf_hdr_zone
= zinit(sizeof(struct buf
), 32, PAGE_SIZE
, "buf headers");
2450 static __inline__ zone_t
2451 getbufzone(size_t size
)
2455 if ((size
% 512) || (size
< MINMETA
) || (size
> MAXMETA
))
2456 panic("getbufzone: incorect size = %d", size
);
2458 for (i
= 0; meta_zones
[i
].mz_size
!= 0; i
++) {
2459 if (meta_zones
[i
].mz_size
>= size
)
2463 return (meta_zones
[i
].mz_zone
);
2467 * With UBC, there is no need to expand / shrink the file data
2468 * buffer. The VM uses the same pages, hence no waste.
2469 * All the file data buffers can have one size.
2470 * In fact expand / shrink would be an expensive operation.
2472 * Only exception to this is meta-data buffers. Most of the
2473 * meta data operations are smaller than PAGE_SIZE. Having the
2474 * meta-data buffers grow and shrink as needed, optimizes use
2475 * of the kernel wired memory.
2479 allocbuf(buf_t bp
, int size
)
2481 vm_size_t desired_size
;
2483 desired_size
= roundup(size
, CLBYTES
);
2485 if (desired_size
< PAGE_SIZE
)
2486 desired_size
= PAGE_SIZE
;
2487 if (desired_size
> MAXBSIZE
)
2488 panic("allocbuf: buffer larger than MAXBSIZE requested");
2490 if (ISSET(bp
->b_flags
, B_META
)) {
2492 int nsize
= roundup(size
, MINMETA
);
2495 vm_offset_t elem
= (vm_offset_t
)bp
->b_datap
;
2497 if (ISSET(bp
->b_flags
, B_ZALLOC
)) {
2498 if (bp
->b_bufsize
< nsize
) {
2499 /* reallocate to a bigger size */
2501 zprev
= getbufzone(bp
->b_bufsize
);
2502 if (nsize
<= MAXMETA
) {
2503 desired_size
= nsize
;
2504 z
= getbufzone(nsize
);
2505 bp
->b_datap
= (uintptr_t)zalloc(z
);
2507 bp
->b_datap
= (uintptr_t)NULL
;
2508 kmem_alloc_wired(kernel_map
, (vm_offset_t
*)&bp
->b_datap
, desired_size
);
2509 CLR(bp
->b_flags
, B_ZALLOC
);
2511 bcopy((void *)elem
, (caddr_t
)bp
->b_datap
, bp
->b_bufsize
);
2512 zfree(zprev
, (void *)elem
);
2514 desired_size
= bp
->b_bufsize
;
2518 if ((vm_size_t
)bp
->b_bufsize
< desired_size
) {
2519 /* reallocate to a bigger size */
2520 bp
->b_datap
= (uintptr_t)NULL
;
2521 kmem_alloc_wired(kernel_map
, (vm_offset_t
*)&bp
->b_datap
, desired_size
);
2522 bcopy((const void *)elem
, (caddr_t
)bp
->b_datap
, bp
->b_bufsize
);
2523 kmem_free(kernel_map
, elem
, bp
->b_bufsize
);
2525 desired_size
= bp
->b_bufsize
;
2529 /* new allocation */
2530 if (nsize
<= MAXMETA
) {
2531 desired_size
= nsize
;
2532 z
= getbufzone(nsize
);
2533 bp
->b_datap
= (uintptr_t)zalloc(z
);
2534 SET(bp
->b_flags
, B_ZALLOC
);
2536 kmem_alloc_wired(kernel_map
, (vm_offset_t
*)&bp
->b_datap
, desired_size
);
2539 bp
->b_bufsize
= desired_size
;
2540 bp
->b_bcount
= size
;
2546 * Get a new buffer from one of the free lists.
2548 * Request for a queue is passes in. The queue from which the buffer was taken
2549 * from is returned. Out of range queue requests get BQ_EMPTY. Request for
2550 * BQUEUE means no preference. Use heuristics in that case.
2551 * Heuristics is as follows:
2552 * Try BQ_AGE, BQ_LRU, BQ_EMPTY, BQ_META in that order.
2553 * If none available block till one is made available.
2554 * If buffers available on both BQ_AGE and BQ_LRU, check the timestamps.
2555 * Pick the most stale buffer.
2556 * If found buffer was marked delayed write, start the async. write
2557 * and restart the search.
2558 * Initialize the fields and disassociate the buffer from the vnode.
2559 * Remove the buffer from the hash. Return the buffer and the queue
2560 * on which it was found.
2562 * buf_mtxp is held upon entry
2563 * returns with buf_mtxp locked
2567 getnewbuf(int slpflag
, int slptimeo
, int * queue
)
2573 int age_time
, lru_time
, bp_time
, meta_time
;
2574 int req
= *queue
; /* save it for restarts */
2579 * invalid request gets empty queue
2581 if ((*queue
> BQUEUES
) || (*queue
< 0)
2582 || (*queue
== BQ_LAUNDRY
) || (*queue
== BQ_LOCKED
))
2584 /* need to grow number of bufs, add another one rather than recycling */
2585 if (nbuf
< max_nbuf_headers
) {
2587 * Increment count now as lock
2588 * is dropped for allocation.
2589 * That avoids over commits
2596 * (*queue == BQUEUES) means no preference
2598 if (*queue
!= BQUEUES
) {
2599 /* Try for the requested queue first */
2600 bp
= bufqueues
[*queue
].tqh_first
;
2605 /* Unable to use requested queue */
2606 age_bp
= bufqueues
[BQ_AGE
].tqh_first
;
2607 lru_bp
= bufqueues
[BQ_LRU
].tqh_first
;
2608 meta_bp
= bufqueues
[BQ_META
].tqh_first
;
2610 if (!age_bp
&& !lru_bp
&& !meta_bp
) {
2612 * Unavailble on AGE or LRU or META queues
2613 * Try the empty list first
2615 bp
= bufqueues
[BQ_EMPTY
].tqh_first
;
2621 * We have seen is this is hard to trigger.
2622 * This is an overcommit of nbufs but needed
2623 * in some scenarios with diskiamges
2627 lck_mtx_unlock(buf_mtxp
);
2629 /* Create a new temporary buffer header */
2630 bp
= (struct buf
*)zalloc(buf_hdr_zone
);
2632 lck_mtx_lock(buf_mtxp
);
2637 binshash(bp
, &invalhash
);
2638 SET(bp
->b_flags
, B_HDRALLOC
);
2640 binsheadfree(bp
, &bufqueues
[BQ_EMPTY
], BQ_EMPTY
);
2644 /* subtract already accounted bufcount */
2647 bufstats
.bufs_sleeps
++;
2649 /* wait for a free buffer of any kind */
2651 /* hz value is 100 */
2652 ts
.tv_sec
= (slptimeo
/1000);
2653 /* the hz value is 100; which leads to 10ms */
2654 ts
.tv_nsec
= (slptimeo
% 1000) * NSEC_PER_USEC
* 1000 * 10;
2655 msleep(&needbuffer
, buf_mtxp
, slpflag
|(PRIBIO
+1), (char *)"getnewbuf", &ts
);
2659 /* Buffer available either on AGE or LRU or META */
2663 /* Buffer available either on AGE or LRU */
2667 } else if (!lru_bp
) {
2670 } else { /* buffer available on both AGE and LRU */
2671 int t
= buf_timestamp();
2673 age_time
= t
- age_bp
->b_timestamp
;
2674 lru_time
= t
- lru_bp
->b_timestamp
;
2675 if ((age_time
< 0) || (lru_time
< 0)) { /* time set backwards */
2679 * we should probably re-timestamp eveything in the
2680 * queues at this point with the current time
2683 if ((lru_time
>= lru_is_stale
) && (age_time
< age_is_stale
)) {
2693 if (!bp
) { /* Neither on AGE nor on LRU */
2696 } else if (meta_bp
) {
2697 int t
= buf_timestamp();
2699 bp_time
= t
- bp
->b_timestamp
;
2700 meta_time
= t
- meta_bp
->b_timestamp
;
2702 if (!(bp_time
< 0) && !(meta_time
< 0)) {
2703 /* time not set backwards */
2705 bp_is_stale
= (*queue
== BQ_LRU
) ?
2706 lru_is_stale
: age_is_stale
;
2708 if ((meta_time
>= meta_is_stale
) &&
2709 (bp_time
< bp_is_stale
)) {
2716 if (ISSET(bp
->b_flags
, B_LOCKED
) || ISSET(bp
->b_lflags
, BL_BUSY
))
2717 panic("getnewbuf: bp @ 0x%x is LOCKED or BUSY! (flags 0x%x)\n", bp
, bp
->b_flags
);
2720 if (bcleanbuf(bp
)) {
2722 * moved to the laundry thread, buffer not ready
2733 * Returns 0 is buffer is ready to use,
2734 * Returns 1 if issued a buf_bawrite() to indicate
2735 * that the buffer is not ready.
2737 * buf_mtxp is held upon entry
2738 * returns with buf_mtxp locked
2746 /* Remove from the queue */
2747 bremfree_locked(bp
);
2749 /* Buffer is no longer on free lists. */
2750 SET(bp
->b_lflags
, BL_BUSY
);
2752 bp
->b_owner
= current_thread();
2756 * If buffer was a delayed write, start the IO by queuing
2757 * it on the LAUNDRY queue, and return 1
2759 if (ISSET(bp
->b_flags
, B_DELWRI
)) {
2760 binstailfree(bp
, &bufqueues
[BQ_LAUNDRY
], BQ_LAUNDRY
);
2763 lck_mtx_unlock(buf_mtxp
);
2765 wakeup(&blaundrycnt
);
2766 /* and give it a chance to run */
2767 (void)thread_block(THREAD_CONTINUE_NULL
);
2769 lck_mtx_lock(buf_mtxp
);
2774 lck_mtx_unlock(buf_mtxp
);
2778 * disassociate us from our vnode, if we had one...
2783 if (ISSET(bp
->b_flags
, B_META
)) {
2786 elem
= (vm_offset_t
)bp
->b_datap
;
2787 bp
->b_datap
= (uintptr_t)0xdeadbeef;
2789 if (ISSET(bp
->b_flags
, B_ZALLOC
)) {
2792 z
= getbufzone(bp
->b_bufsize
);
2793 zfree(z
, (void *)elem
);
2795 kmem_free(kernel_map
, elem
, bp
->b_bufsize
);
2798 trace(TR_BRELSE
, pack(bp
->b_vp
, bp
->b_bufsize
), bp
->b_lblkno
);
2800 /* clear out various other fields */
2802 bp
->b_datap
= (uintptr_t)NULL
;
2803 bp
->b_upl
= (void *)NULL
;
2805 * preserve the state of whether this buffer
2806 * was allocated on the fly or not...
2807 * the only other flag that should be set at
2808 * this point is BL_BUSY...
2811 bp
->b_owner
= current_thread();
2814 bp
->b_lflags
= BL_BUSY
;
2815 bp
->b_flags
= (bp
->b_flags
& B_HDRALLOC
);
2817 bp
->b_blkno
= bp
->b_lblkno
= 0;
2818 bp
->b_iodone
= NULL
;
2822 bp
->b_dirtyoff
= bp
->b_dirtyend
= 0;
2823 bp
->b_validoff
= bp
->b_validend
= 0;
2825 /* nuke any credentials we were holding */
2827 if (cred
!= NOCRED
) {
2828 bp
->b_rcred
= NOCRED
;
2829 kauth_cred_rele(cred
);
2832 if (cred
!= NOCRED
) {
2833 bp
->b_wcred
= NOCRED
;
2834 kauth_cred_rele(cred
);
2836 lck_mtx_lock(buf_mtxp
);
2844 buf_invalblkno(vnode_t vp
, daddr64_t lblkno
, int flags
)
2849 lck_mtx_lock(buf_mtxp
);
2851 if ((bp
= incore_locked(vp
, lblkno
)) == (struct buf
*)0) {
2852 lck_mtx_unlock(buf_mtxp
);
2855 if (ISSET(bp
->b_lflags
, BL_BUSY
)) {
2856 if ( !ISSET(flags
, BUF_WAIT
)) {
2857 lck_mtx_unlock(buf_mtxp
);
2860 SET(bp
->b_lflags
, BL_WANTED
);
2862 error
= msleep((caddr_t
)bp
, buf_mtxp
, (PRIBIO
+ 1), (char *)"buf_invalblkno", 0);
2868 bremfree_locked(bp
);
2869 SET(bp
->b_lflags
, BL_BUSY
);
2870 SET(bp
->b_flags
, B_INVAL
);
2872 bp
->b_owner
= current_thread();
2875 lck_mtx_unlock(buf_mtxp
);
2885 int need_wakeup
= 0;
2887 lck_mtx_lock(buf_mtxp
);
2889 if (ISSET(bp
->b_lflags
, BL_WANTED
)) {
2891 * delay the actual wakeup until after we
2892 * clear BL_BUSY and we've dropped buf_mtxp
2897 * Unlock the buffer.
2899 CLR(bp
->b_lflags
, (BL_BUSY
| BL_WANTED
));
2901 lck_mtx_unlock(buf_mtxp
);
2905 * Wake up any proceeses waiting for _this_ buffer to become free.
2913 buf_acquire(buf_t bp
, int flags
, int slpflag
, int slptimeo
) {
2916 lck_mtx_lock(buf_mtxp
);
2918 error
= buf_acquire_locked(bp
, flags
, slpflag
, slptimeo
);
2920 lck_mtx_unlock(buf_mtxp
);
2927 buf_acquire_locked(buf_t bp
, int flags
, int slpflag
, int slptimeo
)
2932 if (ISSET(bp
->b_flags
, B_LOCKED
)) {
2933 if ((flags
& BAC_SKIP_LOCKED
))
2936 if ((flags
& BAC_SKIP_NONLOCKED
))
2939 if (ISSET(bp
->b_lflags
, BL_BUSY
)) {
2941 * since the mutex_lock may block, the buffer
2942 * may become BUSY, so we need to
2943 * recheck for a NOWAIT request
2945 if (flags
& BAC_NOWAIT
)
2947 SET(bp
->b_lflags
, BL_WANTED
);
2949 /* the hz value is 100; which leads to 10ms */
2950 ts
.tv_sec
= (slptimeo
/100);
2951 ts
.tv_nsec
= (slptimeo
% 100) * 10 * NSEC_PER_USEC
* 1000;
2952 error
= msleep((caddr_t
)bp
, buf_mtxp
, slpflag
| (PRIBIO
+ 1), (char *)"buf_acquire", &ts
);
2958 if (flags
& BAC_REMOVE
)
2959 bremfree_locked(bp
);
2960 SET(bp
->b_lflags
, BL_BUSY
);
2962 bp
->b_owner
= current_thread();
2970 * Wait for operations on the buffer to complete.
2971 * When they do, extract and return the I/O's error value.
2974 buf_biowait(buf_t bp
)
2976 lck_mtx_lock(buf_mtxp
);
2978 while (!ISSET(bp
->b_flags
, B_DONE
))
2979 (void) msleep(bp
, buf_mtxp
, (PRIBIO
+1), (char *)"buf_biowait", 0);
2981 lck_mtx_unlock(buf_mtxp
);
2983 /* check for interruption of I/O (e.g. via NFS), then errors. */
2984 if (ISSET(bp
->b_flags
, B_EINTR
)) {
2985 CLR(bp
->b_flags
, B_EINTR
);
2987 } else if (ISSET(bp
->b_flags
, B_ERROR
))
2988 return (bp
->b_error
? bp
->b_error
: EIO
);
2994 * Mark I/O complete on a buffer.
2996 * If a callback has been requested, e.g. the pageout
2997 * daemon, do so. Otherwise, awaken waiting processes.
2999 * [ Leffler, et al., says on p.247:
3000 * "This routine wakes up the blocked process, frees the buffer
3001 * for an asynchronous write, or, for a request by the pagedaemon
3002 * process, invokes a procedure specified in the buffer structure" ]
3004 * In real life, the pagedaemon (or other system processes) wants
3005 * to do async stuff to, and doesn't want the buffer buf_brelse()'d.
3006 * (for swap pager, that puts swap buffers on the free lists (!!!),
3007 * for the vn device, that puts malloc'd buffers on the free lists!)
3009 extern struct timeval priority_IO_timestamp_for_root
;
3010 extern int hard_throttle_on_root
;
3013 buf_biodone(buf_t bp
)
3015 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 387)) | DBG_FUNC_START
,
3016 (int)bp
, (int)bp
->b_datap
, bp
->b_flags
, 0, 0);
3018 if (ISSET(bp
->b_flags
, B_DONE
))
3019 panic("biodone already");
3021 if (kdebug_enable
) {
3022 int code
= DKIO_DONE
;
3024 if (bp
->b_flags
& B_READ
)
3026 if (bp
->b_flags
& B_ASYNC
)
3029 if (bp
->b_flags
& B_META
)
3031 else if (bp
->b_flags
& B_PAGEIO
)
3032 code
|= DKIO_PAGING
;
3034 KERNEL_DEBUG_CONSTANT(FSDBG_CODE(DBG_DKRW
, code
) | DBG_FUNC_NONE
,
3035 (unsigned int)bp
, (unsigned int)bp
->b_vp
,
3036 bp
->b_resid
, bp
->b_error
, 0);
3038 if ((bp
->b_vp
!= NULLVP
) &&
3039 ((bp
->b_flags
& (B_PAGEIO
| B_READ
)) == (B_PAGEIO
| B_READ
)) &&
3040 (bp
->b_vp
->v_mount
->mnt_kern_flag
& MNTK_ROOTDEV
)) {
3041 microuptime(&priority_IO_timestamp_for_root
);
3042 hard_throttle_on_root
= 0;
3045 * I/O was done, so don't believe
3046 * the DIRTY state from VM anymore
3048 CLR(bp
->b_flags
, B_WASDIRTY
);
3050 if (!ISSET(bp
->b_flags
, B_READ
) && !ISSET(bp
->b_flags
, B_RAW
))
3052 * wake up any writer's blocked
3053 * on throttle or waiting for I/O
3056 vnode_writedone(bp
->b_vp
);
3058 if (ISSET(bp
->b_flags
, (B_CALL
| B_FILTER
))) { /* if necessary, call out */
3059 void (*iodone_func
)(struct buf
*, void *) = bp
->b_iodone
;
3060 void *arg
= (void *)bp
->b_transaction
;
3061 int callout
= ISSET(bp
->b_flags
, B_CALL
);
3063 CLR(bp
->b_flags
, (B_CALL
| B_FILTER
)); /* filters and callouts are one-shot */
3064 bp
->b_iodone
= NULL
;
3065 bp
->b_transaction
= NULL
;
3067 if (iodone_func
== NULL
) {
3068 panic("biodone: bp @ 0x%x has NULL b_iodone!\n", bp
);
3071 SET(bp
->b_flags
, B_DONE
); /* note that it's done */
3072 (*iodone_func
)(bp
, arg
);
3076 * assumes that the call back function takes
3077 * ownership of the bp and deals with releasing it if necessary
3081 * in this case the call back function is acting
3082 * strictly as a filter... it does not take
3083 * ownership of the bp and is expecting us
3084 * to finish cleaning up... this is currently used
3085 * by the HFS journaling code
3088 if (ISSET(bp
->b_flags
, B_ASYNC
)) { /* if async, release it */
3089 SET(bp
->b_flags
, B_DONE
); /* note that it's done */
3092 } else { /* or just wakeup the buffer */
3094 * by taking the mutex, we serialize
3095 * the buf owner calling buf_biowait so that we'll
3096 * only see him in one of 2 states...
3097 * state 1: B_DONE wasn't set and he's
3099 * state 2: he's blocked trying to take the
3100 * mutex before looking at B_DONE
3101 * BL_WANTED is cleared in case anyone else
3102 * is blocked waiting for the buffer... note
3103 * that we haven't cleared B_BUSY yet, so if
3104 * they do get to run, their going to re-set
3105 * BL_WANTED and go back to sleep
3107 lck_mtx_lock(buf_mtxp
);
3109 CLR(bp
->b_lflags
, BL_WANTED
);
3110 SET(bp
->b_flags
, B_DONE
); /* note that it's done */
3112 lck_mtx_unlock(buf_mtxp
);
3117 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW
, 387)) | DBG_FUNC_END
,
3118 (int)bp
, (int)bp
->b_datap
, bp
->b_flags
, 0, 0);
3122 * Return a count of buffers on the "locked" queue.
3125 count_lock_queue(void)
3130 lck_mtx_lock(buf_mtxp
);
3132 for (bp
= bufqueues
[BQ_LOCKED
].tqh_first
; bp
;
3133 bp
= bp
->b_freelist
.tqe_next
)
3135 lck_mtx_unlock(buf_mtxp
);
3141 * Return a count of 'busy' buffers. Used at the time of shutdown.
3144 count_busy_buffers(void)
3149 lck_mtx_lock(buf_mtxp
);
3150 for (bp
= &buf
[boot_nbuf
]; --bp
>= buf
; )
3151 if (!ISSET(bp
->b_flags
, B_INVAL
) && ISSET(bp
->b_lflags
, BL_BUSY
))
3153 lck_mtx_unlock(buf_mtxp
);
3160 * Print out statistics on the current allocation of the buffer pool.
3161 * Can be enabled to print out on every ``sync'' by setting "syncprt"
3162 * in vfs_syscalls.c using sysctl.
3168 register struct buf
*bp
;
3169 register struct bqueues
*dp
;
3170 int counts
[MAXBSIZE
/CLBYTES
+1];
3171 static char *bname
[BQUEUES
] =
3172 { "LOCKED", "LRU", "AGE", "EMPTY", "META", "LAUNDRY" };
3174 for (dp
= bufqueues
, i
= 0; dp
< &bufqueues
[BQUEUES
]; dp
++, i
++) {
3176 for (j
= 0; j
<= MAXBSIZE
/CLBYTES
; j
++)
3179 lck_mtx_lock(buf_mtxp
);
3181 for (bp
= dp
->tqh_first
; bp
; bp
= bp
->b_freelist
.tqe_next
) {
3182 counts
[bp
->b_bufsize
/CLBYTES
]++;
3185 lck_mtx_unlock(buf_mtxp
);
3187 printf("%s: total-%d", bname
[i
], count
);
3188 for (j
= 0; j
<= MAXBSIZE
/CLBYTES
; j
++)
3190 printf(", %d-%d", j
* CLBYTES
, counts
[j
]);
3194 #endif /* DIAGNOSTIC */
3196 #define NRESERVEDIOBUFS 64
3200 alloc_io_buf(vnode_t vp
, int priv
)
3204 lck_mtx_lock(iobuffer_mtxp
);
3206 while (((niobuf
- NRESERVEDIOBUFS
< bufstats
.bufs_iobufinuse
) && !priv
) ||
3207 (bp
= iobufqueue
.tqh_first
) == NULL
) {
3208 bufstats
.bufs_iobufsleeps
++;
3211 (void) msleep(&need_iobuffer
, iobuffer_mtxp
, (PRIBIO
+1), (const char *)"alloc_io_buf", 0);
3213 TAILQ_REMOVE(&iobufqueue
, bp
, b_freelist
);
3215 bufstats
.bufs_iobufinuse
++;
3216 if (bufstats
.bufs_iobufinuse
> bufstats
.bufs_iobufmax
)
3217 bufstats
.bufs_iobufmax
= bufstats
.bufs_iobufinuse
;
3219 lck_mtx_unlock(iobuffer_mtxp
);
3222 * initialize various fields
3223 * we don't need to hold the mutex since the buffer
3224 * is now private... the vp should have a reference
3225 * on it and is not protected by this mutex in any event
3227 bp
->b_timestamp
= 0;
3232 bp
->b_lflags
= BL_BUSY
| BL_IOBUF
;
3233 bp
->b_blkno
= bp
->b_lblkno
= 0;
3235 bp
->b_owner
= current_thread();
3238 bp
->b_iodone
= NULL
;
3246 if (vp
&& (vp
->v_type
== VBLK
|| vp
->v_type
== VCHR
))
3247 bp
->b_dev
= vp
->v_rdev
;
3256 free_io_buf(buf_t bp
)
3258 int need_wakeup
= 0;
3261 * put buffer back on the head of the iobufqueue
3264 bp
->b_flags
= B_INVAL
;
3266 lck_mtx_lock(iobuffer_mtxp
);
3268 binsheadfree(bp
, &iobufqueue
, -1);
3270 if (need_iobuffer
) {
3272 * Wake up any processes waiting because they need an io buffer
3274 * do the wakeup after we drop the mutex... it's possible that the
3275 * wakeup will be superfluous if need_iobuffer gets set again and
3276 * another thread runs this path, but it's highly unlikely, doesn't
3277 * hurt, and it means we don't hold up I/O progress if the wakeup blocks
3278 * trying to grab a task related lock...
3283 bufstats
.bufs_iobufinuse
--;
3285 lck_mtx_unlock(iobuffer_mtxp
);
3288 wakeup(&need_iobuffer
);
3294 * If getnewbuf() calls bcleanbuf() on the same thread
3295 * there is a potential for stack overrun and deadlocks.
3296 * So we always handoff the work to a worker thread for completion
3298 #include <mach/mach_types.h>
3299 #include <mach/memory_object_types.h>
3300 #include <kern/sched_prim.h>
3304 bcleanbuf_thread_init(void)
3306 /* create worker thread */
3307 kernel_thread(kernel_task
, bcleanbuf_thread
);
3311 bcleanbuf_thread(void)
3318 lck_mtx_lock(buf_mtxp
);
3320 while (blaundrycnt
== 0)
3321 (void)msleep((void *)&blaundrycnt
, buf_mtxp
, PRIBIO
, "blaundry", 0);
3323 bp
= TAILQ_FIRST(&bufqueues
[BQ_LAUNDRY
]);
3325 * Remove from the queue
3327 bremfree_locked(bp
);
3330 lck_mtx_unlock(buf_mtxp
);
3334 error
= bawrite_internal(bp
, 0);
3337 lck_mtx_lock(buf_mtxp
);
3339 binstailfree(bp
, &bufqueues
[BQ_LAUNDRY
], BQ_LAUNDRY
);
3342 lck_mtx_unlock(buf_mtxp
);
3345 (void)tsleep((void *)&blaundrycnt
, PRIBIO
, "blaundry", 1);
3348 (void)thread_block(THREAD_CONTINUE_NULL
);
3357 brecover_data(buf_t bp
)
3361 upl_page_info_t
*pl
;
3363 vnode_t vp
= bp
->b_vp
;
3367 if ( !UBCINFOEXISTS(vp
) || bp
->b_bufsize
== 0)
3370 upl_flags
= UPL_PRECIOUS
;
3371 if (! (buf_flags(bp
) & B_READ
)) {
3373 * "write" operation: let the UPL subsystem know
3374 * that we intend to modify the buffer cache pages we're
3377 upl_flags
|= UPL_WILL_MODIFY
;
3380 kret
= ubc_create_upl(vp
,
3381 ubc_blktooff(vp
, bp
->b_lblkno
),
3386 if (kret
!= KERN_SUCCESS
)
3387 panic("Failed to create UPL");
3389 for (upl_offset
= 0; upl_offset
< bp
->b_bufsize
; upl_offset
+= PAGE_SIZE
) {
3391 if (!upl_valid_page(pl
, upl_offset
/ PAGE_SIZE
) || !upl_dirty_page(pl
, upl_offset
/ PAGE_SIZE
)) {
3392 ubc_upl_abort(upl
, 0);
3398 kret
= ubc_upl_map(upl
, (vm_address_t
*)&(bp
->b_datap
));
3400 if (kret
!= KERN_SUCCESS
)
3401 panic("getblk: ubc_upl_map() failed with (%d)", kret
);
3406 SET(bp
->b_flags
, B_INVAL
);
3423 bp_cmp(void *a
, void *b
)
3425 buf_t
*bp_a
= *(buf_t
**)a
,
3426 *bp_b
= *(buf_t
**)b
;
3429 // don't have to worry about negative block
3430 // numbers so this is ok to do.
3432 res
= (bp_a
->b_blkno
- bp_b
->b_blkno
);
3439 bflushq(int whichq
, mount_t mp
)
3443 int total_writes
= 0;
3444 static buf_t flush_table
[NFLUSH
];
3446 if (whichq
< 0 || whichq
>= BQUEUES
) {
3451 lck_mtx_lock(buf_mtxp
);
3453 bp
= TAILQ_FIRST(&bufqueues
[whichq
]);
3455 for (buf_count
= 0; bp
; bp
= next
) {
3456 next
= bp
->b_freelist
.tqe_next
;
3458 if (bp
->b_vp
== NULL
|| bp
->b_vp
->v_mount
!= mp
) {
3462 if (ISSET(bp
->b_flags
, B_DELWRI
) && !ISSET(bp
->b_lflags
, BL_BUSY
)) {
3464 bremfree_locked(bp
);
3466 bp
->b_owner
= current_thread();
3469 SET(bp
->b_lflags
, BL_BUSY
);
3470 flush_table
[buf_count
] = bp
;
3474 if (buf_count
>= NFLUSH
) {
3475 lck_mtx_unlock(buf_mtxp
);
3477 qsort(flush_table
, buf_count
, sizeof(struct buf
*), bp_cmp
);
3479 for (i
= 0; i
< buf_count
; i
++) {
3480 buf_bawrite(flush_table
[i
]);
3486 lck_mtx_unlock(buf_mtxp
);
3488 if (buf_count
> 0) {
3489 qsort(flush_table
, buf_count
, sizeof(struct buf
*), bp_cmp
);
3491 for (i
= 0; i
< buf_count
; i
++) {
3492 buf_bawrite(flush_table
[i
]);
3496 return (total_writes
);
3503 /* XXX move this to a separate file */
3506 * NOTE: THIS CODE HAS NOT BEEN UPDATED
3507 * WITH RESPECT TO THE NEW LOCKING MODEL
3512 * Dynamic Scaling of the Buffer Queues
3515 typedef long long blsize_t
;
3517 blsize_t MAXNBUF
; /* initialize to (sane_size / PAGE_SIZE) */
3518 /* Global tunable limits */
3519 blsize_t nbufh
; /* number of buffer headers */
3520 blsize_t nbuflow
; /* minimum number of buffer headers required */
3521 blsize_t nbufhigh
; /* maximum number of buffer headers allowed */
3522 blsize_t nbuftarget
; /* preferred number of buffer headers */
3527 * 1. 0 < nbuflow <= nbufh <= nbufhigh
3528 * 2. nbufhigh <= MAXNBUF
3529 * 3. 0 < nbuflow <= nbuftarget <= nbufhigh
3530 * 4. nbufh can not be set by sysctl().
3533 /* Per queue tunable limits */
3536 blsize_t bl_nlow
; /* minimum number of buffer headers required */
3537 blsize_t bl_num
; /* number of buffer headers on the queue */
3538 blsize_t bl_nlhigh
; /* maximum number of buffer headers allowed */
3539 blsize_t bl_target
; /* preferred number of buffer headers */
3540 long bl_stale
; /* Seconds after which a buffer is considered stale */
3546 * 1. 0 <= bl_nlow <= bl_num <= bl_nlhigh
3547 * 2. bl_nlhigh <= MAXNBUF
3548 * 3. bufqlim[BQ_META].bl_nlow != 0
3549 * 4. bufqlim[BQ_META].bl_nlow > (number of possible concurrent
3550 * file system IO operations)
3551 * 5. bl_num can not be set by sysctl().
3552 * 6. bl_nhigh <= nbufhigh
3558 * Defining it blsize_t as long permits 2^31 buffer headers per queue.
3559 * Which can describe (2^31 * PAGE_SIZE) memory per queue.
3561 * These limits are exported to by means of sysctl().
3562 * It was decided to define blsize_t as a 64 bit quantity.
3563 * This will make sure that we will not be required to change it
3564 * as long as we do not exceed 64 bit address space for the kernel.
3566 * low and high numbers parameters initialized at compile time
3567 * and boot arguments can be used to override them. sysctl()
3568 * would not change the value. sysctl() can get all the values
3569 * but can set only target. num is the current level.
3571 * Advantages of having a "bufqscan" thread doing the balancing are,
3572 * Keep enough bufs on BQ_EMPTY.
3573 * getnewbuf() by default will always select a buffer from the BQ_EMPTY.
3574 * getnewbuf() perfoms best if a buffer was found there.
3575 * Also this minimizes the possibility of starting IO
3576 * from getnewbuf(). That's a performance win, too.
3578 * Localize complex logic [balancing as well as time aging]
3581 * Simplify getnewbuf() logic by elimination of time aging code.
3587 * The goal of the dynamic scaling of the buffer queues to to keep
3588 * the size of the LRU close to bl_target. Buffers on a queue would
3591 * There would be a thread which will be responsible for "balancing"
3592 * the buffer cache queues.
3594 * The scan order would be: AGE, LRU, META, EMPTY.
3597 long bufqscanwait
= 0;
3599 static void bufqscan_thread();
3600 static int balancebufq(int q
);
3601 static int btrimempty(int n
);
3602 static __inline__
int initbufqscan(void);
3603 static __inline__
int nextbufq(int q
);
3604 static void buqlimprt(int all
);
3607 static __inline__
void
3610 if ((q
< 0) || (q
>= BQUEUES
))
3613 bufqlim
[q
].bl_num
++;
3617 static __inline__
void
3620 if ((q
< 0) || (q
>= BQUEUES
))
3623 bufqlim
[q
].bl_num
--;
3628 bufq_balance_thread_init()
3631 if (bufqscanwait
++ == 0) {
3633 /* Initalize globals */
3634 MAXNBUF
= (sane_size
/ PAGE_SIZE
);
3636 nbuflow
= min(nbufh
, 100);
3637 nbufhigh
= min(MAXNBUF
, max(nbufh
, 2048));
3638 nbuftarget
= (sane_size
>> 5) / PAGE_SIZE
;
3639 nbuftarget
= max(nbuflow
, nbuftarget
);
3640 nbuftarget
= min(nbufhigh
, nbuftarget
);
3643 * Initialize the bufqlim
3647 bufqlim
[BQ_LOCKED
].bl_nlow
= 0;
3648 bufqlim
[BQ_LOCKED
].bl_nlhigh
= 32;
3649 bufqlim
[BQ_LOCKED
].bl_target
= 0;
3650 bufqlim
[BQ_LOCKED
].bl_stale
= 30;
3653 bufqlim
[BQ_LRU
].bl_nlow
= 0;
3654 bufqlim
[BQ_LRU
].bl_nlhigh
= nbufhigh
/4;
3655 bufqlim
[BQ_LRU
].bl_target
= nbuftarget
/4;
3656 bufqlim
[BQ_LRU
].bl_stale
= LRU_IS_STALE
;
3659 bufqlim
[BQ_AGE
].bl_nlow
= 0;
3660 bufqlim
[BQ_AGE
].bl_nlhigh
= nbufhigh
/4;
3661 bufqlim
[BQ_AGE
].bl_target
= nbuftarget
/4;
3662 bufqlim
[BQ_AGE
].bl_stale
= AGE_IS_STALE
;
3665 bufqlim
[BQ_EMPTY
].bl_nlow
= 0;
3666 bufqlim
[BQ_EMPTY
].bl_nlhigh
= nbufhigh
/4;
3667 bufqlim
[BQ_EMPTY
].bl_target
= nbuftarget
/4;
3668 bufqlim
[BQ_EMPTY
].bl_stale
= 600000;
3671 bufqlim
[BQ_META
].bl_nlow
= 0;
3672 bufqlim
[BQ_META
].bl_nlhigh
= nbufhigh
/4;
3673 bufqlim
[BQ_META
].bl_target
= nbuftarget
/4;
3674 bufqlim
[BQ_META
].bl_stale
= META_IS_STALE
;
3677 bufqlim
[BQ_LOCKED
].bl_nlow
= 0;
3678 bufqlim
[BQ_LOCKED
].bl_nlhigh
= 32;
3679 bufqlim
[BQ_LOCKED
].bl_target
= 0;
3680 bufqlim
[BQ_LOCKED
].bl_stale
= 30;
3685 /* create worker thread */
3686 kernel_thread(kernel_task
, bufqscan_thread
);
3689 /* The workloop for the buffer balancing thread */
3697 int q
; /* buffer queue to process */
3701 moretodo
|= balancebufq(q
);
3710 (void)tsleep((void *)&bufqscanwait
, PRIBIO
, "bufqscanwait", 60 * hz
);
3715 /* Seed for the buffer queue balancing */
3716 static __inline__
int
3719 /* Start with AGE queue */
3723 /* Pick next buffer queue to balance */
3724 static __inline__
int
3727 int order
[] = { BQ_AGE
, BQ_LRU
, BQ_META
, BQ_EMPTY
, 0 };
3734 /* function to balance the buffer queues */
3742 /* reject invalid q */
3743 if ((q
< 0) || (q
>= BQUEUES
))
3746 /* LOCKED or LAUNDRY queue MUST not be balanced */
3747 if ((q
== BQ_LOCKED
) || (q
== BQ_LAUNDRY
))
3750 n
= (bufqlim
[q
].bl_num
- bufqlim
[q
].bl_target
);
3752 /* If queue has less than target nothing more to do */
3757 /* Balance only a small amount (12.5%) at a time */
3761 /* EMPTY queue needs special handling */
3762 if (q
== BQ_EMPTY
) {
3763 moretodo
|= btrimempty(n
);
3767 t
= buf_timestamp():
3769 for (; n
> 0; n
--) {
3770 struct buf
*bp
= bufqueues
[q
].tqh_first
;
3774 /* check if it's stale */
3775 if ((t
- bp
->b_timestamp
) > bufqlim
[q
].bl_stale
) {
3776 if (bcleanbuf(bp
)) {
3777 /* buf_bawrite() issued, bp not ready */
3780 /* release the cleaned buffer to BQ_EMPTY */
3781 SET(bp
->b_flags
, B_INVAL
);
3797 * When struct buf are allocated dynamically, this would
3798 * reclaim upto 'n' struct buf from the empty queue.
3808 static char *bname
[BQUEUES
] =
3809 { "LOCKED", "LRU", "AGE", "EMPTY", "META", "LAUNDRY" };
3812 for (i
= 0; i
< BQUEUES
; i
++) {
3813 printf("%s : ", bname
[i
]);
3814 printf("min = %ld, ", (long)bufqlim
[i
].bl_nlow
);
3815 printf("cur = %ld, ", (long)bufqlim
[i
].bl_num
);
3816 printf("max = %ld, ", (long)bufqlim
[i
].bl_nlhigh
);
3817 printf("target = %ld, ", (long)bufqlim
[i
].bl_target
);
3818 printf("stale after %ld seconds\n", bufqlim
[i
].bl_stale
);
3821 for (i
= 0; i
< BQUEUES
; i
++) {
3822 printf("%s : ", bname
[i
]);
3823 printf("cur = %ld, ", (long)bufqlim
[i
].bl_num
);