]> git.saurik.com Git - apple/xnu.git/blame - bsd/vfs/vfs_bio.c
xnu-792.25.20.tar.gz
[apple/xnu.git] / bsd / vfs / vfs_bio.c
CommitLineData
1c79356b 1/*
5d5c5d0d
A
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
3 *
6601e61a 4 * @APPLE_LICENSE_HEADER_START@
1c79356b 5 *
6601e61a
A
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
8f6c56a5 11 *
6601e61a
A
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
8f6c56a5
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
6601e61a
A
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
8f6c56a5 19 *
6601e61a 20 * @APPLE_LICENSE_HEADER_END@
1c79356b
A
21 */
22/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
23/*-
24 * Copyright (c) 1994 Christopher G. Demetriou
25 * Copyright (c) 1982, 1986, 1989, 1993
26 * The Regents of the University of California. All rights reserved.
27 * (c) UNIX System Laboratories, Inc.
28 * All or some portions of this file are derived from material licensed
29 * to the University of California by American Telephone and Telegraph
30 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
31 * the permission of UNIX System Laboratories, Inc.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 * notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 * notice, this list of conditions and the following disclaimer in the
40 * documentation and/or other materials provided with the distribution.
41 * 3. All advertising materials mentioning features or use of this software
42 * must display the following acknowledgement:
43 * This product includes software developed by the University of
44 * California, Berkeley and its contributors.
45 * 4. Neither the name of the University nor the names of its contributors
46 * may be used to endorse or promote products derived from this software
47 * without specific prior written permission.
48 *
49 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
50 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
51 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
52 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
53 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
54 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
55 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
56 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
57 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE.
60 *
1c79356b
A
61 * @(#)vfs_bio.c 8.6 (Berkeley) 1/11/94
62 */
63
64/*
65 * Some references:
66 * Bach: The Design of the UNIX Operating System (Prentice Hall, 1986)
67 * Leffler, et al.: The Design and Implementation of the 4.3BSD
68 * UNIX Operating System (Addison Welley, 1989)
69 */
1c79356b
A
70
71#include <sys/param.h>
72#include <sys/systm.h>
91447636
A
73#include <sys/proc_internal.h>
74#include <sys/buf_internal.h>
75#include <sys/vnode_internal.h>
76#include <sys/mount_internal.h>
1c79356b
A
77#include <sys/trace.h>
78#include <sys/malloc.h>
79#include <sys/resourcevar.h>
80#include <miscfs/specfs/specdev.h>
81#include <sys/ubc.h>
91447636 82#include <sys/kauth.h>
1c79356b
A
83#if DIAGNOSTIC
84#include <kern/assert.h>
85#endif /* DIAGNOSTIC */
86#include <kern/task.h>
87#include <kern/zalloc.h>
91447636
A
88#include <kern/lock.h>
89
90#include <vm/vm_kern.h>
1c79356b
A
91
92#include <sys/kdebug.h>
9bccf70c 93#include <machine/spl.h>
1c79356b 94
91447636 95#if BALANCE_QUEUES
9bccf70c
A
96static __inline__ void bufqinc(int q);
97static __inline__ void bufqdec(int q);
91447636 98#endif
1c79356b 99
91447636
A
100static int bcleanbuf(buf_t bp);
101static int brecover_data(buf_t bp);
102static boolean_t incore(vnode_t vp, daddr64_t blkno);
103static buf_t incore_locked(vnode_t vp, daddr64_t blkno);
104/* timeout is in msecs */
105static buf_t getnewbuf(int slpflag, int slptimeo, int *queue);
106static void bremfree_locked(buf_t bp);
107static void buf_reassign(buf_t bp, vnode_t newvp);
108static errno_t buf_acquire_locked(buf_t bp, int flags, int slpflag, int slptimeo);
109static int buf_iterprepare(vnode_t vp, struct buflists *, int flags);
110static void buf_itercomplete(vnode_t vp, struct buflists *, int flags);
1c79356b 111
91447636 112__private_extern__ int bdwrite_internal(buf_t, int);
1c79356b 113
d52fe63f 114/* zone allocated buffer headers */
91447636
A
115static void bufzoneinit(void);
116static void bcleanbuf_thread_init(void);
117static void bcleanbuf_thread(void);
118
119static zone_t buf_hdr_zone;
120static int buf_hdr_count;
d52fe63f 121
1c79356b
A
122
123/*
124 * Definitions for the buffer hash lists.
125 */
126#define BUFHASH(dvp, lbn) \
127 (&bufhashtbl[((long)(dvp) / sizeof(*(dvp)) + (int)(lbn)) & bufhash])
128LIST_HEAD(bufhashhdr, buf) *bufhashtbl, invalhash;
129u_long bufhash;
130
131/* Definitions for the buffer stats. */
132struct bufstats bufstats;
133
d52fe63f
A
134/* Number of delayed write buffers */
135int nbdwrite = 0;
91447636 136int blaundrycnt = 0;
d52fe63f 137
1c79356b 138
91447636
A
139static TAILQ_HEAD(ioqueue, buf) iobufqueue;
140static TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
d52fe63f
A
141static int needbuffer;
142static int need_iobuffer;
1c79356b 143
91447636
A
144static lck_grp_t *buf_mtx_grp;
145static lck_attr_t *buf_mtx_attr;
146static lck_grp_attr_t *buf_mtx_grp_attr;
147static lck_mtx_t *iobuffer_mtxp;
148static lck_mtx_t *buf_mtxp;
149
150static __inline__ int
151buf_timestamp(void)
152{
153 struct timeval t;
154 microuptime(&t);
155 return (t.tv_sec);
156}
157
1c79356b
A
158/*
159 * Insq/Remq for the buffer free lists.
160 */
91447636 161#if BALANCE_QUEUES
1c79356b
A
162#define binsheadfree(bp, dp, whichq) do { \
163 TAILQ_INSERT_HEAD(dp, bp, b_freelist); \
164 bufqinc((whichq)); \
165 (bp)->b_whichq = whichq; \
91447636 166 (bp)->b_timestamp = buf_timestamp(); \
1c79356b
A
167 } while (0)
168
169#define binstailfree(bp, dp, whichq) do { \
170 TAILQ_INSERT_TAIL(dp, bp, b_freelist); \
171 bufqinc((whichq)); \
172 (bp)->b_whichq = whichq; \
91447636
A
173 (bp)->b_timestamp = buf_timestamp(); \
174 } while (0)
175#else
176#define binsheadfree(bp, dp, whichq) do { \
177 TAILQ_INSERT_HEAD(dp, bp, b_freelist); \
178 (bp)->b_whichq = whichq; \
179 (bp)->b_timestamp = buf_timestamp(); \
1c79356b
A
180 } while (0)
181
91447636
A
182#define binstailfree(bp, dp, whichq) do { \
183 TAILQ_INSERT_TAIL(dp, bp, b_freelist); \
184 (bp)->b_whichq = whichq; \
185 (bp)->b_timestamp = buf_timestamp(); \
186 } while (0)
187#endif
188
189
1c79356b
A
190#define BHASHENTCHECK(bp) \
191 if ((bp)->b_hash.le_prev != (struct buf **)0xdeadbeef) \
765c9de3 192 panic("%x: b_hash.le_prev is not deadbeef", (bp));
1c79356b
A
193
194#define BLISTNONE(bp) \
195 (bp)->b_hash.le_next = (struct buf *)0; \
196 (bp)->b_hash.le_prev = (struct buf **)0xdeadbeef;
197
9bccf70c
A
198/*
199 * Insq/Remq for the vnode usage lists.
200 */
201#define bufinsvn(bp, dp) LIST_INSERT_HEAD(dp, bp, b_vnbufs)
202#define bufremvn(bp) { \
203 LIST_REMOVE(bp, b_vnbufs); \
204 (bp)->b_vnbufs.le_next = NOLIST; \
205}
206
1c79356b
A
207/*
208 * Time in seconds before a buffer on a list is
209 * considered as a stale buffer
210 */
211#define LRU_IS_STALE 120 /* default value for the LRU */
212#define AGE_IS_STALE 60 /* default value for the AGE */
213#define META_IS_STALE 180 /* default value for the BQ_META */
214
215int lru_is_stale = LRU_IS_STALE;
216int age_is_stale = AGE_IS_STALE;
217int meta_is_stale = META_IS_STALE;
0c530ab8 218static int boot_nbuf = 0;
91447636
A
219
220
9bccf70c
A
221/* LIST_INSERT_HEAD() with assertions */
222static __inline__ void
91447636 223blistenterhead(struct bufhashhdr * head, buf_t bp)
1c79356b
A
224{
225 if ((bp->b_hash.le_next = (head)->lh_first) != NULL)
226 (head)->lh_first->b_hash.le_prev = &(bp)->b_hash.le_next;
227 (head)->lh_first = bp;
228 bp->b_hash.le_prev = &(head)->lh_first;
229 if (bp->b_hash.le_prev == (struct buf **)0xdeadbeef)
230 panic("blistenterhead: le_prev is deadbeef");
1c79356b 231}
1c79356b 232
9bccf70c 233static __inline__ void
91447636 234binshash(buf_t bp, struct bufhashhdr *dp)
1c79356b 235{
0c530ab8 236#if DIAGNOSTIC
91447636 237 buf_t nbp;
0c530ab8 238#endif /* DIAGNOSTIC */
9bccf70c 239
1c79356b 240 BHASHENTCHECK(bp);
9bccf70c 241
0c530ab8 242#if DIAGNOSTIC
1c79356b
A
243 nbp = dp->lh_first;
244 for(; nbp != NULL; nbp = nbp->b_hash.le_next) {
245 if(nbp == bp)
246 panic("buf already in hashlist");
247 }
0c530ab8 248#endif /* DIAGNOSTIC */
1c79356b 249
1c79356b 250 blistenterhead(dp, bp);
1c79356b
A
251}
252
9bccf70c 253static __inline__ void
91447636 254bremhash(buf_t bp)
1c79356b 255{
1c79356b
A
256 if (bp->b_hash.le_prev == (struct buf **)0xdeadbeef)
257 panic("bremhash le_prev is deadbeef");
258 if (bp->b_hash.le_next == bp)
259 panic("bremhash: next points to self");
260
261 if (bp->b_hash.le_next != NULL)
262 bp->b_hash.le_next->b_hash.le_prev = bp->b_hash.le_prev;
263 *bp->b_hash.le_prev = (bp)->b_hash.le_next;
1c79356b
A
264}
265
1c79356b 266
1c79356b 267
9bccf70c 268
91447636
A
269int
270buf_valid(buf_t bp) {
271
272 if ( (bp->b_flags & (B_DONE | B_DELWRI)) )
273 return 1;
274 return 0;
9bccf70c
A
275}
276
91447636
A
277int
278buf_fromcache(buf_t bp) {
9bccf70c 279
91447636
A
280 if ( (bp->b_flags & B_CACHE) )
281 return 1;
282 return 0;
9bccf70c
A
283}
284
9bccf70c 285void
91447636
A
286buf_markinvalid(buf_t bp) {
287
288 SET(bp->b_flags, B_INVAL);
289}
9bccf70c 290
91447636
A
291void
292buf_markdelayed(buf_t bp) {
293
294 SET(bp->b_flags, B_DELWRI);
295 buf_reassign(bp, bp->b_vp);
9bccf70c
A
296}
297
91447636
A
298void
299buf_markeintr(buf_t bp) {
300
301 SET(bp->b_flags, B_EINTR);
302}
765c9de3 303
91447636
A
304void
305buf_markaged(buf_t bp) {
306
307 SET(bp->b_flags, B_AGE);
765c9de3
A
308}
309
91447636
A
310errno_t
311buf_error(buf_t bp) {
312
313 return (bp->b_error);
314}
1c79356b 315
91447636
A
316void
317buf_seterror(buf_t bp, errno_t error) {
1c79356b 318
91447636
A
319 if ((bp->b_error = error))
320 SET(bp->b_flags, B_ERROR);
321 else
322 CLR(bp->b_flags, B_ERROR);
323}
1c79356b 324
91447636
A
325void
326buf_setflags(buf_t bp, int32_t flags) {
1c79356b 327
91447636
A
328 SET(bp->b_flags, (flags & BUF_X_WRFLAGS));
329}
765c9de3 330
91447636
A
331void
332buf_clearflags(buf_t bp, int32_t flags) {
1c79356b 333
91447636
A
334 CLR(bp->b_flags, (flags & BUF_X_WRFLAGS));
335}
1c79356b 336
91447636
A
337int32_t
338buf_flags(buf_t bp) {
339
340 return ((bp->b_flags & BUF_X_RDFLAGS));
341}
1c79356b 342
91447636
A
343void
344buf_reset(buf_t bp, int32_t io_flags) {
345
346 CLR(bp->b_flags, (B_READ | B_WRITE | B_ERROR | B_DONE | B_INVAL | B_ASYNC | B_NOCACHE));
347 SET(bp->b_flags, (io_flags & (B_ASYNC | B_READ | B_WRITE | B_NOCACHE)));
1c79356b 348
91447636
A
349 bp->b_error = 0;
350}
1c79356b 351
91447636
A
352uint32_t
353buf_count(buf_t bp) {
354
355 return (bp->b_bcount);
356}
765c9de3 357
91447636
A
358void
359buf_setcount(buf_t bp, uint32_t bcount) {
360
361 bp->b_bcount = bcount;
1c79356b
A
362}
363
91447636
A
364uint32_t
365buf_size(buf_t bp) {
366
367 return (bp->b_bufsize);
368}
1c79356b 369
91447636
A
370void
371buf_setsize(buf_t bp, uint32_t bufsize) {
372
373 bp->b_bufsize = bufsize;
374}
1c79356b 375
91447636
A
376uint32_t
377buf_resid(buf_t bp) {
378
379 return (bp->b_resid);
380}
b4c24cb9 381
91447636
A
382void
383buf_setresid(buf_t bp, uint32_t resid) {
384
385 bp->b_resid = resid;
386}
1c79356b 387
91447636
A
388uint32_t
389buf_dirtyoff(buf_t bp) {
1c79356b 390
91447636
A
391 return (bp->b_dirtyoff);
392}
1c79356b 393
91447636
A
394uint32_t
395buf_dirtyend(buf_t bp) {
1c79356b 396
91447636 397 return (bp->b_dirtyend);
1c79356b 398}
1c79356b 399
91447636
A
400void
401buf_setdirtyoff(buf_t bp, uint32_t dirtyoff) {
402
403 bp->b_dirtyoff = dirtyoff;
404}
1c79356b 405
91447636
A
406void
407buf_setdirtyend(buf_t bp, uint32_t dirtyend) {
408
409 bp->b_dirtyend = dirtyend;
1c79356b
A
410}
411
91447636
A
412uintptr_t
413buf_dataptr(buf_t bp) {
414
415 return (bp->b_datap);
416}
1c79356b 417
91447636
A
418void
419buf_setdataptr(buf_t bp, uintptr_t data) {
420
421 bp->b_datap = data;
422}
423
424vnode_t
425buf_vnode(buf_t bp) {
426
427 return (bp->b_vp);
428}
429
430void
431buf_setvnode(buf_t bp, vnode_t vp) {
432
433 bp->b_vp = vp;
434}
435
436
437void *
438buf_callback(buf_t bp)
439{
440 if ( !(bp->b_lflags & BL_IOBUF) )
441 return ((void *) NULL);
442 if ( !(bp->b_flags & B_CALL) )
443 return ((void *) NULL);
444
445 return ((void *)bp->b_iodone);
446}
447
448
449errno_t
450buf_setcallback(buf_t bp, void (*callback)(buf_t, void *), void *transaction)
451{
452
453 if ( !(bp->b_lflags & BL_IOBUF) )
454 return (EINVAL);
455
456 if (callback)
457 bp->b_flags |= (B_CALL | B_ASYNC);
458 else
459 bp->b_flags &= ~B_CALL;
460 bp->b_transaction = transaction;
461 bp->b_iodone = callback;
462
463 return (0);
464}
465
466errno_t
467buf_setupl(buf_t bp, upl_t upl, uint32_t offset)
468{
469
470 if ( !(bp->b_lflags & BL_IOBUF) )
471 return (EINVAL);
472
473 if (upl)
474 bp->b_flags |= B_CLUSTER;
475 else
476 bp->b_flags &= ~B_CLUSTER;
477 bp->b_upl = upl;
478 bp->b_uploffset = offset;
479
480 return (0);
481}
482
483buf_t
484buf_clone(buf_t bp, int io_offset, int io_size, void (*iodone)(buf_t, void *), void *arg)
485{
486 buf_t io_bp;
487
488 if (io_offset < 0 || io_size < 0)
489 return (NULL);
490
491 if ((unsigned)(io_offset + io_size) > (unsigned)bp->b_bcount)
492 return (NULL);
493
494 if (bp->b_flags & B_CLUSTER) {
495 if (io_offset && ((bp->b_uploffset + io_offset) & PAGE_MASK))
496 return (NULL);
497
498 if (((bp->b_uploffset + io_offset + io_size) & PAGE_MASK) && ((io_offset + io_size) < bp->b_bcount))
499 return (NULL);
500 }
501 io_bp = alloc_io_buf(bp->b_vp, 0);
502
503 io_bp->b_flags = bp->b_flags & (B_COMMIT_UPL | B_META | B_PAGEIO | B_CLUSTER | B_PHYS | B_ASYNC | B_READ);
504
505 if (iodone) {
506 io_bp->b_transaction = arg;
507 io_bp->b_iodone = iodone;
508 io_bp->b_flags |= B_CALL;
509 }
510 if (bp->b_flags & B_CLUSTER) {
511 io_bp->b_upl = bp->b_upl;
512 io_bp->b_uploffset = bp->b_uploffset + io_offset;
513 } else {
514 io_bp->b_datap = (uintptr_t)(((char *)bp->b_datap) + io_offset);
515 }
516 io_bp->b_bcount = io_size;
517
518 return (io_bp);
519}
520
521
522
523void
524buf_setfilter(buf_t bp, void (*filter)(buf_t, void *), void *transaction,
525 void **old_iodone, void **old_transaction)
526{
527 if (old_iodone)
528 *old_iodone = (void *)(bp->b_iodone);
529 if (old_transaction)
530 *old_transaction = (void *)(bp->b_transaction);
531
532 bp->b_transaction = transaction;
533 bp->b_iodone = filter;
534 bp->b_flags |= B_FILTER;
535}
536
537
538daddr64_t
539buf_blkno(buf_t bp) {
540
541 return (bp->b_blkno);
542}
543
544daddr64_t
545buf_lblkno(buf_t bp) {
546
547 return (bp->b_lblkno);
548}
549
550void
551buf_setblkno(buf_t bp, daddr64_t blkno) {
552
553 bp->b_blkno = blkno;
554}
555
556void
557buf_setlblkno(buf_t bp, daddr64_t lblkno) {
558
559 bp->b_lblkno = lblkno;
560}
561
562dev_t
563buf_device(buf_t bp) {
564
565 return (bp->b_dev);
566}
567
568errno_t
569buf_setdevice(buf_t bp, vnode_t vp) {
570
571 if ((vp->v_type != VBLK) && (vp->v_type != VCHR))
572 return EINVAL;
573 bp->b_dev = vp->v_rdev;
574
575 return 0;
576}
577
578
579void *
580buf_drvdata(buf_t bp) {
581
582 return (bp->b_drvdata);
583}
584
585void
586buf_setdrvdata(buf_t bp, void *drvdata) {
587
588 bp->b_drvdata = drvdata;
589}
590
591void *
592buf_fsprivate(buf_t bp) {
593
594 return (bp->b_fsprivate);
595}
596
597void
598buf_setfsprivate(buf_t bp, void *fsprivate) {
599
600 bp->b_fsprivate = fsprivate;
601}
602
603ucred_t
604buf_rcred(buf_t bp) {
605
606 return (bp->b_rcred);
607}
608
609ucred_t
610buf_wcred(buf_t bp) {
611
612 return (bp->b_wcred);
613}
614
615void *
616buf_upl(buf_t bp) {
617
618 return (bp->b_upl);
619}
620
621uint32_t
622buf_uploffset(buf_t bp) {
623
624 return ((uint32_t)(bp->b_uploffset));
625}
626
627proc_t
628buf_proc(buf_t bp) {
629
630 return (bp->b_proc);
631}
632
633
634errno_t
635buf_map(buf_t bp, caddr_t *io_addr)
636{
637 buf_t real_bp;
638 vm_offset_t vaddr;
639 kern_return_t kret;
640
641 if ( !(bp->b_flags & B_CLUSTER)) {
642 *io_addr = (caddr_t)bp->b_datap;
643 return (0);
644 }
645 real_bp = (buf_t)(bp->b_real_bp);
646
647 if (real_bp && real_bp->b_datap) {
648 /*
649 * b_real_bp is only valid if B_CLUSTER is SET
650 * if it's non-zero, than someone did a cluster_bp call
651 * if the backing physical pages were already mapped
652 * in before the call to cluster_bp (non-zero b_datap),
653 * than we just use that mapping
654 */
655 *io_addr = (caddr_t)real_bp->b_datap;
656 return (0);
657 }
658 kret = ubc_upl_map(bp->b_upl, &vaddr); /* Map it in */
659
660 if (kret != KERN_SUCCESS) {
661 *io_addr = 0;
662
663 return(ENOMEM);
664 }
665 vaddr += bp->b_uploffset;
666
667 *io_addr = (caddr_t)vaddr;
668
669 return (0);
670}
671
672errno_t
673buf_unmap(buf_t bp)
674{
675 buf_t real_bp;
676 kern_return_t kret;
677
678 if ( !(bp->b_flags & B_CLUSTER))
679 return (0);
680 /*
681 * see buf_map for the explanation
682 */
683 real_bp = (buf_t)(bp->b_real_bp);
684
685 if (real_bp && real_bp->b_datap)
686 return (0);
687
688 if (bp->b_lflags & BL_IOBUF) {
689 /*
690 * when we commit these pages, we'll hit
691 * it with UPL_COMMIT_INACTIVE which
692 * will clear the reference bit that got
693 * turned on when we touched the mapping
694 */
695 bp->b_flags |= B_AGE;
696 }
697 kret = ubc_upl_unmap(bp->b_upl);
698
699 if (kret != KERN_SUCCESS)
700 return (EINVAL);
701 return (0);
702}
703
704
705void
706buf_clear(buf_t bp) {
707 caddr_t baddr;
708
709 if (buf_map(bp, &baddr) == 0) {
710 bzero(baddr, bp->b_bcount);
711 buf_unmap(bp);
712 }
713 bp->b_resid = 0;
714}
715
716
717
718/*
719 * Read or write a buffer that is not contiguous on disk.
720 * buffer is marked done/error at the conclusion
721 */
722static int
723buf_strategy_fragmented(vnode_t devvp, buf_t bp, off_t f_offset, size_t contig_bytes)
724{
725 vnode_t vp = buf_vnode(bp);
726 buf_t io_bp; /* For reading or writing a single block */
727 int io_direction;
728 int io_resid;
729 size_t io_contig_bytes;
730 daddr64_t io_blkno;
731 int error = 0;
732 int bmap_flags;
733
734 /*
735 * save our starting point... the bp was already mapped
736 * in buf_strategy before we got called
737 * no sense doing it again.
738 */
739 io_blkno = bp->b_blkno;
740 /*
741 * Make sure we redo this mapping for the next I/O
742 * i.e. this can never be a 'permanent' mapping
743 */
744 bp->b_blkno = bp->b_lblkno;
745
746 /*
747 * Get an io buffer to do the deblocking
748 */
749 io_bp = alloc_io_buf(devvp, 0);
750
751 io_bp->b_lblkno = bp->b_lblkno;
752 io_bp->b_datap = bp->b_datap;
753 io_resid = bp->b_bcount;
754 io_direction = bp->b_flags & B_READ;
755 io_contig_bytes = contig_bytes;
756
757 if (bp->b_flags & B_READ)
758 bmap_flags = VNODE_READ;
759 else
760 bmap_flags = VNODE_WRITE;
761
762 for (;;) {
763 if (io_blkno == -1)
764 /*
765 * this is unexepected, but we'll allow for it
766 */
767 bzero((caddr_t)io_bp->b_datap, (int)io_contig_bytes);
768 else {
769 io_bp->b_bcount = io_contig_bytes;
770 io_bp->b_bufsize = io_contig_bytes;
771 io_bp->b_resid = io_contig_bytes;
772 io_bp->b_blkno = io_blkno;
773
774 buf_reset(io_bp, io_direction);
775 /*
776 * Call the device to do the I/O and wait for it
777 */
778 if ((error = VNOP_STRATEGY(io_bp)))
779 break;
780 if ((error = (int)buf_biowait(io_bp)))
781 break;
782 if (io_bp->b_resid) {
783 io_resid -= (io_contig_bytes - io_bp->b_resid);
784 break;
785 }
786 }
787 if ((io_resid -= io_contig_bytes) == 0)
788 break;
789 f_offset += io_contig_bytes;
790 io_bp->b_datap += io_contig_bytes;
791
792 /*
793 * Map the current position to a physical block number
794 */
795 if ((error = VNOP_BLOCKMAP(vp, f_offset, io_resid, &io_blkno, &io_contig_bytes, NULL, bmap_flags, NULL)))
796 break;
797 }
798 buf_free(io_bp);
799
800 if (error)
801 buf_seterror(bp, error);
802 bp->b_resid = io_resid;
803 /*
804 * This I/O is now complete
805 */
806 buf_biodone(bp);
807
808 return error;
809}
810
811
812/*
813 * struct vnop_strategy_args {
814 * struct buf *a_bp;
815 * } *ap;
816 */
817errno_t
818buf_strategy(vnode_t devvp, void *ap)
819{
820 buf_t bp = ((struct vnop_strategy_args *)ap)->a_bp;
821 vnode_t vp = bp->b_vp;
822 int bmap_flags;
823 errno_t error;
824
825 if (vp == NULL || vp->v_type == VCHR || vp->v_type == VBLK)
826 panic("buf_strategy: b_vp == NULL || vtype == VCHR | VBLK\n");
827 /*
828 * associate the physical device with
829 * with this buf_t even if we don't
830 * end up issuing the I/O...
831 */
832 bp->b_dev = devvp->v_rdev;
833
834 if (bp->b_flags & B_READ)
835 bmap_flags = VNODE_READ;
836 else
837 bmap_flags = VNODE_WRITE;
838
839 if ( !(bp->b_flags & B_CLUSTER)) {
840
841 if ( (bp->b_upl) ) {
842 /*
843 * we have a UPL associated with this bp
844 * go through cluster_bp which knows how
845 * to deal with filesystem block sizes
846 * that aren't equal to the page size
847 */
848 return (cluster_bp(bp));
849 }
850 if (bp->b_blkno == bp->b_lblkno) {
851 off_t f_offset;
852 size_t contig_bytes;
853
854 if ((error = VNOP_BLKTOOFF(vp, bp->b_lblkno, &f_offset))) {
855 buf_seterror(bp, error);
856 buf_biodone(bp);
857
858 return (error);
859 }
860 if ((error = VNOP_BLOCKMAP(vp, f_offset, bp->b_bcount, &bp->b_blkno, &contig_bytes, NULL, bmap_flags, NULL))) {
861 buf_seterror(bp, error);
862 buf_biodone(bp);
863
864 return (error);
865 }
866 if (bp->b_blkno == -1)
867 buf_clear(bp);
868 else if ((long)contig_bytes < bp->b_bcount)
869 return (buf_strategy_fragmented(devvp, bp, f_offset, contig_bytes));
870 }
871 if (bp->b_blkno == -1) {
872 buf_biodone(bp);
873 return (0);
874 }
875 }
876 /*
877 * we can issue the I/O because...
878 * either B_CLUSTER is set which
879 * means that the I/O is properly set
880 * up to be a multiple of the page size, or
881 * we were able to successfully set up the
882 * phsyical block mapping
883 */
884 return (VOCALL(devvp->v_op, VOFFSET(vnop_strategy), ap));
885}
886
887
888
889buf_t
890buf_alloc(vnode_t vp)
891{
892 return(alloc_io_buf(vp, 0));
893}
894
895void
896buf_free(buf_t bp) {
897
898 free_io_buf(bp);
899}
900
901
902
903void
904buf_iterate(vnode_t vp, int (*callout)(buf_t, void *), int flags, void *arg) {
905 buf_t bp;
906 int retval;
907 struct buflists local_iterblkhd;
908 int lock_flags = BAC_NOWAIT | BAC_REMOVE;
909
910 if (flags & BUF_SKIP_LOCKED)
911 lock_flags |= BAC_SKIP_LOCKED;
912 if (flags & BUF_SKIP_NONLOCKED)
913 lock_flags |= BAC_SKIP_NONLOCKED;
914
915 lck_mtx_lock(buf_mtxp);
916
917 if (buf_iterprepare(vp, &local_iterblkhd, VBI_DIRTY)) {
918 lck_mtx_unlock(buf_mtxp);
919 return;
920 }
921 while (!LIST_EMPTY(&local_iterblkhd)) {
922 bp = LIST_FIRST(&local_iterblkhd);
923 LIST_REMOVE(bp, b_vnbufs);
924 LIST_INSERT_HEAD(&vp->v_dirtyblkhd, bp, b_vnbufs);
925
926 if (buf_acquire_locked(bp, lock_flags, 0, 0))
927 continue;
928
929 lck_mtx_unlock(buf_mtxp);
930
931 retval = callout(bp, arg);
932
933 switch (retval) {
934 case BUF_RETURNED:
935 buf_brelse(bp);
936 break;
937 case BUF_CLAIMED:
938 break;
939 case BUF_RETURNED_DONE:
940 buf_brelse(bp);
941 lck_mtx_lock(buf_mtxp);
942 goto out;
943 case BUF_CLAIMED_DONE:
944 lck_mtx_lock(buf_mtxp);
945 goto out;
946 }
947 lck_mtx_lock(buf_mtxp);
948 }
949out:
950 buf_itercomplete(vp, &local_iterblkhd, VBI_DIRTY);
951
952 lck_mtx_unlock(buf_mtxp);
953}
954
955
956/*
957 * Flush out and invalidate all buffers associated with a vnode.
958 */
959int
960buf_invalidateblks(vnode_t vp, int flags, int slpflag, int slptimeo)
961{
962 buf_t bp;
963 int error = 0;
964 int must_rescan = 1;
965 struct buflists local_iterblkhd;
966
967 lck_mtx_lock(buf_mtxp);
968
969 for (;;) {
970 if (must_rescan == 0)
971 /*
972 * the lists may not be empty, but all that's left at this
973 * point are metadata or B_LOCKED buffers which are being
974 * skipped... we know this because we made it through both
975 * the clean and dirty lists without dropping buf_mtxp...
976 * each time we drop buf_mtxp we bump "must_rescan"
977 */
978 break;
979 if (LIST_EMPTY(&vp->v_cleanblkhd) && LIST_EMPTY(&vp->v_dirtyblkhd))
980 break;
981 must_rescan = 0;
982 /*
983 * iterate the clean list
984 */
985 if (buf_iterprepare(vp, &local_iterblkhd, VBI_CLEAN)) {
986 goto try_dirty_list;
987 }
988 while (!LIST_EMPTY(&local_iterblkhd)) {
989 bp = LIST_FIRST(&local_iterblkhd);
990
991 LIST_REMOVE(bp, b_vnbufs);
992 LIST_INSERT_HEAD(&vp->v_cleanblkhd, bp, b_vnbufs);
993
994 /*
995 * some filesystems distinguish meta data blocks with a negative logical block #
996 */
997 if ((flags & BUF_SKIP_META) && (bp->b_lblkno < 0 || ISSET(bp->b_flags, B_META)))
998 continue;
999
1000 if ( (error = (int)buf_acquire_locked(bp, BAC_REMOVE | BAC_SKIP_LOCKED, slpflag, slptimeo)) ) {
1001 if (error == EDEADLK)
1002 /*
1003 * this buffer was marked B_LOCKED...
1004 * we didn't drop buf_mtxp, so we
1005 * we don't need to rescan
1006 */
1007 continue;
1008 if (error == EAGAIN) {
1009 /*
1010 * found a busy buffer... we blocked and
1011 * dropped buf_mtxp, so we're going to
1012 * need to rescan after this pass is completed
1013 */
1014 must_rescan++;
1015 continue;
1016 }
1017 /*
1018 * got some kind of 'real' error out of the msleep
1019 * in buf_acquire_locked, terminate the scan and return the error
1020 */
1021 buf_itercomplete(vp, &local_iterblkhd, VBI_CLEAN);
1022
1023 lck_mtx_unlock(buf_mtxp);
1024 return (error);
1025 }
1026 lck_mtx_unlock(buf_mtxp);
1027
1028 SET(bp->b_flags, B_INVAL);
1029 buf_brelse(bp);
1030
1031 lck_mtx_lock(buf_mtxp);
1032
1033 /*
1034 * by dropping buf_mtxp, we allow new
1035 * buffers to be added to the vnode list(s)
1036 * we'll have to rescan at least once more
1037 * if the queues aren't empty
1038 */
1039 must_rescan++;
1040 }
1041 buf_itercomplete(vp, &local_iterblkhd, VBI_CLEAN);
1042
1043try_dirty_list:
1044 /*
1045 * Now iterate on dirty blks
1046 */
1047 if (buf_iterprepare(vp, &local_iterblkhd, VBI_DIRTY)) {
1048 continue;
1049 }
1050 while (!LIST_EMPTY(&local_iterblkhd)) {
1051 bp = LIST_FIRST(&local_iterblkhd);
1052
1053 LIST_REMOVE(bp, b_vnbufs);
1054 LIST_INSERT_HEAD(&vp->v_dirtyblkhd, bp, b_vnbufs);
1055
1056 /*
1057 * some filesystems distinguish meta data blocks with a negative logical block #
1058 */
1059 if ((flags & BUF_SKIP_META) && (bp->b_lblkno < 0 || ISSET(bp->b_flags, B_META)))
1060 continue;
1061
1062 if ( (error = (int)buf_acquire_locked(bp, BAC_REMOVE | BAC_SKIP_LOCKED, slpflag, slptimeo)) ) {
1063 if (error == EDEADLK)
1064 /*
1065 * this buffer was marked B_LOCKED...
1066 * we didn't drop buf_mtxp, so we
1067 * we don't need to rescan
1068 */
1069 continue;
1070 if (error == EAGAIN) {
1071 /*
1072 * found a busy buffer... we blocked and
1073 * dropped buf_mtxp, so we're going to
1074 * need to rescan after this pass is completed
1075 */
1076 must_rescan++;
1077 continue;
1078 }
1079 /*
1080 * got some kind of 'real' error out of the msleep
1081 * in buf_acquire_locked, terminate the scan and return the error
1082 */
1083 buf_itercomplete(vp, &local_iterblkhd, VBI_DIRTY);
1084
1085 lck_mtx_unlock(buf_mtxp);
1086 return (error);
1087 }
1088 lck_mtx_unlock(buf_mtxp);
1089
1090 SET(bp->b_flags, B_INVAL);
1091
1092 if (ISSET(bp->b_flags, B_DELWRI) && (flags & BUF_WRITE_DATA))
1093 (void) VNOP_BWRITE(bp);
1094 else
1095 buf_brelse(bp);
1096
1097 lck_mtx_lock(buf_mtxp);
1098 /*
1099 * by dropping buf_mtxp, we allow new
1100 * buffers to be added to the vnode list(s)
1101 * we'll have to rescan at least once more
1102 * if the queues aren't empty
1103 */
1104 must_rescan++;
1105 }
1106 buf_itercomplete(vp, &local_iterblkhd, VBI_DIRTY);
1107 }
1108 lck_mtx_unlock(buf_mtxp);
1109
1110 return (0);
1111}
1112
1113void
1114buf_flushdirtyblks(vnode_t vp, int wait, int flags, char *msg) {
1115 buf_t bp;
1116 int writes_issued = 0;
1117 errno_t error;
1118 int busy = 0;
1119 struct buflists local_iterblkhd;
1120 int lock_flags = BAC_NOWAIT | BAC_REMOVE;
1121
1122 if (flags & BUF_SKIP_LOCKED)
1123 lock_flags |= BAC_SKIP_LOCKED;
1124 if (flags & BUF_SKIP_NONLOCKED)
1125 lock_flags |= BAC_SKIP_NONLOCKED;
1126loop:
1127 lck_mtx_lock(buf_mtxp);
1128
1129 if (buf_iterprepare(vp, &local_iterblkhd, VBI_DIRTY) == 0) {
1130 while (!LIST_EMPTY(&local_iterblkhd)) {
1131 bp = LIST_FIRST(&local_iterblkhd);
1132 LIST_REMOVE(bp, b_vnbufs);
1133 LIST_INSERT_HEAD(&vp->v_dirtyblkhd, bp, b_vnbufs);
1134
1135 if ((error = buf_acquire_locked(bp, lock_flags, 0, 0)) == EBUSY)
1136 busy++;
1137 if (error)
1138 continue;
1139 lck_mtx_unlock(buf_mtxp);
1140
1141 bp->b_flags &= ~B_LOCKED;
1142
1143 /*
1144 * Wait for I/O associated with indirect blocks to complete,
1145 * since there is no way to quickly wait for them below.
1146 */
1147 if ((bp->b_vp == vp) || (wait == 0))
1148 (void) buf_bawrite(bp);
1149 else
1150 (void) VNOP_BWRITE(bp);
1151 writes_issued++;
1152
1153 lck_mtx_lock(buf_mtxp);
1154 }
1155 buf_itercomplete(vp, &local_iterblkhd, VBI_DIRTY);
1156 }
1157 lck_mtx_unlock(buf_mtxp);
1158
1159 if (wait) {
1160 (void)vnode_waitforwrites(vp, 0, 0, 0, msg);
1161
1162 if (vp->v_dirtyblkhd.lh_first && busy) {
1163 /*
1164 * we had one or more BUSY buffers on
1165 * the dirtyblock list... most likely
1166 * these are due to delayed writes that
1167 * were moved to the bclean queue but
1168 * have not yet been 'written'.
1169 * if we issued some writes on the
1170 * previous pass, we try again immediately
1171 * if we didn't, we'll sleep for some time
1172 * to allow the state to change...
1173 */
1174 if (writes_issued == 0) {
1175 (void)tsleep((caddr_t)&vp->v_numoutput,
1176 PRIBIO + 1, "vnode_flushdirtyblks", hz/20);
1177 }
1178 writes_issued = 0;
1179 busy = 0;
1180
1181 goto loop;
1182 }
1183 }
1184}
1185
1186
1187/*
1188 * called with buf_mtxp held...
1189 * this lock protects the queue manipulation
1190 */
1191static int
1192buf_iterprepare(vnode_t vp, struct buflists *iterheadp, int flags)
1193{
1194 struct buflists * listheadp;
1195
1196 if (flags & VBI_DIRTY)
1197 listheadp = &vp->v_dirtyblkhd;
1198 else
1199 listheadp = &vp->v_cleanblkhd;
1200
1201 while (vp->v_iterblkflags & VBI_ITER) {
1202 vp->v_iterblkflags |= VBI_ITERWANT;
1203 msleep(&vp->v_iterblkflags, buf_mtxp, 0, "buf_iterprepare", 0);
1204 }
1205 if (LIST_EMPTY(listheadp)) {
1206 LIST_INIT(iterheadp);
1207 return(EINVAL);
1208 }
1209 vp->v_iterblkflags |= VBI_ITER;
1210
1211 iterheadp->lh_first = listheadp->lh_first;
1212 listheadp->lh_first->b_vnbufs.le_prev = &iterheadp->lh_first;
1213 LIST_INIT(listheadp);
1214
1215 return(0);
1216}
1217
1218/*
1219 * called with buf_mtxp held...
1220 * this lock protects the queue manipulation
1221 */
1222static void
1223buf_itercomplete(vnode_t vp, struct buflists *iterheadp, int flags)
1224{
1225 struct buflists * listheadp;
1226 buf_t bp;
1227
1228 if (flags & VBI_DIRTY)
1229 listheadp = &vp->v_dirtyblkhd;
1230 else
1231 listheadp = &vp->v_cleanblkhd;
1232
1233 while (!LIST_EMPTY(iterheadp)) {
1234 bp = LIST_FIRST(iterheadp);
1235 LIST_REMOVE(bp, b_vnbufs);
1236 LIST_INSERT_HEAD(listheadp, bp, b_vnbufs);
1237 }
1238 vp->v_iterblkflags &= ~VBI_ITER;
1239
1240 if (vp->v_iterblkflags & VBI_ITERWANT) {
1241 vp->v_iterblkflags &= ~VBI_ITERWANT;
1242 wakeup(&vp->v_iterblkflags);
1243 }
1244}
1245
1246
1247static void
1248bremfree_locked(buf_t bp)
1249{
1250 struct bqueues *dp = NULL;
1251 int whichq = -1;
1252
1253 /*
1254 * We only calculate the head of the freelist when removing
1255 * the last element of the list as that is the only time that
1256 * it is needed (e.g. to reset the tail pointer).
1257 *
1258 * NB: This makes an assumption about how tailq's are implemented.
1259 */
1260 if (bp->b_freelist.tqe_next == NULL) {
1261 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++)
1262 if (dp->tqh_last == &bp->b_freelist.tqe_next)
1263 break;
1264 if (dp == &bufqueues[BQUEUES])
1265 panic("bremfree: lost tail");
1266 }
1267 TAILQ_REMOVE(dp, bp, b_freelist);
1268 whichq = bp->b_whichq;
1269#if BALANCE_QUEUES
1270 bufqdec(whichq);
1271#endif
1272 bp->b_whichq = -1;
1273 bp->b_timestamp = 0;
1274}
1275
1276/*
1277 * Associate a buffer with a vnode.
1278 */
1279static void
1280bgetvp(vnode_t vp, buf_t bp)
1281{
1282
1283 if (bp->b_vp != vp)
1284 panic("bgetvp: not free");
1285
1286 if (vp->v_type == VBLK || vp->v_type == VCHR)
1287 bp->b_dev = vp->v_rdev;
1288 else
1289 bp->b_dev = NODEV;
1290 /*
1291 * Insert onto list for new vnode.
1292 */
1293 lck_mtx_lock(buf_mtxp);
1294 bufinsvn(bp, &vp->v_cleanblkhd);
1295 lck_mtx_unlock(buf_mtxp);
1296}
1297
1298/*
1299 * Disassociate a buffer from a vnode.
1300 */
1301static void
1302brelvp(buf_t bp)
1303{
1304 vnode_t vp;
1305
1306 if ((vp = bp->b_vp) == (vnode_t)NULL)
1307 panic("brelvp: NULL vp");
1308 /*
1309 * Delete from old vnode list, if on one.
1310 */
1311 lck_mtx_lock(buf_mtxp);
1312 if (bp->b_vnbufs.le_next != NOLIST)
1313 bufremvn(bp);
1314 lck_mtx_unlock(buf_mtxp);
1315
1316 bp->b_vp = (vnode_t)NULL;
1317}
1318
1319/*
1320 * Reassign a buffer from one vnode to another.
1321 * Used to assign file specific control information
1322 * (indirect blocks) to the vnode to which they belong.
1323 */
1324static void
1325buf_reassign(buf_t bp, vnode_t newvp)
1326{
1327 register struct buflists *listheadp;
1c79356b 1328
91447636
A
1329 if (newvp == NULL) {
1330 printf("buf_reassign: NULL");
1331 return;
1332 }
1333 lck_mtx_lock(buf_mtxp);
1334
1335 /*
1336 * Delete from old vnode list, if on one.
1337 */
1338 if (bp->b_vnbufs.le_next != NOLIST)
1339 bufremvn(bp);
1340 /*
1341 * If dirty, put on list of dirty buffers;
1342 * otherwise insert onto list of clean buffers.
1343 */
1344 if (ISSET(bp->b_flags, B_DELWRI))
1345 listheadp = &newvp->v_dirtyblkhd;
1346 else
1347 listheadp = &newvp->v_cleanblkhd;
1348 bufinsvn(bp, listheadp);
1349
1350 lck_mtx_unlock(buf_mtxp);
1c79356b
A
1351}
1352
91447636
A
1353static __inline__ void
1354bufhdrinit(buf_t bp)
55e303ae 1355{
91447636
A
1356 bzero((char *)bp, sizeof *bp);
1357 bp->b_dev = NODEV;
1358 bp->b_rcred = NOCRED;
1359 bp->b_wcred = NOCRED;
1360 bp->b_vnbufs.le_next = NOLIST;
1361 bp->b_flags = B_INVAL;
1362
1363 return;
55e303ae
A
1364}
1365
1366/*
91447636 1367 * Initialize buffers and hash links for buffers.
55e303ae 1368 */
91447636
A
1369__private_extern__ void
1370bufinit()
55e303ae 1371{
91447636
A
1372 buf_t bp;
1373 struct bqueues *dp;
1374 int i;
1375 int metabuf;
1376 long whichq;
1377
0c530ab8 1378 nbuf = 0;
91447636
A
1379 /* Initialize the buffer queues ('freelists') and the hash table */
1380 for (dp = bufqueues; dp < &bufqueues[BQUEUES]; dp++)
1381 TAILQ_INIT(dp);
0c530ab8 1382 bufhashtbl = hashinit(nbuf_hashelements, M_CACHE, &bufhash);
91447636 1383
0c530ab8 1384 metabuf = max_nbuf_headers/8; /* reserved for meta buf */
91447636
A
1385
1386 /* Initialize the buffer headers */
0c530ab8
A
1387 for (i = 0; i < max_nbuf_headers; i++) {
1388 nbuf++;
91447636
A
1389 bp = &buf[i];
1390 bufhdrinit(bp);
1391
1392 /*
1393 * metabuf buffer headers on the meta-data list and
1394 * rest of the buffer headers on the empty list
1395 */
1396 if (--metabuf)
1397 whichq = BQ_META;
1398 else
1399 whichq = BQ_EMPTY;
1400
1401 BLISTNONE(bp);
1402 dp = &bufqueues[whichq];
1403 binsheadfree(bp, dp, whichq);
1404 binshash(bp, &invalhash);
1405 }
1406
0c530ab8
A
1407 boot_nbuf = nbuf;
1408
91447636
A
1409 for (; i < nbuf + niobuf; i++) {
1410 bp = &buf[i];
1411 bufhdrinit(bp);
1412 binsheadfree(bp, &iobufqueue, -1);
1413 }
1414
0c530ab8 1415 /*
91447636
A
1416 * allocate lock group attribute and group
1417 */
0c530ab8 1418 buf_mtx_grp_attr = lck_grp_attr_alloc_init();
91447636
A
1419 buf_mtx_grp = lck_grp_alloc_init("buffer cache", buf_mtx_grp_attr);
1420
1421 /*
1422 * allocate the lock attribute
1423 */
1424 buf_mtx_attr = lck_attr_alloc_init();
91447636
A
1425
1426 /*
1427 * allocate and initialize mutex's for the buffer and iobuffer pools
1428 */
1429 buf_mtxp = lck_mtx_alloc_init(buf_mtx_grp, buf_mtx_attr);
1430 iobuffer_mtxp = lck_mtx_alloc_init(buf_mtx_grp, buf_mtx_attr);
1431
1432 if (iobuffer_mtxp == NULL)
1433 panic("couldn't create iobuffer mutex");
1434
1435 if (buf_mtxp == NULL)
1436 panic("couldn't create buf mutex");
1437
1438 /*
1439 * allocate and initialize cluster specific global locks...
1440 */
1441 cluster_init();
1442
1443 printf("using %d buffer headers and %d cluster IO buffer headers\n",
1444 nbuf, niobuf);
1445
1446 /* Set up zones used by the buffer cache */
1447 bufzoneinit();
1448
1449 /* start the bcleanbuf() thread */
1450 bcleanbuf_thread_init();
1451
1452#if BALANCE_QUEUES
1453 {
1454 static void bufq_balance_thread_init();
1455 /* create a thread to do dynamic buffer queue balancing */
1456 bufq_balance_thread_init();
1457 }
1458#endif /* notyet */
1459}
1460
1461static struct buf *
1462bio_doread(vnode_t vp, daddr64_t blkno, int size, ucred_t cred, int async, int queuetype)
1463{
1464 buf_t bp;
1465
1466 bp = buf_getblk(vp, blkno, size, 0, 0, queuetype);
1467
1468 /*
1469 * If buffer does not have data valid, start a read.
1470 * Note that if buffer is B_INVAL, buf_getblk() won't return it.
1471 * Therefore, it's valid if it's I/O has completed or been delayed.
1472 */
1473 if (!ISSET(bp->b_flags, (B_DONE | B_DELWRI))) {
1474 struct proc *p;
1475
1476 p = current_proc();
1477
1478 /* Start I/O for the buffer (keeping credentials). */
1479 SET(bp->b_flags, B_READ | async);
0c530ab8 1480 if (IS_VALID_CRED(cred) && !IS_VALID_CRED(bp->b_rcred)) {
91447636
A
1481 kauth_cred_ref(cred);
1482 bp->b_rcred = cred;
1483 }
1484
1485 VNOP_STRATEGY(bp);
1486
1487 trace(TR_BREADMISS, pack(vp, size), blkno);
1488
1489 /* Pay for the read. */
1490 if (p && p->p_stats)
1491 p->p_stats->p_ru.ru_inblock++; /* XXX */
1492
1493 if (async) {
1494 /*
1495 * since we asked for an ASYNC I/O
1496 * the biodone will do the brelse
1497 * we don't want to pass back a bp
1498 * that we don't 'own'
1499 */
1500 bp = NULL;
1501 }
1502 } else if (async) {
1503 buf_brelse(bp);
1504 bp = NULL;
1505 }
1506
1507 trace(TR_BREADHIT, pack(vp, size), blkno);
1508
1509 return (bp);
55e303ae
A
1510}
1511
1512/*
91447636 1513 * Perform the reads for buf_breadn() and buf_meta_breadn().
55e303ae
A
1514 * Trivial modification to the breada algorithm presented in Bach (p.55).
1515 */
91447636
A
1516static errno_t
1517do_breadn_for_type(vnode_t vp, daddr64_t blkno, int size, daddr64_t *rablks, int *rasizes,
1518 int nrablks, ucred_t cred, buf_t *bpp, int queuetype)
1c79356b 1519{
91447636
A
1520 buf_t bp;
1521 int i;
1c79356b 1522
55e303ae 1523 bp = *bpp = bio_doread(vp, blkno, size, cred, 0, queuetype);
1c79356b
A
1524
1525 /*
1526 * For each of the read-ahead blocks, start a read, if necessary.
1527 */
1528 for (i = 0; i < nrablks; i++) {
1529 /* If it's in the cache, just go on to next one. */
1530 if (incore(vp, rablks[i]))
1531 continue;
1532
1533 /* Get a buffer for the read-ahead block */
55e303ae 1534 (void) bio_doread(vp, rablks[i], rasizes[i], cred, B_ASYNC, queuetype);
1c79356b
A
1535 }
1536
1537 /* Otherwise, we had to start a read for it; wait until it's valid. */
91447636 1538 return (buf_biowait(bp));
1c79356b
A
1539}
1540
91447636 1541
1c79356b 1542/*
91447636
A
1543 * Read a disk block.
1544 * This algorithm described in Bach (p.54).
1c79356b 1545 */
91447636
A
1546errno_t
1547buf_bread(vnode_t vp, daddr64_t blkno, int size, ucred_t cred, buf_t *bpp)
1548{
1549 buf_t bp;
1550
1551 /* Get buffer for block. */
1552 bp = *bpp = bio_doread(vp, blkno, size, cred, 0, BLK_READ);
1553
1554 /* Wait for the read to complete, and return result. */
1555 return (buf_biowait(bp));
1556}
1557
1558/*
1559 * Read a disk block. [bread() for meta-data]
1560 * This algorithm described in Bach (p.54).
1561 */
1562errno_t
1563buf_meta_bread(vnode_t vp, daddr64_t blkno, int size, ucred_t cred, buf_t *bpp)
1564{
1565 buf_t bp;
1566
1567 /* Get buffer for block. */
1568 bp = *bpp = bio_doread(vp, blkno, size, cred, 0, BLK_META);
1569
1570 /* Wait for the read to complete, and return result. */
1571 return (buf_biowait(bp));
1572}
1573
1574/*
1575 * Read-ahead multiple disk blocks. The first is sync, the rest async.
1576 */
1577errno_t
1578buf_breadn(vnode_t vp, daddr64_t blkno, int size, daddr64_t *rablks, int *rasizes, int nrablks, ucred_t cred, buf_t *bpp)
1c79356b 1579{
91447636
A
1580 return (do_breadn_for_type(vp, blkno, size, rablks, rasizes, nrablks, cred, bpp, BLK_READ));
1581}
1c79356b 1582
91447636
A
1583/*
1584 * Read-ahead multiple disk blocks. The first is sync, the rest async.
1585 * [buf_breadn() for meta-data]
1586 */
1587errno_t
1588buf_meta_breadn(vnode_t vp, daddr64_t blkno, int size, daddr64_t *rablks, int *rasizes, int nrablks, ucred_t cred, buf_t *bpp)
1589{
1590 return (do_breadn_for_type(vp, blkno, size, rablks, rasizes, nrablks, cred, bpp, BLK_META));
1c79356b
A
1591}
1592
1593/*
1594 * Block write. Described in Bach (p.56)
1595 */
91447636
A
1596errno_t
1597buf_bwrite(buf_t bp)
1c79356b 1598{
91447636
A
1599 int sync, wasdelayed;
1600 errno_t rv;
1601 proc_t p = current_proc();
1602 vnode_t vp = bp->b_vp;
1c79356b 1603
91447636 1604 if (bp->b_datap == 0) {
55e303ae
A
1605 if (brecover_data(bp) == 0)
1606 return (0);
1607 }
1c79356b
A
1608 /* Remember buffer type, to switch on it later. */
1609 sync = !ISSET(bp->b_flags, B_ASYNC);
1610 wasdelayed = ISSET(bp->b_flags, B_DELWRI);
1611 CLR(bp->b_flags, (B_READ | B_DONE | B_ERROR | B_DELWRI));
91447636
A
1612
1613 if (wasdelayed)
1614 OSAddAtomic(-1, &nbdwrite);
1c79356b
A
1615
1616 if (!sync) {
1617 /*
1618 * If not synchronous, pay for the I/O operation and make
1619 * sure the buf is on the correct vnode queue. We have
1620 * to do this now, because if we don't, the vnode may not
1621 * be properly notified that its I/O has completed.
1622 */
1623 if (wasdelayed)
91447636 1624 buf_reassign(bp, vp);
1c79356b
A
1625 else
1626 if (p && p->p_stats)
1627 p->p_stats->p_ru.ru_oublock++; /* XXX */
1628 }
d52fe63f 1629 trace(TR_BUFWRITE, pack(vp, bp->b_bcount), bp->b_lblkno);
1c79356b
A
1630
1631 /* Initiate disk write. Make sure the appropriate party is charged. */
91447636
A
1632
1633 OSAddAtomic(1, &vp->v_numoutput);
1c79356b 1634
91447636 1635 VNOP_STRATEGY(bp);
1c79356b
A
1636
1637 if (sync) {
1638 /*
1639 * If I/O was synchronous, wait for it to complete.
1640 */
91447636 1641 rv = buf_biowait(bp);
1c79356b
A
1642
1643 /*
1644 * Pay for the I/O operation, if it's not been paid for, and
1645 * make sure it's on the correct vnode queue. (async operatings
1646 * were payed for above.)
1647 */
1648 if (wasdelayed)
91447636 1649 buf_reassign(bp, vp);
1c79356b
A
1650 else
1651 if (p && p->p_stats)
1652 p->p_stats->p_ru.ru_oublock++; /* XXX */
1653
1654 /* Release the buffer. */
b4c24cb9
A
1655 // XXXdbg - only if the unused bit is set
1656 if (!ISSET(bp->b_flags, B_NORELSE)) {
91447636 1657 buf_brelse(bp);
b4c24cb9
A
1658 } else {
1659 CLR(bp->b_flags, B_NORELSE);
1660 }
1c79356b
A
1661
1662 return (rv);
1663 } else {
1664 return (0);
1665 }
1666}
1667
1668int
1669vn_bwrite(ap)
91447636 1670 struct vnop_bwrite_args *ap;
1c79356b 1671{
91447636 1672 return (buf_bwrite(ap->a_bp));
1c79356b
A
1673}
1674
1675/*
1676 * Delayed write.
1677 *
1678 * The buffer is marked dirty, but is not queued for I/O.
1679 * This routine should be used when the buffer is expected
1680 * to be modified again soon, typically a small write that
1681 * partially fills a buffer.
1682 *
1683 * NB: magnetic tapes cannot be delayed; they must be
1684 * written in the order that the writes are requested.
1685 *
1686 * Described in Leffler, et al. (pp. 208-213).
d52fe63f
A
1687 *
1688 * Note: With the abilitty to allocate additional buffer
1689 * headers, we can get in to the situation where "too" many
91447636
A
1690 * buf_bdwrite()s can create situation where the kernel can create
1691 * buffers faster than the disks can service. Doing a buf_bawrite() in
1692 * cases were we have "too many" outstanding buf_bdwrite()s avoids that.
1c79356b 1693 */
9bccf70c 1694__private_extern__ int
91447636 1695bdwrite_internal(buf_t bp, int return_error)
1c79356b 1696{
91447636
A
1697 proc_t p = current_proc();
1698 vnode_t vp = bp->b_vp;
1c79356b
A
1699
1700 /*
1701 * If the block hasn't been seen before:
1702 * (1) Mark it as having been seen,
1703 * (2) Charge for the write.
1704 * (3) Make sure it's on its vnode's correct block list,
1705 */
1706 if (!ISSET(bp->b_flags, B_DELWRI)) {
1707 SET(bp->b_flags, B_DELWRI);
1708 if (p && p->p_stats)
1709 p->p_stats->p_ru.ru_oublock++; /* XXX */
91447636
A
1710 OSAddAtomic(1, &nbdwrite);
1711 buf_reassign(bp, vp);
1c79356b
A
1712 }
1713
1c79356b
A
1714 /* If this is a tape block, write it the block now. */
1715 if (ISSET(bp->b_flags, B_TAPE)) {
91447636 1716 VNOP_BWRITE(bp);
9bccf70c 1717 return (0);
1c79356b
A
1718 }
1719
d52fe63f 1720 /*
91447636
A
1721 * if we're not LOCKED, but the total number of delayed writes
1722 * has climbed above 75% of the total buffers in the system
1723 * return an error if the caller has indicated that it can
1724 * handle one in this case, otherwise schedule the I/O now
1725 * this is done to prevent us from allocating tons of extra
1726 * buffers when dealing with virtual disks (i.e. DiskImages),
1727 * because additional buffers are dynamically allocated to prevent
1728 * deadlocks from occurring
1729 *
1730 * however, can't do a buf_bawrite() if the LOCKED bit is set because the
1731 * buffer is part of a transaction and can't go to disk until
1732 * the LOCKED bit is cleared.
d52fe63f 1733 */
b4c24cb9 1734 if (!ISSET(bp->b_flags, B_LOCKED) && nbdwrite > ((nbuf/4)*3)) {
9bccf70c
A
1735 if (return_error)
1736 return (EAGAIN);
91447636
A
1737 /*
1738 * If the vnode has "too many" write operations in progress
1739 * wait for them to finish the IO
1740 */
1741 (void)vnode_waitforwrites(vp, VNODE_ASYNC_THROTTLE, 0, 0, (char *)"buf_bdwrite");
1742
1743 return (buf_bawrite(bp));
d52fe63f
A
1744 }
1745
1c79356b
A
1746 /* Otherwise, the "write" is done, so mark and release the buffer. */
1747 SET(bp->b_flags, B_DONE);
91447636 1748 buf_brelse(bp);
9bccf70c 1749 return (0);
1c79356b
A
1750}
1751
91447636
A
1752errno_t
1753buf_bdwrite(buf_t bp)
9bccf70c 1754{
91447636 1755 return (bdwrite_internal(bp, 0));
9bccf70c
A
1756}
1757
1758
1c79356b 1759/*
91447636 1760 * Asynchronous block write; just an asynchronous buf_bwrite().
d52fe63f
A
1761 *
1762 * Note: With the abilitty to allocate additional buffer
1763 * headers, we can get in to the situation where "too" many
91447636 1764 * buf_bawrite()s can create situation where the kernel can create
d52fe63f
A
1765 * buffers faster than the disks can service.
1766 * We limit the number of "in flight" writes a vnode can have to
1767 * avoid this.
1c79356b 1768 */
9bccf70c 1769static int
91447636 1770bawrite_internal(buf_t bp, int throttle)
1c79356b 1771{
91447636 1772 vnode_t vp = bp->b_vp;
d52fe63f
A
1773
1774 if (vp) {
91447636
A
1775 if (throttle)
1776 /*
1777 * If the vnode has "too many" write operations in progress
1778 * wait for them to finish the IO
1779 */
1780 (void)vnode_waitforwrites(vp, VNODE_ASYNC_THROTTLE, 0, 0, (const char *)"buf_bawrite");
1781 else if (vp->v_numoutput >= VNODE_ASYNC_THROTTLE)
1782 /*
1783 * return to the caller and
1784 * let him decide what to do
1785 */
1786 return (EWOULDBLOCK);
d52fe63f 1787 }
1c79356b 1788 SET(bp->b_flags, B_ASYNC);
9bccf70c 1789
91447636 1790 return (VNOP_BWRITE(bp));
9bccf70c
A
1791}
1792
91447636
A
1793errno_t
1794buf_bawrite(buf_t bp)
9bccf70c 1795{
91447636 1796 return (bawrite_internal(bp, 1));
1c79356b
A
1797}
1798
91447636 1799
1c79356b
A
1800/*
1801 * Release a buffer on to the free lists.
1802 * Described in Bach (p. 46).
1803 */
1804void
91447636 1805buf_brelse(buf_t bp)
1c79356b
A
1806{
1807 struct bqueues *bufq;
91447636
A
1808 long whichq;
1809 upl_t upl;
1810 int need_wakeup = 0;
1811 int need_bp_wakeup = 0;
1812
1813
1814 if (bp->b_whichq != -1 || !(bp->b_lflags & BL_BUSY))
1815 panic("buf_brelse: bad buffer = %x\n", bp);
1816
1817#ifdef JOE_DEBUG
1818 bp->b_stackbrelse[0] = __builtin_return_address(0);
1819 bp->b_stackbrelse[1] = __builtin_return_address(1);
1820 bp->b_stackbrelse[2] = __builtin_return_address(2);
1821 bp->b_stackbrelse[3] = __builtin_return_address(3);
1822 bp->b_stackbrelse[4] = __builtin_return_address(4);
1823 bp->b_stackbrelse[5] = __builtin_return_address(5);
1824
1825 bp->b_lastbrelse = current_thread();
1826 bp->b_tag = 0;
1827#endif
1828 if (bp->b_lflags & BL_IOBUF) {
1829 free_io_buf(bp);
1830 return;
1831 }
1c79356b
A
1832
1833 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 388)) | DBG_FUNC_START,
91447636 1834 bp->b_lblkno * PAGE_SIZE, (int)bp, (int)bp->b_datap,
fa4905b1 1835 bp->b_flags, 0);
1c79356b
A
1836
1837 trace(TR_BRELSE, pack(bp->b_vp, bp->b_bufsize), bp->b_lblkno);
1838
91447636
A
1839 /*
1840 * if we're invalidating a buffer that has the B_FILTER bit
1841 * set then call the b_iodone function so it gets cleaned
1842 * up properly.
1843 *
1844 * the HFS journal code depends on this
1845 */
b4c24cb9 1846 if (ISSET(bp->b_flags, B_META) && ISSET(bp->b_flags, B_INVAL)) {
91447636
A
1847 if (ISSET(bp->b_flags, B_FILTER)) { /* if necessary, call out */
1848 void (*iodone_func)(struct buf *, void *) = bp->b_iodone;
1849 void *arg = (void *)bp->b_transaction;
b4c24cb9 1850
91447636 1851 CLR(bp->b_flags, B_FILTER); /* but note callout done */
b4c24cb9 1852 bp->b_iodone = NULL;
91447636 1853 bp->b_transaction = NULL;
b4c24cb9
A
1854
1855 if (iodone_func == NULL) {
1856 panic("brelse: bp @ 0x%x has NULL b_iodone!\n", bp);
1857 }
91447636 1858 (*iodone_func)(bp, arg);
b4c24cb9
A
1859 }
1860 }
91447636
A
1861 /*
1862 * I/O is done. Cleanup the UPL state
1863 */
1864 upl = bp->b_upl;
1865
1866 if ( !ISSET(bp->b_flags, B_META) && UBCINFOEXISTS(bp->b_vp) && bp->b_bufsize) {
1c79356b 1867 kern_return_t kret;
1c79356b
A
1868 int upl_flags;
1869
91447636 1870 if ( (upl == NULL) ) {
1c79356b 1871 if ( !ISSET(bp->b_flags, B_INVAL)) {
0b4e3aa0 1872 kret = ubc_create_upl(bp->b_vp,
91447636
A
1873 ubc_blktooff(bp->b_vp, bp->b_lblkno),
1874 bp->b_bufsize,
1875 &upl,
1876 NULL,
1877 UPL_PRECIOUS);
1878
1c79356b 1879 if (kret != KERN_SUCCESS)
91447636
A
1880 panic("brelse: Failed to create UPL");
1881#ifdef UPL_DEBUG
1c79356b 1882 upl_ubc_alias_set(upl, bp, 5);
91447636
A
1883#endif /* UPL_DEBUG */
1884 }
1c79356b 1885 } else {
91447636 1886 if (bp->b_datap) {
55e303ae
A
1887 kret = ubc_upl_unmap(upl);
1888
1889 if (kret != KERN_SUCCESS)
91447636
A
1890 panic("ubc_upl_unmap failed");
1891 bp->b_datap = (uintptr_t)NULL;
55e303ae 1892 }
1c79356b
A
1893 }
1894 if (upl) {
1c79356b 1895 if (bp->b_flags & (B_ERROR | B_INVAL)) {
91447636 1896 if (bp->b_flags & (B_READ | B_INVAL))
1c79356b
A
1897 upl_flags = UPL_ABORT_DUMP_PAGES;
1898 else
1899 upl_flags = 0;
91447636 1900
0b4e3aa0 1901 ubc_upl_abort(upl, upl_flags);
1c79356b 1902 } else {
91447636
A
1903 if (ISSET(bp->b_flags, B_DELWRI | B_WASDIRTY))
1904 upl_flags = UPL_COMMIT_SET_DIRTY ;
1905 else
1906 upl_flags = UPL_COMMIT_CLEAR_DIRTY ;
1907
0b4e3aa0 1908 ubc_upl_commit_range(upl, 0, bp->b_bufsize, upl_flags |
91447636 1909 UPL_COMMIT_INACTIVATE | UPL_COMMIT_FREE_ON_EMPTY);
1c79356b 1910 }
91447636 1911 bp->b_upl = NULL;
1c79356b
A
1912 }
1913 } else {
91447636
A
1914 if ( (upl) )
1915 panic("brelse: UPL set for non VREG; vp=%x", bp->b_vp);
1c79356b
A
1916 }
1917
1c79356b 1918 /*
91447636 1919 * If it's locked, don't report an error; try again later.
1c79356b 1920 */
1c79356b
A
1921 if (ISSET(bp->b_flags, (B_LOCKED|B_ERROR)) == (B_LOCKED|B_ERROR))
1922 CLR(bp->b_flags, B_ERROR);
91447636
A
1923 /*
1924 * If it's not cacheable, or an error, mark it invalid.
1925 */
1c79356b
A
1926 if (ISSET(bp->b_flags, (B_NOCACHE|B_ERROR)))
1927 SET(bp->b_flags, B_INVAL);
91447636 1928
1c79356b
A
1929 if ((bp->b_bufsize <= 0) || ISSET(bp->b_flags, B_INVAL)) {
1930 /*
1931 * If it's invalid or empty, dissociate it from its vnode
1932 * and put on the head of the appropriate queue.
1933 */
91447636
A
1934 if (bp->b_vp)
1935 brelvp(bp);
1936
1937 if (ISSET(bp->b_flags, B_DELWRI))
1938 OSAddAtomic(-1, &nbdwrite);
1939
1940 CLR(bp->b_flags, (B_DELWRI | B_LOCKED | B_AGE | B_ASYNC | B_NOCACHE));
1941 /*
1942 * Determine which queue the buffer should be on, then put it there.
1943 */
1c79356b
A
1944 if (bp->b_bufsize <= 0)
1945 whichq = BQ_EMPTY; /* no data */
9bccf70c
A
1946 else if (ISSET(bp->b_flags, B_META))
1947 whichq = BQ_META; /* meta-data */
1c79356b
A
1948 else
1949 whichq = BQ_AGE; /* invalid data */
1c79356b 1950 bufq = &bufqueues[whichq];
91447636
A
1951
1952 lck_mtx_lock(buf_mtxp);
1953
1c79356b
A
1954 binsheadfree(bp, bufq, whichq);
1955 } else {
1956 /*
1957 * It has valid data. Put it on the end of the appropriate
1958 * queue, so that it'll stick around for as long as possible.
1959 */
1960 if (ISSET(bp->b_flags, B_LOCKED))
1961 whichq = BQ_LOCKED; /* locked in core */
1962 else if (ISSET(bp->b_flags, B_META))
1963 whichq = BQ_META; /* meta-data */
1964 else if (ISSET(bp->b_flags, B_AGE))
1965 whichq = BQ_AGE; /* stale but valid data */
1966 else
1967 whichq = BQ_LRU; /* valid data */
1c79356b 1968 bufq = &bufqueues[whichq];
91447636
A
1969
1970 CLR(bp->b_flags, (B_AGE | B_ASYNC | B_NOCACHE));
1971
1972 lck_mtx_lock(buf_mtxp);
1973
1c79356b
A
1974 binstailfree(bp, bufq, whichq);
1975 }
91447636
A
1976 if (needbuffer) {
1977 /*
1978 * needbuffer is a global
1979 * we're currently using buf_mtxp to protect it
1980 * delay doing the actual wakeup until after
1981 * we drop buf_mtxp
1982 */
1983 needbuffer = 0;
1984 need_wakeup = 1;
1985 }
1986 if (ISSET(bp->b_lflags, BL_WANTED)) {
1987 /*
1988 * delay the actual wakeup until after we
1989 * clear BL_BUSY and we've dropped buf_mtxp
1990 */
1991 need_bp_wakeup = 1;
1992 }
1993 /*
1994 * Unlock the buffer.
1995 */
1996 CLR(bp->b_lflags, (BL_BUSY | BL_WANTED));
1c79356b 1997
91447636 1998 lck_mtx_unlock(buf_mtxp);
1c79356b 1999
91447636
A
2000 if (need_wakeup) {
2001 /*
2002 * Wake up any processes waiting for any buffer to become free.
2003 */
2004 wakeup(&needbuffer);
2005 }
2006 if (need_bp_wakeup) {
2007 /*
2008 * Wake up any proceeses waiting for _this_ buffer to become free.
2009 */
2010 wakeup(bp);
2011 }
1c79356b 2012 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 388)) | DBG_FUNC_END,
91447636 2013 (int)bp, (int)bp->b_datap, bp->b_flags, 0, 0);
1c79356b
A
2014}
2015
2016/*
2017 * Determine if a block is in the cache.
2018 * Just look on what would be its hash chain. If it's there, return
2019 * a pointer to it, unless it's marked invalid. If it's marked invalid,
2020 * we normally don't return the buffer, unless the caller explicitly
2021 * wants us to.
2022 */
91447636
A
2023static boolean_t
2024incore(vnode_t vp, daddr64_t blkno)
2025{
2026 boolean_t retval;
2027
2028 lck_mtx_lock(buf_mtxp);
2029
2030 if (incore_locked(vp, blkno))
2031 retval = TRUE;
2032 else
2033 retval = FALSE;
2034 lck_mtx_unlock(buf_mtxp);
2035
2036 return (retval);
2037}
2038
2039
2040static buf_t
2041incore_locked(vnode_t vp, daddr64_t blkno)
1c79356b
A
2042{
2043 struct buf *bp;
1c79356b
A
2044
2045 bp = BUFHASH(vp, blkno)->lh_first;
2046
2047 /* Search hash chain */
9bccf70c 2048 for (; bp != NULL; bp = bp->b_hash.le_next) {
1c79356b 2049 if (bp->b_lblkno == blkno && bp->b_vp == vp &&
91447636 2050 !ISSET(bp->b_flags, B_INVAL)) {
1c79356b 2051 return (bp);
91447636 2052 }
1c79356b 2053 }
1c79356b
A
2054 return (0);
2055}
2056
fa4905b1
A
2057
2058/* XXX FIXME -- Update the comment to reflect the UBC changes (please) -- */
1c79356b
A
2059/*
2060 * Get a block of requested size that is associated with
2061 * a given vnode and block offset. If it is found in the
2062 * block cache, mark it as having been found, make it busy
2063 * and return it. Otherwise, return an empty block of the
2064 * correct size. It is up to the caller to insure that the
2065 * cached blocks be of the correct size.
2066 */
91447636
A
2067buf_t
2068buf_getblk(vnode_t vp, daddr64_t blkno, int size, int slpflag, int slptimeo, int operation)
1c79356b 2069{
91447636
A
2070 buf_t bp;
2071 int err;
1c79356b
A
2072 upl_t upl;
2073 upl_page_info_t *pl;
1c79356b 2074 kern_return_t kret;
91447636
A
2075 int ret_only_valid;
2076 struct timespec ts;
2077 int upl_flags;
1c79356b 2078
1c79356b 2079 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 386)) | DBG_FUNC_START,
91447636 2080 (int)(blkno * PAGE_SIZE), size, operation, 0, 0);
1c79356b 2081
91447636
A
2082 ret_only_valid = operation & BLK_ONLYVALID;
2083 operation &= ~BLK_ONLYVALID;
2084start:
2085 lck_mtx_lock(buf_mtxp);
2086start_locked:
2087 if ((bp = incore_locked(vp, blkno))) {
2088 /*
2089 * Found in the Buffer Cache
2090 */
2091 if (ISSET(bp->b_lflags, BL_BUSY)) {
2092 /*
2093 * but is busy
2094 */
1c79356b
A
2095 switch (operation) {
2096 case BLK_READ:
2097 case BLK_WRITE:
2098 case BLK_META:
91447636 2099 SET(bp->b_lflags, BL_WANTED);
1c79356b 2100 bufstats.bufs_busyincore++;
91447636
A
2101
2102 /*
2103 * don't retake the mutex after being awakened...
2104 * the time out is in msecs
2105 */
2106 ts.tv_sec = (slptimeo/1000);
2107 ts.tv_nsec = (slptimeo % 1000) * 10 * NSEC_PER_USEC * 1000;
2108
2109 err = msleep(bp, buf_mtxp, slpflag | PDROP | (PRIBIO + 1), "buf_getblk", &ts);
2110
1c79356b
A
2111 /*
2112 * Callers who call with PCATCH or timeout are
2113 * willing to deal with the NULL pointer
2114 */
91447636 2115 if (err && ((slpflag & PCATCH) || ((err == EWOULDBLOCK) && slptimeo)))
1c79356b
A
2116 return (NULL);
2117 goto start;
2118 /*NOTREACHED*/
2119 break;
2120
1c79356b 2121 default:
91447636
A
2122 /*
2123 * unknown operation requested
2124 */
2125 panic("getblk: paging or unknown operation for incore busy buffer - %x\n", operation);
1c79356b
A
2126 /*NOTREACHED*/
2127 break;
2128 }
2129 } else {
91447636
A
2130 /*
2131 * buffer in core and not busy
2132 */
2133 if ( (bp->b_upl) )
2134 panic("buffer has UPL, but not marked BUSY: %x", bp);
2135 SET(bp->b_lflags, BL_BUSY);
2136 SET(bp->b_flags, B_CACHE);
2137#ifdef JOE_DEBUG
2138 bp->b_owner = current_thread();
2139 bp->b_tag = 1;
2140#endif
2141 bremfree_locked(bp);
1c79356b 2142 bufstats.bufs_incore++;
91447636
A
2143
2144 lck_mtx_unlock(buf_mtxp);
1c79356b 2145
91447636
A
2146 if ( !ret_only_valid)
2147 allocbuf(bp, size);
1c79356b 2148
91447636 2149 upl_flags = 0;
1c79356b 2150 switch (operation) {
1c79356b 2151 case BLK_WRITE:
91447636
A
2152 /*
2153 * "write" operation: let the UPL subsystem
2154 * know that we intend to modify the buffer
2155 * cache pages we're gathering.
2156 */
2157 upl_flags |= UPL_WILL_MODIFY;
2158 case BLK_READ:
2159 upl_flags |= UPL_PRECIOUS;
2160 if (UBCINFOEXISTS(bp->b_vp) && bp->b_bufsize) {
0b4e3aa0 2161 kret = ubc_create_upl(vp,
91447636
A
2162 ubc_blktooff(vp, bp->b_lblkno),
2163 bp->b_bufsize,
2164 &upl,
2165 &pl,
2166 upl_flags);
1c79356b 2167 if (kret != KERN_SUCCESS)
91447636 2168 panic("Failed to create UPL");
1c79356b 2169
91447636 2170 bp->b_upl = upl;
1c79356b 2171
91447636
A
2172 if (upl_valid_page(pl, 0)) {
2173 if (upl_dirty_page(pl, 0))
2174 SET(bp->b_flags, B_WASDIRTY);
2175 else
2176 CLR(bp->b_flags, B_WASDIRTY);
2177 } else
2178 CLR(bp->b_flags, (B_DONE | B_CACHE | B_WASDIRTY | B_DELWRI));
1c79356b 2179
91447636 2180 kret = ubc_upl_map(upl, (vm_address_t *)&(bp->b_datap));
1c79356b 2181
9bccf70c 2182 if (kret != KERN_SUCCESS)
91447636 2183 panic("getblk: ubc_upl_map() failed with (%d)", kret);
1c79356b
A
2184 }
2185 break;
2186
2187 case BLK_META:
2188 /*
2189 * VM is not involved in IO for the meta data
2190 * buffer already has valid data
2191 */
1c79356b
A
2192 break;
2193
2194 default:
91447636 2195 panic("getblk: paging or unknown operation for incore buffer- %d\n", operation);
1c79356b
A
2196 /*NOTREACHED*/
2197 break;
2198 }
2199 }
2200 } else { /* not incore() */
2201 int queue = BQ_EMPTY; /* Start with no preference */
1c79356b 2202
91447636
A
2203 if (ret_only_valid) {
2204 lck_mtx_unlock(buf_mtxp);
2205 return (NULL);
1c79356b 2206 }
91447636
A
2207
2208 if ((UBCINVALID(vp)) || !(UBCINFOEXISTS(vp)))
2209 operation = BLK_META;
2210
1c79356b 2211 if ((bp = getnewbuf(slpflag, slptimeo, &queue)) == NULL)
91447636
A
2212 goto start_locked;
2213
2214 /*
2215 * getnewbuf may block for a number of different reasons...
2216 * if it does, it's then possible for someone else to
2217 * create a buffer for the same block and insert it into
2218 * the hash... if we see it incore at this point we dump
2219 * the buffer we were working on and start over
2220 */
2221 if (incore_locked(vp, blkno)) {
0b4e3aa0
A
2222 SET(bp->b_flags, B_INVAL);
2223 binshash(bp, &invalhash);
91447636
A
2224
2225 lck_mtx_unlock(buf_mtxp);
2226
2227 buf_brelse(bp);
0b4e3aa0
A
2228 goto start;
2229 }
b4c24cb9
A
2230 /*
2231 * NOTE: YOU CAN NOT BLOCK UNTIL binshash() HAS BEEN
2232 * CALLED! BE CAREFUL.
2233 */
0b4e3aa0 2234
1c79356b 2235 /*
91447636 2236 * mark the buffer as B_META if indicated
1c79356b 2237 * so that when buffer is released it will goto META queue
1c79356b 2238 */
91447636
A
2239 if (operation == BLK_META)
2240 SET(bp->b_flags, B_META);
9bccf70c
A
2241
2242 bp->b_blkno = bp->b_lblkno = blkno;
2243 bp->b_vp = vp;
2244
0b4e3aa0
A
2245 /*
2246 * Insert in the hash so that incore() can find it
2247 */
2248 binshash(bp, BUFHASH(vp, blkno));
2249
91447636
A
2250 lck_mtx_unlock(buf_mtxp);
2251
9bccf70c 2252 bgetvp(vp, bp);
9bccf70c 2253
1c79356b
A
2254 allocbuf(bp, size);
2255
91447636 2256 upl_flags = 0;
1c79356b
A
2257 switch (operation) {
2258 case BLK_META:
91447636
A
2259 /*
2260 * buffer data is invalid...
2261 *
2262 * I don't want to have to retake buf_mtxp,
2263 * so the miss and vmhits counters are done
2264 * with Atomic updates... all other counters
2265 * in bufstats are protected with either
2266 * buf_mtxp or iobuffer_mtxp
2267 */
2268 OSAddAtomic(1, &bufstats.bufs_miss);
1c79356b
A
2269 break;
2270
1c79356b 2271 case BLK_WRITE:
91447636
A
2272 /*
2273 * "write" operation: let the UPL subsystem know
2274 * that we intend to modify the buffer cache pages
2275 * we're gathering.
2276 */
2277 upl_flags |= UPL_WILL_MODIFY;
2278 case BLK_READ:
2279 { off_t f_offset;
2280 size_t contig_bytes;
2281 int bmap_flags;
1c79356b 2282
91447636
A
2283 if ( (bp->b_upl) )
2284 panic("bp already has UPL: %x",bp);
1c79356b 2285
91447636
A
2286 f_offset = ubc_blktooff(vp, blkno);
2287
2288 upl_flags |= UPL_PRECIOUS;
0b4e3aa0 2289 kret = ubc_create_upl(vp,
91447636
A
2290 f_offset,
2291 bp->b_bufsize,
2292 &upl,
2293 &pl,
2294 upl_flags);
1c79356b 2295
91447636
A
2296 if (kret != KERN_SUCCESS)
2297 panic("Failed to create UPL");
2298#ifdef UPL_DEBUG
1c79356b 2299 upl_ubc_alias_set(upl, bp, 4);
91447636
A
2300#endif /* UPL_DEBUG */
2301 bp->b_upl = upl;
1c79356b
A
2302
2303 if (upl_valid_page(pl, 0)) {
1c79356b 2304
91447636
A
2305 if (operation == BLK_READ)
2306 bmap_flags = VNODE_READ;
2307 else
2308 bmap_flags = VNODE_WRITE;
1c79356b 2309
91447636 2310 SET(bp->b_flags, B_CACHE | B_DONE);
1c79356b 2311
91447636 2312 OSAddAtomic(1, &bufstats.bufs_vmhits);
1c79356b 2313
91447636
A
2314 bp->b_validoff = 0;
2315 bp->b_dirtyoff = 0;
1c79356b 2316
91447636
A
2317 if (upl_dirty_page(pl, 0)) {
2318 /* page is dirty */
2319 SET(bp->b_flags, B_WASDIRTY);
1c79356b 2320
91447636
A
2321 bp->b_validend = bp->b_bcount;
2322 bp->b_dirtyend = bp->b_bcount;
1c79356b 2323 } else {
91447636
A
2324 /* page is clean */
2325 bp->b_validend = bp->b_bcount;
2326 bp->b_dirtyend = 0;
1c79356b 2327 }
91447636
A
2328 /*
2329 * try to recreate the physical block number associated with
2330 * this buffer...
2331 */
2332 if (VNOP_BLOCKMAP(vp, f_offset, bp->b_bcount, &bp->b_blkno, &contig_bytes, NULL, bmap_flags, NULL))
2333 panic("getblk: VNOP_BLOCKMAP failed");
2334 /*
2335 * if the extent represented by this buffer
2336 * is not completely physically contiguous on
2337 * disk, than we can't cache the physical mapping
2338 * in the buffer header
2339 */
2340 if ((long)contig_bytes < bp->b_bcount)
2341 bp->b_blkno = bp->b_lblkno;
1c79356b 2342 } else {
91447636 2343 OSAddAtomic(1, &bufstats.bufs_miss);
1c79356b 2344 }
91447636 2345 kret = ubc_upl_map(upl, (vm_address_t *)&(bp->b_datap));
1c79356b 2346
91447636
A
2347 if (kret != KERN_SUCCESS)
2348 panic("getblk: ubc_upl_map() failed with (%d)", kret);
1c79356b 2349 break;
91447636 2350 }
1c79356b 2351 default:
91447636 2352 panic("getblk: paging or unknown operation - %x", operation);
1c79356b
A
2353 /*NOTREACHED*/
2354 break;
2355 }
2356 }
1c79356b 2357 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 386)) | DBG_FUNC_END,
91447636
A
2358 (int)bp, (int)bp->b_datap, bp->b_flags, 3, 0);
2359
2360#ifdef JOE_DEBUG
2361 bp->b_stackgetblk[0] = __builtin_return_address(0);
2362 bp->b_stackgetblk[1] = __builtin_return_address(1);
2363 bp->b_stackgetblk[2] = __builtin_return_address(2);
2364 bp->b_stackgetblk[3] = __builtin_return_address(3);
2365 bp->b_stackgetblk[4] = __builtin_return_address(4);
2366 bp->b_stackgetblk[5] = __builtin_return_address(5);
2367#endif
1c79356b
A
2368 return (bp);
2369}
2370
2371/*
2372 * Get an empty, disassociated buffer of given size.
2373 */
91447636
A
2374buf_t
2375buf_geteblk(size)
1c79356b
A
2376 int size;
2377{
91447636
A
2378 buf_t bp;
2379 int queue = BQ_EMPTY;
2380
2381 lck_mtx_lock(buf_mtxp);
1c79356b
A
2382
2383 while ((bp = getnewbuf(0, 0, &queue)) == 0)
2384 ;
1c79356b 2385 SET(bp->b_flags, (B_META|B_INVAL));
1c79356b
A
2386
2387#if DIAGNOSTIC
2388 assert(queue == BQ_EMPTY);
2389#endif /* DIAGNOSTIC */
2390 /* XXX need to implement logic to deal with other queues */
2391
1c79356b 2392 binshash(bp, &invalhash);
1c79356b
A
2393 bufstats.bufs_eblk++;
2394
91447636
A
2395 lck_mtx_unlock(buf_mtxp);
2396
2397 allocbuf(bp, size);
2398
1c79356b
A
2399 return (bp);
2400}
2401
1c79356b
A
2402/*
2403 * Zones for the meta data buffers
2404 */
2405
2406#define MINMETA 512
2407#define MAXMETA 4096
2408
2409struct meta_zone_entry {
2410 zone_t mz_zone;
2411 vm_size_t mz_size;
2412 vm_size_t mz_max;
2413 char *mz_name;
2414};
2415
2416struct meta_zone_entry meta_zones[] = {
2417 {NULL, (MINMETA * 1), 128 * (MINMETA * 1), "buf.512" },
2418 {NULL, (MINMETA * 2), 64 * (MINMETA * 2), "buf.1024" },
1c79356b 2419 {NULL, (MINMETA * 4), 16 * (MINMETA * 4), "buf.2048" },
1c79356b
A
2420 {NULL, (MINMETA * 8), 512 * (MINMETA * 8), "buf.4096" },
2421 {NULL, 0, 0, "" } /* End */
2422};
765c9de3 2423
1c79356b
A
2424/*
2425 * Initialize the meta data zones
2426 */
2427static void
2428bufzoneinit(void)
2429{
2430 int i;
2431
2432 for (i = 0; meta_zones[i].mz_size != 0; i++) {
2433 meta_zones[i].mz_zone =
2434 zinit(meta_zones[i].mz_size,
2435 meta_zones[i].mz_max,
2436 PAGE_SIZE,
2437 meta_zones[i].mz_name);
2438 }
765c9de3 2439 buf_hdr_zone = zinit(sizeof(struct buf), 32, PAGE_SIZE, "buf headers");
1c79356b
A
2440}
2441
9bccf70c 2442static __inline__ zone_t
1c79356b
A
2443getbufzone(size_t size)
2444{
2445 int i;
2446
9bccf70c 2447 if ((size % 512) || (size < MINMETA) || (size > MAXMETA))
1c79356b
A
2448 panic("getbufzone: incorect size = %d", size);
2449
91447636 2450 for (i = 0; meta_zones[i].mz_size != 0; i++) {
9bccf70c
A
2451 if (meta_zones[i].mz_size >= size)
2452 break;
2453 }
2454
1c79356b
A
2455 return (meta_zones[i].mz_zone);
2456}
1c79356b
A
2457
2458/*
2459 * With UBC, there is no need to expand / shrink the file data
2460 * buffer. The VM uses the same pages, hence no waste.
2461 * All the file data buffers can have one size.
2462 * In fact expand / shrink would be an expensive operation.
2463 *
2464 * Only exception to this is meta-data buffers. Most of the
2465 * meta data operations are smaller than PAGE_SIZE. Having the
2466 * meta-data buffers grow and shrink as needed, optimizes use
2467 * of the kernel wired memory.
2468 */
2469
2470int
91447636 2471allocbuf(buf_t bp, int size)
1c79356b
A
2472{
2473 vm_size_t desired_size;
2474
2475 desired_size = roundup(size, CLBYTES);
2476
91447636 2477 if (desired_size < PAGE_SIZE)
1c79356b
A
2478 desired_size = PAGE_SIZE;
2479 if (desired_size > MAXBSIZE)
2480 panic("allocbuf: buffer larger than MAXBSIZE requested");
2481
1c79356b 2482 if (ISSET(bp->b_flags, B_META)) {
1c79356b 2483 zone_t zprev, z;
91447636
A
2484 int nsize = roundup(size, MINMETA);
2485
2486 if (bp->b_datap) {
2487 vm_offset_t elem = (vm_offset_t)bp->b_datap;
2488
2489 if (ISSET(bp->b_flags, B_ZALLOC)) {
2490 if (bp->b_bufsize < nsize) {
2491 /* reallocate to a bigger size */
2492
2493 zprev = getbufzone(bp->b_bufsize);
2494 if (nsize <= MAXMETA) {
2495 desired_size = nsize;
2496 z = getbufzone(nsize);
2497 bp->b_datap = (uintptr_t)zalloc(z);
1c79356b 2498 } else {
91447636 2499 bp->b_datap = (uintptr_t)NULL;
0c530ab8 2500 kmem_alloc_wired(kernel_map, (vm_offset_t *)&bp->b_datap, desired_size);
91447636 2501 CLR(bp->b_flags, B_ZALLOC);
1c79356b 2502 }
91447636
A
2503 bcopy((void *)elem, (caddr_t)bp->b_datap, bp->b_bufsize);
2504 zfree(zprev, (void *)elem);
2505 } else {
2506 desired_size = bp->b_bufsize;
2507 }
2508
2509 } else {
2510 if ((vm_size_t)bp->b_bufsize < desired_size) {
1c79356b 2511 /* reallocate to a bigger size */
91447636 2512 bp->b_datap = (uintptr_t)NULL;
0c530ab8 2513 kmem_alloc_wired(kernel_map, (vm_offset_t *)&bp->b_datap, desired_size);
91447636 2514 bcopy((const void *)elem, (caddr_t)bp->b_datap, bp->b_bufsize);
1c79356b
A
2515 kmem_free(kernel_map, elem, bp->b_bufsize);
2516 } else {
2517 desired_size = bp->b_bufsize;
2518 }
91447636 2519 }
1c79356b
A
2520 } else {
2521 /* new allocation */
2522 if (nsize <= MAXMETA) {
2523 desired_size = nsize;
2524 z = getbufzone(nsize);
91447636 2525 bp->b_datap = (uintptr_t)zalloc(z);
1c79356b 2526 SET(bp->b_flags, B_ZALLOC);
91447636 2527 } else
0c530ab8 2528 kmem_alloc_wired(kernel_map, (vm_offset_t *)&bp->b_datap, desired_size);
1c79356b
A
2529 }
2530 }
9bccf70c
A
2531 bp->b_bufsize = desired_size;
2532 bp->b_bcount = size;
91447636 2533
9bccf70c 2534 return (0);
1c79356b
A
2535}
2536
2537/*
2538 * Get a new buffer from one of the free lists.
2539 *
2540 * Request for a queue is passes in. The queue from which the buffer was taken
2541 * from is returned. Out of range queue requests get BQ_EMPTY. Request for
2542 * BQUEUE means no preference. Use heuristics in that case.
2543 * Heuristics is as follows:
2544 * Try BQ_AGE, BQ_LRU, BQ_EMPTY, BQ_META in that order.
2545 * If none available block till one is made available.
2546 * If buffers available on both BQ_AGE and BQ_LRU, check the timestamps.
2547 * Pick the most stale buffer.
2548 * If found buffer was marked delayed write, start the async. write
2549 * and restart the search.
2550 * Initialize the fields and disassociate the buffer from the vnode.
2551 * Remove the buffer from the hash. Return the buffer and the queue
2552 * on which it was found.
91447636
A
2553 *
2554 * buf_mtxp is held upon entry
2555 * returns with buf_mtxp locked
1c79356b
A
2556 */
2557
91447636
A
2558static buf_t
2559getnewbuf(int slpflag, int slptimeo, int * queue)
1c79356b 2560{
91447636
A
2561 buf_t bp;
2562 buf_t lru_bp;
2563 buf_t age_bp;
2564 buf_t meta_bp;
2565 int age_time, lru_time, bp_time, meta_time;
2566 int req = *queue; /* save it for restarts */
2567 struct timespec ts;
1c79356b
A
2568
2569start:
91447636
A
2570 /*
2571 * invalid request gets empty queue
2572 */
765c9de3
A
2573 if ((*queue > BQUEUES) || (*queue < 0)
2574 || (*queue == BQ_LAUNDRY) || (*queue == BQ_LOCKED))
1c79356b 2575 *queue = BQ_EMPTY;
0c530ab8
A
2576 /* need to grow number of bufs, add another one rather than recycling */
2577 if (nbuf < max_nbuf_headers) {
2578 /*
2579 * Increment count now as lock
2580 * is dropped for allocation.
2581 * That avoids over commits
2582 */
2583 nbuf++;
2584 goto add_newbufs;
2585 }
1c79356b 2586
91447636
A
2587 /*
2588 * (*queue == BQUEUES) means no preference
2589 */
1c79356b
A
2590 if (*queue != BQUEUES) {
2591 /* Try for the requested queue first */
2592 bp = bufqueues[*queue].tqh_first;
2593 if (bp)
2594 goto found;
2595 }
2596
2597 /* Unable to use requested queue */
2598 age_bp = bufqueues[BQ_AGE].tqh_first;
2599 lru_bp = bufqueues[BQ_LRU].tqh_first;
2600 meta_bp = bufqueues[BQ_META].tqh_first;
2601
9bccf70c
A
2602 if (!age_bp && !lru_bp && !meta_bp) {
2603 /*
2604 * Unavailble on AGE or LRU or META queues
2605 * Try the empty list first
2606 */
1c79356b
A
2607 bp = bufqueues[BQ_EMPTY].tqh_first;
2608 if (bp) {
2609 *queue = BQ_EMPTY;
2610 goto found;
2611 }
0c530ab8
A
2612 /*
2613 * We have seen is this is hard to trigger.
2614 * This is an overcommit of nbufs but needed
2615 * in some scenarios with diskiamges
2616 */
2617
2618add_newbufs:
91447636 2619 lck_mtx_unlock(buf_mtxp);
765c9de3 2620
91447636 2621 /* Create a new temporary buffer header */
765c9de3
A
2622 bp = (struct buf *)zalloc(buf_hdr_zone);
2623
91447636
A
2624 lck_mtx_lock(buf_mtxp);
2625
765c9de3
A
2626 if (bp) {
2627 bufhdrinit(bp);
2628 BLISTNONE(bp);
2629 binshash(bp, &invalhash);
2630 SET(bp->b_flags, B_HDRALLOC);
2631 *queue = BQ_EMPTY;
2632 binsheadfree(bp, &bufqueues[BQ_EMPTY], BQ_EMPTY);
2633 buf_hdr_count++;
2634 goto found;
2635 }
0c530ab8
A
2636 /* subtract already accounted bufcount */
2637 nbuf--;
2638
91447636 2639 bufstats.bufs_sleeps++;
765c9de3 2640
1c79356b
A
2641 /* wait for a free buffer of any kind */
2642 needbuffer = 1;
91447636
A
2643 /* hz value is 100 */
2644 ts.tv_sec = (slptimeo/1000);
2645 /* the hz value is 100; which leads to 10ms */
2646 ts.tv_nsec = (slptimeo % 1000) * NSEC_PER_USEC * 1000 * 10;
2647 msleep(&needbuffer, buf_mtxp, slpflag|(PRIBIO+1), (char *)"getnewbuf", &ts);
1c79356b
A
2648 return (0);
2649 }
2650
2651 /* Buffer available either on AGE or LRU or META */
2652 bp = NULL;
2653 *queue = -1;
2654
2655 /* Buffer available either on AGE or LRU */
2656 if (!age_bp) {
2657 bp = lru_bp;
2658 *queue = BQ_LRU;
2659 } else if (!lru_bp) {
2660 bp = age_bp;
2661 *queue = BQ_AGE;
2662 } else { /* buffer available on both AGE and LRU */
91447636
A
2663 int t = buf_timestamp();
2664
2665 age_time = t - age_bp->b_timestamp;
2666 lru_time = t - lru_bp->b_timestamp;
1c79356b
A
2667 if ((age_time < 0) || (lru_time < 0)) { /* time set backwards */
2668 bp = age_bp;
2669 *queue = BQ_AGE;
2670 /*
2671 * we should probably re-timestamp eveything in the
2672 * queues at this point with the current time
2673 */
2674 } else {
2675 if ((lru_time >= lru_is_stale) && (age_time < age_is_stale)) {
2676 bp = lru_bp;
2677 *queue = BQ_LRU;
2678 } else {
2679 bp = age_bp;
2680 *queue = BQ_AGE;
2681 }
2682 }
2683 }
2684
2685 if (!bp) { /* Neither on AGE nor on LRU */
2686 bp = meta_bp;
2687 *queue = BQ_META;
2688 } else if (meta_bp) {
91447636
A
2689 int t = buf_timestamp();
2690
2691 bp_time = t - bp->b_timestamp;
2692 meta_time = t - meta_bp->b_timestamp;
1c79356b
A
2693
2694 if (!(bp_time < 0) && !(meta_time < 0)) {
2695 /* time not set backwards */
2696 int bp_is_stale;
2697 bp_is_stale = (*queue == BQ_LRU) ?
2698 lru_is_stale : age_is_stale;
2699
2700 if ((meta_time >= meta_is_stale) &&
2701 (bp_time < bp_is_stale)) {
2702 bp = meta_bp;
2703 *queue = BQ_META;
2704 }
2705 }
2706 }
1c79356b 2707found:
91447636
A
2708 if (ISSET(bp->b_flags, B_LOCKED) || ISSET(bp->b_lflags, BL_BUSY))
2709 panic("getnewbuf: bp @ 0x%x is LOCKED or BUSY! (flags 0x%x)\n", bp, bp->b_flags);
1c79356b
A
2710
2711 /* Clean it */
2712 if (bcleanbuf(bp)) {
91447636
A
2713 /*
2714 * moved to the laundry thread, buffer not ready
2715 */
1c79356b
A
2716 *queue = req;
2717 goto start;
2718 }
1c79356b
A
2719 return (bp);
2720}
9bccf70c 2721
1c79356b
A
2722
2723/*
2724 * Clean a buffer.
2725 * Returns 0 is buffer is ready to use,
91447636 2726 * Returns 1 if issued a buf_bawrite() to indicate
1c79356b 2727 * that the buffer is not ready.
91447636
A
2728 *
2729 * buf_mtxp is held upon entry
2730 * returns with buf_mtxp locked
1c79356b 2731 */
9bccf70c 2732static int
91447636 2733bcleanbuf(buf_t bp)
1c79356b 2734{
1c79356b 2735 /* Remove from the queue */
91447636 2736 bremfree_locked(bp);
1c79356b
A
2737
2738 /* Buffer is no longer on free lists. */
91447636
A
2739 SET(bp->b_lflags, BL_BUSY);
2740#ifdef JOE_DEBUG
2741 bp->b_owner = current_thread();
2742 bp->b_tag = 2;
2743#endif
765c9de3
A
2744 /*
2745 * If buffer was a delayed write, start the IO by queuing
2746 * it on the LAUNDRY queue, and return 1
2747 */
1c79356b 2748 if (ISSET(bp->b_flags, B_DELWRI)) {
765c9de3
A
2749 binstailfree(bp, &bufqueues[BQ_LAUNDRY], BQ_LAUNDRY);
2750 blaundrycnt++;
91447636
A
2751
2752 lck_mtx_unlock(buf_mtxp);
2753
765c9de3 2754 wakeup(&blaundrycnt);
9bccf70c
A
2755 /* and give it a chance to run */
2756 (void)thread_block(THREAD_CONTINUE_NULL);
91447636
A
2757
2758 lck_mtx_lock(buf_mtxp);
1c79356b
A
2759 return (1);
2760 }
91447636
A
2761 bremhash(bp);
2762
2763 lck_mtx_unlock(buf_mtxp);
2764
2765 BLISTNONE(bp);
2766 /*
2767 * disassociate us from our vnode, if we had one...
2768 */
2769 if (bp->b_vp)
2770 brelvp(bp);
2771
2772 if (ISSET(bp->b_flags, B_META)) {
2773 vm_offset_t elem;
2774
2775 elem = (vm_offset_t)bp->b_datap;
2776 bp->b_datap = (uintptr_t)0xdeadbeef;
2777
2778 if (ISSET(bp->b_flags, B_ZALLOC)) {
2779 zone_t z;
2780
2781 z = getbufzone(bp->b_bufsize);
2782 zfree(z, (void *)elem);
2783 } else
2784 kmem_free(kernel_map, elem, bp->b_bufsize);
2785 }
2786
2787 trace(TR_BRELSE, pack(bp->b_vp, bp->b_bufsize), bp->b_lblkno);
2788
2789 /* clear out various other fields */
2790 bp->b_bufsize = 0;
2791 bp->b_datap = (uintptr_t)NULL;
2792 bp->b_upl = (void *)NULL;
2793 /*
2794 * preserve the state of whether this buffer
2795 * was allocated on the fly or not...
2796 * the only other flag that should be set at
2797 * this point is BL_BUSY...
2798 */
2799#ifdef JOE_DEBUG
2800 bp->b_owner = current_thread();
2801 bp->b_tag = 3;
2802#endif
2803 bp->b_lflags = BL_BUSY;
2804 bp->b_flags = (bp->b_flags & B_HDRALLOC);
2805 bp->b_dev = NODEV;
2806 bp->b_blkno = bp->b_lblkno = 0;
2807 bp->b_iodone = NULL;
2808 bp->b_error = 0;
2809 bp->b_resid = 0;
2810 bp->b_bcount = 0;
2811 bp->b_dirtyoff = bp->b_dirtyend = 0;
2812 bp->b_validoff = bp->b_validend = 0;
2813
2814 /* nuke any credentials we were holding */
0c530ab8
A
2815 if (IS_VALID_CRED(bp->b_rcred)) {
2816 kauth_cred_unref(&bp->b_rcred);
91447636 2817 }
0c530ab8
A
2818 if (IS_VALID_CRED(bp->b_wcred)) {
2819 kauth_cred_unref(&bp->b_wcred);
91447636
A
2820 }
2821 lck_mtx_lock(buf_mtxp);
2822
2823 return (0);
2824}
2825
2826
2827
2828errno_t
2829buf_invalblkno(vnode_t vp, daddr64_t lblkno, int flags)
2830{
2831 buf_t bp;
2832 errno_t error;
2833
2834 lck_mtx_lock(buf_mtxp);
2835relook:
2836 if ((bp = incore_locked(vp, lblkno)) == (struct buf *)0) {
2837 lck_mtx_unlock(buf_mtxp);
2838 return (0);
2839 }
2840 if (ISSET(bp->b_lflags, BL_BUSY)) {
2841 if ( !ISSET(flags, BUF_WAIT)) {
2842 lck_mtx_unlock(buf_mtxp);
2843 return (EBUSY);
2844 }
2845 SET(bp->b_lflags, BL_WANTED);
2846
2847 error = msleep((caddr_t)bp, buf_mtxp, (PRIBIO + 1), (char *)"buf_invalblkno", 0);
2848
2849 if (error)
2850 return (error);
2851 goto relook;
2852 }
2853 bremfree_locked(bp);
2854 SET(bp->b_lflags, BL_BUSY);
2855 SET(bp->b_flags, B_INVAL);
2856#ifdef JOE_DEBUG
2857 bp->b_owner = current_thread();
2858 bp->b_tag = 4;
2859#endif
2860 lck_mtx_unlock(buf_mtxp);
2861 buf_brelse(bp);
2862
2863 return (0);
2864}
2865
2866
2867void
2868buf_drop(buf_t bp)
2869{
2870 int need_wakeup = 0;
2871
2872 lck_mtx_lock(buf_mtxp);
2873
2874 if (ISSET(bp->b_lflags, BL_WANTED)) {
2875 /*
2876 * delay the actual wakeup until after we
2877 * clear BL_BUSY and we've dropped buf_mtxp
2878 */
2879 need_wakeup = 1;
2880 }
2881 /*
2882 * Unlock the buffer.
2883 */
2884 CLR(bp->b_lflags, (BL_BUSY | BL_WANTED));
1c79356b 2885
91447636 2886 lck_mtx_unlock(buf_mtxp);
1c79356b 2887
91447636
A
2888 if (need_wakeup) {
2889 /*
2890 * Wake up any proceeses waiting for _this_ buffer to become free.
2891 */
2892 wakeup(bp);
2893 }
2894}
1c79356b 2895
1c79356b 2896
91447636
A
2897errno_t
2898buf_acquire(buf_t bp, int flags, int slpflag, int slptimeo) {
2899 errno_t error;
1c79356b 2900
91447636 2901 lck_mtx_lock(buf_mtxp);
1c79356b 2902
91447636 2903 error = buf_acquire_locked(bp, flags, slpflag, slptimeo);
1c79356b 2904
91447636 2905 lck_mtx_unlock(buf_mtxp);
1c79356b 2906
91447636
A
2907 return (error);
2908}
1c79356b 2909
91447636
A
2910
2911static errno_t
2912buf_acquire_locked(buf_t bp, int flags, int slpflag, int slptimeo)
2913{
2914 errno_t error;
2915 struct timespec ts;
2916
2917 if (ISSET(bp->b_flags, B_LOCKED)) {
2918 if ((flags & BAC_SKIP_LOCKED))
2919 return (EDEADLK);
2920 } else {
2921 if ((flags & BAC_SKIP_NONLOCKED))
2922 return (EDEADLK);
1c79356b 2923 }
91447636
A
2924 if (ISSET(bp->b_lflags, BL_BUSY)) {
2925 /*
2926 * since the mutex_lock may block, the buffer
2927 * may become BUSY, so we need to
2928 * recheck for a NOWAIT request
2929 */
2930 if (flags & BAC_NOWAIT)
2931 return (EBUSY);
2932 SET(bp->b_lflags, BL_WANTED);
2933
2934 /* the hz value is 100; which leads to 10ms */
2935 ts.tv_sec = (slptimeo/100);
2936 ts.tv_nsec = (slptimeo % 100) * 10 * NSEC_PER_USEC * 1000;
2937 error = msleep((caddr_t)bp, buf_mtxp, slpflag | (PRIBIO + 1), (char *)"buf_acquire", &ts);
2938
2939 if (error)
2940 return (error);
2941 return (EAGAIN);
1c79356b 2942 }
91447636
A
2943 if (flags & BAC_REMOVE)
2944 bremfree_locked(bp);
2945 SET(bp->b_lflags, BL_BUSY);
2946#ifdef JOE_DEBUG
2947 bp->b_owner = current_thread();
2948 bp->b_tag = 5;
2949#endif
1c79356b
A
2950 return (0);
2951}
2952
2953
2954/*
2955 * Wait for operations on the buffer to complete.
2956 * When they do, extract and return the I/O's error value.
2957 */
91447636
A
2958errno_t
2959buf_biowait(buf_t bp)
1c79356b 2960{
91447636 2961 lck_mtx_lock(buf_mtxp);
1c79356b 2962
1c79356b 2963 while (!ISSET(bp->b_flags, B_DONE))
91447636
A
2964 (void) msleep(bp, buf_mtxp, (PRIBIO+1), (char *)"buf_biowait", 0);
2965
2966 lck_mtx_unlock(buf_mtxp);
1c79356b
A
2967
2968 /* check for interruption of I/O (e.g. via NFS), then errors. */
2969 if (ISSET(bp->b_flags, B_EINTR)) {
2970 CLR(bp->b_flags, B_EINTR);
2971 return (EINTR);
2972 } else if (ISSET(bp->b_flags, B_ERROR))
2973 return (bp->b_error ? bp->b_error : EIO);
2974 else
2975 return (0);
2976}
2977
2978/*
2979 * Mark I/O complete on a buffer.
2980 *
2981 * If a callback has been requested, e.g. the pageout
2982 * daemon, do so. Otherwise, awaken waiting processes.
2983 *
2984 * [ Leffler, et al., says on p.247:
2985 * "This routine wakes up the blocked process, frees the buffer
2986 * for an asynchronous write, or, for a request by the pagedaemon
2987 * process, invokes a procedure specified in the buffer structure" ]
2988 *
2989 * In real life, the pagedaemon (or other system processes) wants
91447636 2990 * to do async stuff to, and doesn't want the buffer buf_brelse()'d.
1c79356b
A
2991 * (for swap pager, that puts swap buffers on the free lists (!!!),
2992 * for the vn device, that puts malloc'd buffers on the free lists!)
2993 */
91447636
A
2994extern struct timeval priority_IO_timestamp_for_root;
2995extern int hard_throttle_on_root;
2996
1c79356b 2997void
91447636 2998buf_biodone(buf_t bp)
1c79356b 2999{
1c79356b 3000 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 387)) | DBG_FUNC_START,
91447636 3001 (int)bp, (int)bp->b_datap, bp->b_flags, 0, 0);
1c79356b
A
3002
3003 if (ISSET(bp->b_flags, B_DONE))
3004 panic("biodone already");
1c79356b 3005
9bccf70c 3006 if (kdebug_enable) {
91447636 3007 int code = DKIO_DONE;
9bccf70c 3008
91447636
A
3009 if (bp->b_flags & B_READ)
3010 code |= DKIO_READ;
3011 if (bp->b_flags & B_ASYNC)
3012 code |= DKIO_ASYNC;
9bccf70c 3013
91447636
A
3014 if (bp->b_flags & B_META)
3015 code |= DKIO_META;
3016 else if (bp->b_flags & B_PAGEIO)
3017 code |= DKIO_PAGING;
9bccf70c 3018
91447636
A
3019 KERNEL_DEBUG_CONSTANT(FSDBG_CODE(DBG_DKRW, code) | DBG_FUNC_NONE,
3020 (unsigned int)bp, (unsigned int)bp->b_vp,
3021 bp->b_resid, bp->b_error, 0);
9bccf70c 3022 }
91447636
A
3023 if ((bp->b_vp != NULLVP) &&
3024 ((bp->b_flags & (B_PAGEIO | B_READ)) == (B_PAGEIO | B_READ)) &&
3025 (bp->b_vp->v_mount->mnt_kern_flag & MNTK_ROOTDEV)) {
3026 microuptime(&priority_IO_timestamp_for_root);
55e303ae
A
3027 hard_throttle_on_root = 0;
3028 }
91447636
A
3029 /*
3030 * I/O was done, so don't believe
3031 * the DIRTY state from VM anymore
3032 */
3033 CLR(bp->b_flags, B_WASDIRTY);
b4c24cb9 3034
91447636
A
3035 if (!ISSET(bp->b_flags, B_READ) && !ISSET(bp->b_flags, B_RAW))
3036 /*
3037 * wake up any writer's blocked
3038 * on throttle or waiting for I/O
3039 * to drain
3040 */
3041 vnode_writedone(bp->b_vp);
3042
3043 if (ISSET(bp->b_flags, (B_CALL | B_FILTER))) { /* if necessary, call out */
3044 void (*iodone_func)(struct buf *, void *) = bp->b_iodone;
3045 void *arg = (void *)bp->b_transaction;
3046 int callout = ISSET(bp->b_flags, B_CALL);
3047
3048 CLR(bp->b_flags, (B_CALL | B_FILTER)); /* filters and callouts are one-shot */
b4c24cb9 3049 bp->b_iodone = NULL;
91447636 3050 bp->b_transaction = NULL;
b4c24cb9
A
3051
3052 if (iodone_func == NULL) {
3053 panic("biodone: bp @ 0x%x has NULL b_iodone!\n", bp);
3054 } else {
91447636
A
3055 if (callout)
3056 SET(bp->b_flags, B_DONE); /* note that it's done */
3057 (*iodone_func)(bp, arg);
b4c24cb9 3058 }
91447636
A
3059 if (callout)
3060 /*
3061 * assumes that the call back function takes
3062 * ownership of the bp and deals with releasing it if necessary
3063 */
3064 goto biodone_done;
3065 /*
3066 * in this case the call back function is acting
3067 * strictly as a filter... it does not take
3068 * ownership of the bp and is expecting us
3069 * to finish cleaning up... this is currently used
3070 * by the HFS journaling code
3071 */
1c79356b 3072 }
91447636
A
3073 if (ISSET(bp->b_flags, B_ASYNC)) { /* if async, release it */
3074 SET(bp->b_flags, B_DONE); /* note that it's done */
1c79356b 3075
91447636
A
3076 buf_brelse(bp);
3077 } else { /* or just wakeup the buffer */
3078 /*
3079 * by taking the mutex, we serialize
3080 * the buf owner calling buf_biowait so that we'll
3081 * only see him in one of 2 states...
3082 * state 1: B_DONE wasn't set and he's
3083 * blocked in msleep
3084 * state 2: he's blocked trying to take the
3085 * mutex before looking at B_DONE
3086 * BL_WANTED is cleared in case anyone else
3087 * is blocked waiting for the buffer... note
3088 * that we haven't cleared B_BUSY yet, so if
3089 * they do get to run, their going to re-set
3090 * BL_WANTED and go back to sleep
3091 */
3092 lck_mtx_lock(buf_mtxp);
1c79356b 3093
91447636
A
3094 CLR(bp->b_lflags, BL_WANTED);
3095 SET(bp->b_flags, B_DONE); /* note that it's done */
3096
3097 lck_mtx_unlock(buf_mtxp);
3098
3099 wakeup(bp);
3100 }
3101biodone_done:
3102 KERNEL_DEBUG((FSDBG_CODE(DBG_FSRW, 387)) | DBG_FUNC_END,
3103 (int)bp, (int)bp->b_datap, bp->b_flags, 0, 0);
1c79356b
A
3104}
3105
3106/*
3107 * Return a count of buffers on the "locked" queue.
3108 */
3109int
91447636 3110count_lock_queue(void)
1c79356b 3111{
91447636
A
3112 buf_t bp;
3113 int n = 0;
3114
3115 lck_mtx_lock(buf_mtxp);
1c79356b
A
3116
3117 for (bp = bufqueues[BQ_LOCKED].tqh_first; bp;
3118 bp = bp->b_freelist.tqe_next)
3119 n++;
91447636
A
3120 lck_mtx_unlock(buf_mtxp);
3121
1c79356b
A
3122 return (n);
3123}
3124
3125/*
3126 * Return a count of 'busy' buffers. Used at the time of shutdown.
3127 */
3128int
91447636 3129count_busy_buffers(void)
1c79356b 3130{
91447636
A
3131 buf_t bp;
3132 int nbusy = 0;
1c79356b 3133
0c530ab8
A
3134 lck_mtx_lock(buf_mtxp);
3135 for (bp = &buf[boot_nbuf]; --bp >= buf; )
91447636 3136 if (!ISSET(bp->b_flags, B_INVAL) && ISSET(bp->b_lflags, BL_BUSY))
1c79356b 3137 nbusy++;
0c530ab8
A
3138 lck_mtx_unlock(buf_mtxp);
3139
1c79356b
A
3140 return (nbusy);
3141}
3142
9bccf70c 3143#if DIAGNOSTIC
1c79356b
A
3144/*
3145 * Print out statistics on the current allocation of the buffer pool.
3146 * Can be enabled to print out on every ``sync'' by setting "syncprt"
3147 * in vfs_syscalls.c using sysctl.
3148 */
3149void
3150vfs_bufstats()
3151{
91447636
A
3152 int i, j, count;
3153 register struct buf *bp;
3154 register struct bqueues *dp;
3155 int counts[MAXBSIZE/CLBYTES+1];
3156 static char *bname[BQUEUES] =
3157 { "LOCKED", "LRU", "AGE", "EMPTY", "META", "LAUNDRY" };
3158
3159 for (dp = bufqueues, i = 0; dp < &bufqueues[BQUEUES]; dp++, i++) {
3160 count = 0;
3161 for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
3162 counts[j] = 0;
3163
3164 lck_mtx_lock(buf_mtxp);
3165
3166 for (bp = dp->tqh_first; bp; bp = bp->b_freelist.tqe_next) {
3167 counts[bp->b_bufsize/CLBYTES]++;
3168 count++;
3169 }
3170 lck_mtx_unlock(buf_mtxp);
3171
3172 printf("%s: total-%d", bname[i], count);
3173 for (j = 0; j <= MAXBSIZE/CLBYTES; j++)
3174 if (counts[j] != 0)
3175 printf(", %d-%d", j * CLBYTES, counts[j]);
3176 printf("\n");
3177 }
3178}
3179#endif /* DIAGNOSTIC */
3180
3181#define NRESERVEDIOBUFS 64
3182
3183
3184buf_t
3185alloc_io_buf(vnode_t vp, int priv)
3186{
3187 buf_t bp;
3188
3189 lck_mtx_lock(iobuffer_mtxp);
3190
3191 while (((niobuf - NRESERVEDIOBUFS < bufstats.bufs_iobufinuse) && !priv) ||
3192 (bp = iobufqueue.tqh_first) == NULL) {
3193 bufstats.bufs_iobufsleeps++;
3194
3195 need_iobuffer = 1;
3196 (void) msleep(&need_iobuffer, iobuffer_mtxp, (PRIBIO+1), (const char *)"alloc_io_buf", 0);
3197 }
3198 TAILQ_REMOVE(&iobufqueue, bp, b_freelist);
3199
3200 bufstats.bufs_iobufinuse++;
3201 if (bufstats.bufs_iobufinuse > bufstats.bufs_iobufmax)
3202 bufstats.bufs_iobufmax = bufstats.bufs_iobufinuse;
3203
3204 lck_mtx_unlock(iobuffer_mtxp);
3205
3206 /*
3207 * initialize various fields
3208 * we don't need to hold the mutex since the buffer
3209 * is now private... the vp should have a reference
3210 * on it and is not protected by this mutex in any event
3211 */
3212 bp->b_timestamp = 0;
3213 bp->b_proc = NULL;
3214
3215 bp->b_datap = 0;
3216 bp->b_flags = 0;
3217 bp->b_lflags = BL_BUSY | BL_IOBUF;
3218 bp->b_blkno = bp->b_lblkno = 0;
3219#ifdef JOE_DEBUG
3220 bp->b_owner = current_thread();
3221 bp->b_tag = 6;
3222#endif
3223 bp->b_iodone = NULL;
3224 bp->b_error = 0;
3225 bp->b_resid = 0;
3226 bp->b_bcount = 0;
3227 bp->b_bufsize = 0;
3228 bp->b_upl = NULL;
3229 bp->b_vp = vp;
3230
3231 if (vp && (vp->v_type == VBLK || vp->v_type == VCHR))
3232 bp->b_dev = vp->v_rdev;
3233 else
3234 bp->b_dev = NODEV;
3235
3236 return (bp);
3237}
3238
3239
3240void
3241free_io_buf(buf_t bp)
3242{
3243 int need_wakeup = 0;
3244
3245 /*
3246 * put buffer back on the head of the iobufqueue
3247 */
3248 bp->b_vp = NULL;
3249 bp->b_flags = B_INVAL;
3250
3251 lck_mtx_lock(iobuffer_mtxp);
3252
3253 binsheadfree(bp, &iobufqueue, -1);
3254
3255 if (need_iobuffer) {
3256 /*
3257 * Wake up any processes waiting because they need an io buffer
3258 *
3259 * do the wakeup after we drop the mutex... it's possible that the
3260 * wakeup will be superfluous if need_iobuffer gets set again and
3261 * another thread runs this path, but it's highly unlikely, doesn't
3262 * hurt, and it means we don't hold up I/O progress if the wakeup blocks
3263 * trying to grab a task related lock...
3264 */
3265 need_iobuffer = 0;
3266 need_wakeup = 1;
3267 }
3268 bufstats.bufs_iobufinuse--;
3269
3270 lck_mtx_unlock(iobuffer_mtxp);
3271
3272 if (need_wakeup)
3273 wakeup(&need_iobuffer);
3274}
3275
3276
3277
3278/*
3279 * If getnewbuf() calls bcleanbuf() on the same thread
3280 * there is a potential for stack overrun and deadlocks.
3281 * So we always handoff the work to a worker thread for completion
3282 */
3283#include <mach/mach_types.h>
3284#include <mach/memory_object_types.h>
3285#include <kern/sched_prim.h>
3286
3287
3288static void
3289bcleanbuf_thread_init(void)
3290{
3291 /* create worker thread */
3292 kernel_thread(kernel_task, bcleanbuf_thread);
3293}
3294
3295static void
3296bcleanbuf_thread(void)
3297{
3298 struct buf *bp;
3299 int error = 0;
3300 int loopcnt = 0;
3301
3302 for (;;) {
3303 lck_mtx_lock(buf_mtxp);
3304
3305 while (blaundrycnt == 0)
3306 (void)msleep((void *)&blaundrycnt, buf_mtxp, PRIBIO, "blaundry", 0);
3307
3308 bp = TAILQ_FIRST(&bufqueues[BQ_LAUNDRY]);
3309 /*
3310 * Remove from the queue
3311 */
3312 bremfree_locked(bp);
3313 blaundrycnt--;
3314
3315 lck_mtx_unlock(buf_mtxp);
3316 /*
3317 * do the IO
3318 */
3319 error = bawrite_internal(bp, 0);
3320
3321 if (error) {
3322 lck_mtx_lock(buf_mtxp);
3323
3324 binstailfree(bp, &bufqueues[BQ_LAUNDRY], BQ_LAUNDRY);
3325 blaundrycnt++;
3326
3327 lck_mtx_unlock(buf_mtxp);
3328
3329 if (loopcnt > 10) {
3330 (void)tsleep((void *)&blaundrycnt, PRIBIO, "blaundry", 1);
3331 loopcnt = 0;
3332 } else {
3333 (void)thread_block(THREAD_CONTINUE_NULL);
3334 loopcnt++;
3335 }
3336 }
3337 }
3338}
3339
3340
3341static int
3342brecover_data(buf_t bp)
3343{
3344 int upl_offset;
3345 upl_t upl;
3346 upl_page_info_t *pl;
3347 kern_return_t kret;
3348 vnode_t vp = bp->b_vp;
3349 int upl_flags;
3350
3351
3352 if ( !UBCINFOEXISTS(vp) || bp->b_bufsize == 0)
3353 goto dump_buffer;
3354
3355 upl_flags = UPL_PRECIOUS;
3356 if (! (buf_flags(bp) & B_READ)) {
3357 /*
3358 * "write" operation: let the UPL subsystem know
3359 * that we intend to modify the buffer cache pages we're
3360 * gathering.
3361 */
3362 upl_flags |= UPL_WILL_MODIFY;
3363 }
3364
3365 kret = ubc_create_upl(vp,
3366 ubc_blktooff(vp, bp->b_lblkno),
3367 bp->b_bufsize,
3368 &upl,
3369 &pl,
3370 upl_flags);
3371 if (kret != KERN_SUCCESS)
3372 panic("Failed to create UPL");
3373
3374 for (upl_offset = 0; upl_offset < bp->b_bufsize; upl_offset += PAGE_SIZE) {
3375
3376 if (!upl_valid_page(pl, upl_offset / PAGE_SIZE) || !upl_dirty_page(pl, upl_offset / PAGE_SIZE)) {
3377 ubc_upl_abort(upl, 0);
3378 goto dump_buffer;
3379 }
3380 }
3381 bp->b_upl = upl;
3382
3383 kret = ubc_upl_map(upl, (vm_address_t *)&(bp->b_datap));
3384
3385 if (kret != KERN_SUCCESS)
3386 panic("getblk: ubc_upl_map() failed with (%d)", kret);
3387 return (1);
3388
3389dump_buffer:
3390 bp->b_bufsize = 0;
3391 SET(bp->b_flags, B_INVAL);
3392 buf_brelse(bp);
3393
3394 return(0);
3395}
3396
3397
3398
3399/*
3400 * disabled for now
3401 */
3402
3403#if FLUSH_QUEUES
3404
3405#define NFLUSH 32
3406
3407static int
3408bp_cmp(void *a, void *b)
3409{
3410 buf_t *bp_a = *(buf_t **)a,
3411 *bp_b = *(buf_t **)b;
3412 daddr64_t res;
1c79356b 3413
91447636
A
3414 // don't have to worry about negative block
3415 // numbers so this is ok to do.
3416 //
3417 res = (bp_a->b_blkno - bp_b->b_blkno);
3418
3419 return (int)res;
1c79356b 3420}
1c79356b
A
3421
3422
91447636
A
3423int
3424bflushq(int whichq, mount_t mp)
1c79356b 3425{
91447636
A
3426 buf_t bp, next;
3427 int i, buf_count;
3428 int total_writes = 0;
3429 static buf_t flush_table[NFLUSH];
1c79356b 3430
91447636
A
3431 if (whichq < 0 || whichq >= BQUEUES) {
3432 return (0);
0b4e3aa0
A
3433 }
3434
91447636
A
3435 restart:
3436 lck_mtx_lock(buf_mtxp);
0b4e3aa0 3437
91447636 3438 bp = TAILQ_FIRST(&bufqueues[whichq]);
1c79356b 3439
91447636
A
3440 for (buf_count = 0; bp; bp = next) {
3441 next = bp->b_freelist.tqe_next;
3442
3443 if (bp->b_vp == NULL || bp->b_vp->v_mount != mp) {
3444 continue;
3445 }
b4c24cb9 3446
91447636 3447 if (ISSET(bp->b_flags, B_DELWRI) && !ISSET(bp->b_lflags, BL_BUSY)) {
1c79356b 3448
91447636
A
3449 bremfree_locked(bp);
3450#ifdef JOE_DEBUG
3451 bp->b_owner = current_thread();
3452 bp->b_tag = 7;
3453#endif
3454 SET(bp->b_lflags, BL_BUSY);
3455 flush_table[buf_count] = bp;
3456 buf_count++;
3457 total_writes++;
1c79356b 3458
91447636
A
3459 if (buf_count >= NFLUSH) {
3460 lck_mtx_unlock(buf_mtxp);
1c79356b 3461
91447636 3462 qsort(flush_table, buf_count, sizeof(struct buf *), bp_cmp);
1c79356b 3463
91447636
A
3464 for (i = 0; i < buf_count; i++) {
3465 buf_bawrite(flush_table[i]);
3466 }
3467 goto restart;
3468 }
3469 }
3470 }
3471 lck_mtx_unlock(buf_mtxp);
1c79356b 3472
91447636
A
3473 if (buf_count > 0) {
3474 qsort(flush_table, buf_count, sizeof(struct buf *), bp_cmp);
1c79356b 3475
91447636
A
3476 for (i = 0; i < buf_count; i++) {
3477 buf_bawrite(flush_table[i]);
3478 }
1c79356b 3479 }
91447636
A
3480
3481 return (total_writes);
1c79356b 3482}
91447636 3483#endif
1c79356b 3484
91447636
A
3485
3486#if BALANCE_QUEUES
1c79356b
A
3487
3488/* XXX move this to a separate file */
91447636
A
3489
3490/*
3491 * NOTE: THIS CODE HAS NOT BEEN UPDATED
3492 * WITH RESPECT TO THE NEW LOCKING MODEL
3493 */
3494
3495
1c79356b
A
3496/*
3497 * Dynamic Scaling of the Buffer Queues
3498 */
3499
3500typedef long long blsize_t;
3501
55e303ae 3502blsize_t MAXNBUF; /* initialize to (sane_size / PAGE_SIZE) */
1c79356b
A
3503/* Global tunable limits */
3504blsize_t nbufh; /* number of buffer headers */
3505blsize_t nbuflow; /* minimum number of buffer headers required */
3506blsize_t nbufhigh; /* maximum number of buffer headers allowed */
3507blsize_t nbuftarget; /* preferred number of buffer headers */
3508
3509/*
3510 * assertions:
3511 *
3512 * 1. 0 < nbuflow <= nbufh <= nbufhigh
3513 * 2. nbufhigh <= MAXNBUF
3514 * 3. 0 < nbuflow <= nbuftarget <= nbufhigh
3515 * 4. nbufh can not be set by sysctl().
3516 */
3517
3518/* Per queue tunable limits */
3519
3520struct bufqlim {
3521 blsize_t bl_nlow; /* minimum number of buffer headers required */
3522 blsize_t bl_num; /* number of buffer headers on the queue */
3523 blsize_t bl_nlhigh; /* maximum number of buffer headers allowed */
3524 blsize_t bl_target; /* preferred number of buffer headers */
3525 long bl_stale; /* Seconds after which a buffer is considered stale */
3526} bufqlim[BQUEUES];
3527
3528/*
3529 * assertions:
3530 *
3531 * 1. 0 <= bl_nlow <= bl_num <= bl_nlhigh
3532 * 2. bl_nlhigh <= MAXNBUF
3533 * 3. bufqlim[BQ_META].bl_nlow != 0
3534 * 4. bufqlim[BQ_META].bl_nlow > (number of possible concurrent
3535 * file system IO operations)
3536 * 5. bl_num can not be set by sysctl().
3537 * 6. bl_nhigh <= nbufhigh
3538 */
3539
3540/*
3541 * Rationale:
3542 * ----------
3543 * Defining it blsize_t as long permits 2^31 buffer headers per queue.
3544 * Which can describe (2^31 * PAGE_SIZE) memory per queue.
3545 *
3546 * These limits are exported to by means of sysctl().
3547 * It was decided to define blsize_t as a 64 bit quantity.
3548 * This will make sure that we will not be required to change it
3549 * as long as we do not exceed 64 bit address space for the kernel.
3550 *
3551 * low and high numbers parameters initialized at compile time
3552 * and boot arguments can be used to override them. sysctl()
3553 * would not change the value. sysctl() can get all the values
3554 * but can set only target. num is the current level.
3555 *
3556 * Advantages of having a "bufqscan" thread doing the balancing are,
3557 * Keep enough bufs on BQ_EMPTY.
3558 * getnewbuf() by default will always select a buffer from the BQ_EMPTY.
3559 * getnewbuf() perfoms best if a buffer was found there.
3560 * Also this minimizes the possibility of starting IO
3561 * from getnewbuf(). That's a performance win, too.
3562 *
3563 * Localize complex logic [balancing as well as time aging]
3564 * to balancebufq().
3565 *
3566 * Simplify getnewbuf() logic by elimination of time aging code.
3567 */
3568
3569/*
3570 * Algorithm:
3571 * -----------
3572 * The goal of the dynamic scaling of the buffer queues to to keep
3573 * the size of the LRU close to bl_target. Buffers on a queue would
3574 * be time aged.
3575 *
3576 * There would be a thread which will be responsible for "balancing"
3577 * the buffer cache queues.
3578 *
3579 * The scan order would be: AGE, LRU, META, EMPTY.
3580 */
3581
3582long bufqscanwait = 0;
3583
9bccf70c
A
3584static void bufqscan_thread();
3585static int balancebufq(int q);
3586static int btrimempty(int n);
3587static __inline__ int initbufqscan(void);
3588static __inline__ int nextbufq(int q);
3589static void buqlimprt(int all);
1c79356b 3590
91447636
A
3591
3592static __inline__ void
3593bufqinc(int q)
3594{
3595 if ((q < 0) || (q >= BQUEUES))
3596 return;
3597
3598 bufqlim[q].bl_num++;
3599 return;
3600}
3601
3602static __inline__ void
3603bufqdec(int q)
3604{
3605 if ((q < 0) || (q >= BQUEUES))
3606 return;
3607
3608 bufqlim[q].bl_num--;
3609 return;
3610}
3611
9bccf70c 3612static void
1c79356b
A
3613bufq_balance_thread_init()
3614{
3615
3616 if (bufqscanwait++ == 0) {
1c79356b
A
3617
3618 /* Initalize globals */
55e303ae 3619 MAXNBUF = (sane_size / PAGE_SIZE);
1c79356b
A
3620 nbufh = nbuf;
3621 nbuflow = min(nbufh, 100);
3622 nbufhigh = min(MAXNBUF, max(nbufh, 2048));
55e303ae 3623 nbuftarget = (sane_size >> 5) / PAGE_SIZE;
1c79356b
A
3624 nbuftarget = max(nbuflow, nbuftarget);
3625 nbuftarget = min(nbufhigh, nbuftarget);
3626
3627 /*
3628 * Initialize the bufqlim
3629 */
3630
3631 /* LOCKED queue */
3632 bufqlim[BQ_LOCKED].bl_nlow = 0;
3633 bufqlim[BQ_LOCKED].bl_nlhigh = 32;
3634 bufqlim[BQ_LOCKED].bl_target = 0;
3635 bufqlim[BQ_LOCKED].bl_stale = 30;
3636
3637 /* LRU queue */
3638 bufqlim[BQ_LRU].bl_nlow = 0;
3639 bufqlim[BQ_LRU].bl_nlhigh = nbufhigh/4;
3640 bufqlim[BQ_LRU].bl_target = nbuftarget/4;
3641 bufqlim[BQ_LRU].bl_stale = LRU_IS_STALE;
3642
3643 /* AGE queue */
3644 bufqlim[BQ_AGE].bl_nlow = 0;
3645 bufqlim[BQ_AGE].bl_nlhigh = nbufhigh/4;
3646 bufqlim[BQ_AGE].bl_target = nbuftarget/4;
3647 bufqlim[BQ_AGE].bl_stale = AGE_IS_STALE;
3648
3649 /* EMPTY queue */
3650 bufqlim[BQ_EMPTY].bl_nlow = 0;
3651 bufqlim[BQ_EMPTY].bl_nlhigh = nbufhigh/4;
3652 bufqlim[BQ_EMPTY].bl_target = nbuftarget/4;
3653 bufqlim[BQ_EMPTY].bl_stale = 600000;
3654
3655 /* META queue */
3656 bufqlim[BQ_META].bl_nlow = 0;
3657 bufqlim[BQ_META].bl_nlhigh = nbufhigh/4;
3658 bufqlim[BQ_META].bl_target = nbuftarget/4;
3659 bufqlim[BQ_META].bl_stale = META_IS_STALE;
3660
765c9de3
A
3661 /* LAUNDRY queue */
3662 bufqlim[BQ_LOCKED].bl_nlow = 0;
3663 bufqlim[BQ_LOCKED].bl_nlhigh = 32;
3664 bufqlim[BQ_LOCKED].bl_target = 0;
3665 bufqlim[BQ_LOCKED].bl_stale = 30;
3666
1c79356b
A
3667 buqlimprt(1);
3668 }
3669
3670 /* create worker thread */
3671 kernel_thread(kernel_task, bufqscan_thread);
3672}
3673
3674/* The workloop for the buffer balancing thread */
9bccf70c 3675static void
1c79356b
A
3676bufqscan_thread()
3677{
1c79356b
A
3678 int moretodo = 0;
3679
1c79356b
A
3680 for(;;) {
3681 do {
3682 int q; /* buffer queue to process */
3683
9bccf70c
A
3684 q = initbufqscan();
3685 for (; q; ) {
1c79356b
A
3686 moretodo |= balancebufq(q);
3687 q = nextbufq(q);
3688 }
3689 } while (moretodo);
3690
9bccf70c 3691#if DIAGNOSTIC
1c79356b
A
3692 vfs_bufstats();
3693 buqlimprt(0);
3694#endif
3695 (void)tsleep((void *)&bufqscanwait, PRIBIO, "bufqscanwait", 60 * hz);
3696 moretodo = 0;
3697 }
1c79356b
A
3698}
3699
3700/* Seed for the buffer queue balancing */
9bccf70c 3701static __inline__ int
1c79356b
A
3702initbufqscan()
3703{
3704 /* Start with AGE queue */
3705 return (BQ_AGE);
3706}
3707
3708/* Pick next buffer queue to balance */
9bccf70c 3709static __inline__ int
1c79356b
A
3710nextbufq(int q)
3711{
3712 int order[] = { BQ_AGE, BQ_LRU, BQ_META, BQ_EMPTY, 0 };
3713
3714 q++;
3715 q %= sizeof(order);
3716 return (order[q]);
3717}
3718
3719/* function to balance the buffer queues */
9bccf70c 3720static int
1c79356b
A
3721balancebufq(int q)
3722{
3723 int moretodo = 0;
3724 int s = splbio();
91447636 3725 int n, t;
1c79356b
A
3726
3727 /* reject invalid q */
3728 if ((q < 0) || (q >= BQUEUES))
3729 goto out;
3730
765c9de3
A
3731 /* LOCKED or LAUNDRY queue MUST not be balanced */
3732 if ((q == BQ_LOCKED) || (q == BQ_LAUNDRY))
1c79356b
A
3733 goto out;
3734
3735 n = (bufqlim[q].bl_num - bufqlim[q].bl_target);
3736
3737 /* If queue has less than target nothing more to do */
3738 if (n < 0)
3739 goto out;
3740
3741 if ( n > 8 ) {
3742 /* Balance only a small amount (12.5%) at a time */
3743 n >>= 3;
3744 }
3745
3746 /* EMPTY queue needs special handling */
3747 if (q == BQ_EMPTY) {
3748 moretodo |= btrimempty(n);
3749 goto out;
3750 }
91447636
A
3751
3752 t = buf_timestamp():
1c79356b
A
3753
3754 for (; n > 0; n--) {
3755 struct buf *bp = bufqueues[q].tqh_first;
3756 if (!bp)
3757 break;
3758
3759 /* check if it's stale */
91447636 3760 if ((t - bp->b_timestamp) > bufqlim[q].bl_stale) {
1c79356b 3761 if (bcleanbuf(bp)) {
91447636 3762 /* buf_bawrite() issued, bp not ready */
1c79356b
A
3763 moretodo = 1;
3764 } else {
3765 /* release the cleaned buffer to BQ_EMPTY */
3766 SET(bp->b_flags, B_INVAL);
91447636 3767 buf_brelse(bp);
1c79356b
A
3768 }
3769 } else
3770 break;
3771 }
3772
3773out:
3774 splx(s);
3775 return (moretodo);
3776}
3777
9bccf70c 3778static int
1c79356b
A
3779btrimempty(int n)
3780{
3781 /*
3782 * When struct buf are allocated dynamically, this would
3783 * reclaim upto 'n' struct buf from the empty queue.
3784 */
3785
3786 return (0);
3787}
3788
9bccf70c 3789static void
1c79356b
A
3790buqlimprt(int all)
3791{
3792 int i;
765c9de3
A
3793 static char *bname[BQUEUES] =
3794 { "LOCKED", "LRU", "AGE", "EMPTY", "META", "LAUNDRY" };
1c79356b
A
3795
3796 if (all)
3797 for (i = 0; i < BQUEUES; i++) {
3798 printf("%s : ", bname[i]);
9bccf70c
A
3799 printf("min = %ld, ", (long)bufqlim[i].bl_nlow);
3800 printf("cur = %ld, ", (long)bufqlim[i].bl_num);
3801 printf("max = %ld, ", (long)bufqlim[i].bl_nlhigh);
3802 printf("target = %ld, ", (long)bufqlim[i].bl_target);
3803 printf("stale after %ld seconds\n", bufqlim[i].bl_stale);
1c79356b
A
3804 }
3805 else
3806 for (i = 0; i < BQUEUES; i++) {
3807 printf("%s : ", bname[i]);
9bccf70c 3808 printf("cur = %ld, ", (long)bufqlim[i].bl_num);
1c79356b
A
3809 }
3810}
765c9de3 3811
91447636 3812#endif
b4c24cb9 3813
b4c24cb9 3814