17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 536945f79Smrj * Common Development and Distribution License (the "License"). 636945f79Smrj * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22ed0efa68SDonghai Qiao * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 237c478bd9Sstevel@tonic-gate * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ 277c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate /* 307c478bd9Sstevel@tonic-gate * University Copyright- Copyright (c) 1982, 1986, 1988 317c478bd9Sstevel@tonic-gate * The Regents of the University of California 327c478bd9Sstevel@tonic-gate * All Rights Reserved 337c478bd9Sstevel@tonic-gate * 347c478bd9Sstevel@tonic-gate * University Acknowledgment- Portions of this document are derived from 357c478bd9Sstevel@tonic-gate * software developed by the University of California, Berkeley, and its 367c478bd9Sstevel@tonic-gate * contributors. 377c478bd9Sstevel@tonic-gate */ 387c478bd9Sstevel@tonic-gate 397c478bd9Sstevel@tonic-gate #ifndef _SYS_BUF_H 407c478bd9Sstevel@tonic-gate #define _SYS_BUF_H 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #include <sys/types32.h> 437c478bd9Sstevel@tonic-gate #include <sys/t_lock.h> 447c478bd9Sstevel@tonic-gate #include <sys/kstat.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #ifdef __cplusplus 477c478bd9Sstevel@tonic-gate extern "C" { 487c478bd9Sstevel@tonic-gate #endif 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate /* 517c478bd9Sstevel@tonic-gate * Each buffer in the pool is usually doubly linked into 2 lists: 527c478bd9Sstevel@tonic-gate * the device with which it is currently associated (always) 537c478bd9Sstevel@tonic-gate * and also on a list of blocks available for allocation 547c478bd9Sstevel@tonic-gate * for other use (usually). 557c478bd9Sstevel@tonic-gate * The latter list is kept in last-used order, and the two 567c478bd9Sstevel@tonic-gate * lists are doubly linked to make it easy to remove 577c478bd9Sstevel@tonic-gate * a buffer from one list when it was found by 587c478bd9Sstevel@tonic-gate * looking through the other. 597c478bd9Sstevel@tonic-gate * A buffer is on the available list, and is liable 607c478bd9Sstevel@tonic-gate * to be reassigned to another disk block, if and only 617c478bd9Sstevel@tonic-gate * if it is not marked BUSY. When a buffer is busy, the 627c478bd9Sstevel@tonic-gate * available-list pointers can be used for other purposes. 637c478bd9Sstevel@tonic-gate * Most drivers use the forward ptr as a link in their I/O active queue. 647c478bd9Sstevel@tonic-gate * A buffer header contains all the information required to perform I/O. 657c478bd9Sstevel@tonic-gate * Most of the routines which manipulate these things are in bio.c. 667c478bd9Sstevel@tonic-gate * 677c478bd9Sstevel@tonic-gate * There are a number of locks associated with the buffer management 687c478bd9Sstevel@tonic-gate * system. 697c478bd9Sstevel@tonic-gate * hbuf.b_lock: protects hash chains, buffer hdr freelists 707c478bd9Sstevel@tonic-gate * and delayed write freelist 717c478bd9Sstevel@tonic-gate * bfree_lock; protects the bfreelist structure 727c478bd9Sstevel@tonic-gate * bhdr_lock: protects the free header list 737c478bd9Sstevel@tonic-gate * blist_lock: protects b_list fields 747c478bd9Sstevel@tonic-gate * buf.b_sem: protects all remaining members in the buf struct 757c478bd9Sstevel@tonic-gate * buf.b_io: I/O synchronization variable 767c478bd9Sstevel@tonic-gate * 777c478bd9Sstevel@tonic-gate * A buffer header is never "locked" (b_sem) when it is on 787c478bd9Sstevel@tonic-gate * a "freelist" (bhdrlist or bfreelist avail lists). 797c478bd9Sstevel@tonic-gate */ 807c478bd9Sstevel@tonic-gate typedef struct buf { 817c478bd9Sstevel@tonic-gate int b_flags; /* see defines below */ 827c478bd9Sstevel@tonic-gate struct buf *b_forw; /* headed by d_tab of conf.c */ 837c478bd9Sstevel@tonic-gate struct buf *b_back; /* " */ 847c478bd9Sstevel@tonic-gate struct buf *av_forw; /* position on free list, */ 857c478bd9Sstevel@tonic-gate struct buf *av_back; /* if not BUSY */ 867c478bd9Sstevel@tonic-gate o_dev_t b_dev; /* OLD major+minor device name */ 877c478bd9Sstevel@tonic-gate size_t b_bcount; /* transfer count */ 887c478bd9Sstevel@tonic-gate union { 897c478bd9Sstevel@tonic-gate caddr_t b_addr; /* low order core address */ 907c478bd9Sstevel@tonic-gate struct fs *b_fs; /* superblocks */ 917c478bd9Sstevel@tonic-gate struct cg *b_cg; /* UFS cylinder group block */ 927c478bd9Sstevel@tonic-gate struct dinode *b_dino; /* UFS ilist */ 937c478bd9Sstevel@tonic-gate daddr32_t *b_daddr; /* disk blocks */ 947c478bd9Sstevel@tonic-gate } b_un; 957c478bd9Sstevel@tonic-gate 967c478bd9Sstevel@tonic-gate lldaddr_t _b_blkno; /* block # on device (union) */ 977c478bd9Sstevel@tonic-gate #define b_lblkno _b_blkno._f 987c478bd9Sstevel@tonic-gate #ifdef _LP64 997c478bd9Sstevel@tonic-gate #define b_blkno _b_blkno._f 1007c478bd9Sstevel@tonic-gate #else 1017c478bd9Sstevel@tonic-gate #define b_blkno _b_blkno._p._l 1027c478bd9Sstevel@tonic-gate #endif /* _LP64 */ 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate char b_obs1; /* obsolete */ 1057c478bd9Sstevel@tonic-gate size_t b_resid; /* words not transferred after error */ 1067c478bd9Sstevel@tonic-gate clock_t b_start; /* request start time */ 1077c478bd9Sstevel@tonic-gate struct proc *b_proc; /* process doing physical or swap I/O */ 1087c478bd9Sstevel@tonic-gate struct page *b_pages; /* page list for PAGEIO */ 1097c478bd9Sstevel@tonic-gate clock_t b_obs2; /* obsolete */ 1107c478bd9Sstevel@tonic-gate /* Begin new stuff */ 1117c478bd9Sstevel@tonic-gate #define b_actf av_forw 1127c478bd9Sstevel@tonic-gate #define b_actl av_back 1137c478bd9Sstevel@tonic-gate #define b_active b_bcount 1147c478bd9Sstevel@tonic-gate #define b_errcnt b_resid 1157c478bd9Sstevel@tonic-gate size_t b_bufsize; /* size of allocated buffer */ 1167c478bd9Sstevel@tonic-gate int (*b_iodone)(struct buf *); /* function called by iodone */ 1177c478bd9Sstevel@tonic-gate struct vnode *b_vp; /* vnode associated with block */ 1187c478bd9Sstevel@tonic-gate struct buf *b_chain; /* chain together all buffers here */ 1197c478bd9Sstevel@tonic-gate int b_obs3; /* obsolete */ 1207c478bd9Sstevel@tonic-gate int b_error; /* expanded error field */ 1217c478bd9Sstevel@tonic-gate void *b_private; /* "opaque" driver private area */ 1227c478bd9Sstevel@tonic-gate dev_t b_edev; /* expanded dev field */ 1237c478bd9Sstevel@tonic-gate ksema_t b_sem; /* Exclusive access to buf */ 1247c478bd9Sstevel@tonic-gate ksema_t b_io; /* I/O Synchronization */ 1257c478bd9Sstevel@tonic-gate struct buf *b_list; /* List of potential B_DELWRI bufs */ 1267c478bd9Sstevel@tonic-gate struct page **b_shadow; /* shadow page list */ 1277c478bd9Sstevel@tonic-gate void *b_dip; /* device info pointer */ 1287c478bd9Sstevel@tonic-gate struct vnode *b_file; /* file associated with this buffer */ 1297c478bd9Sstevel@tonic-gate offset_t b_offset; /* offset in file assoc. with buffer */ 1307c478bd9Sstevel@tonic-gate } buf_t; 1317c478bd9Sstevel@tonic-gate 1327c478bd9Sstevel@tonic-gate /* 1337c478bd9Sstevel@tonic-gate * Bufhd structures used at the head of the hashed buffer queues. 1347c478bd9Sstevel@tonic-gate * We only need seven words for this, so this abbreviated 1357c478bd9Sstevel@tonic-gate * definition saves some space. 1367c478bd9Sstevel@tonic-gate */ 1377c478bd9Sstevel@tonic-gate struct diskhd { 1387c478bd9Sstevel@tonic-gate int b_flags; /* not used, needed for consistency */ 1397c478bd9Sstevel@tonic-gate struct buf *b_forw, *b_back; /* queue of unit queues */ 1407c478bd9Sstevel@tonic-gate struct buf *av_forw, *av_back; /* queue of bufs for this unit */ 1417c478bd9Sstevel@tonic-gate o_dev_t b_dev; /* OLD major+minor device name */ 1427c478bd9Sstevel@tonic-gate size_t b_bcount; /* transfer count */ 1437c478bd9Sstevel@tonic-gate }; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate /* 1477c478bd9Sstevel@tonic-gate * Statistics on the buffer cache 1487c478bd9Sstevel@tonic-gate */ 1497c478bd9Sstevel@tonic-gate struct biostats { 1507c478bd9Sstevel@tonic-gate kstat_named_t bio_lookup; /* requests to assign buffer */ 1517c478bd9Sstevel@tonic-gate kstat_named_t bio_hit; /* buffer already associated with blk */ 1527c478bd9Sstevel@tonic-gate kstat_named_t bio_bufwant; /* kmem_allocs NOSLEEP failed new buf */ 1537c478bd9Sstevel@tonic-gate kstat_named_t bio_bufwait; /* kmem_allocs with KM_SLEEP for buf */ 1547c478bd9Sstevel@tonic-gate kstat_named_t bio_bufbusy; /* buffer locked by someone else */ 1557c478bd9Sstevel@tonic-gate kstat_named_t bio_bufdup; /* duplicate buffer found for block */ 1567c478bd9Sstevel@tonic-gate }; 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate /* 1597c478bd9Sstevel@tonic-gate * These flags are kept in b_flags. 1607c478bd9Sstevel@tonic-gate * The first group is part of the DDI 1617c478bd9Sstevel@tonic-gate */ 1627c478bd9Sstevel@tonic-gate #define B_BUSY 0x0001 /* not on av_forw/back list */ 1637c478bd9Sstevel@tonic-gate #define B_DONE 0x0002 /* transaction finished */ 1647c478bd9Sstevel@tonic-gate #define B_ERROR 0x0004 /* transaction aborted */ 1657c478bd9Sstevel@tonic-gate #define B_PAGEIO 0x0010 /* do I/O to pages on bp->p_pages */ 1667c478bd9Sstevel@tonic-gate #define B_PHYS 0x0020 /* Physical IO potentially using UNIBUS map */ 1677c478bd9Sstevel@tonic-gate #define B_READ 0x0040 /* read when I/O occurs */ 1687c478bd9Sstevel@tonic-gate #define B_WRITE 0x0100 /* non-read pseudo-flag */ 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* Not part of the DDI */ 1717c478bd9Sstevel@tonic-gate #define B_WANTED 0x0080 /* issue wakeup when BUSY goes off */ 1727c478bd9Sstevel@tonic-gate #define B_AGE 0x000200 /* delayed write for correct aging */ 1737c478bd9Sstevel@tonic-gate #define B_ASYNC 0x000400 /* don't wait for I/O completion */ 1747c478bd9Sstevel@tonic-gate #define B_DELWRI 0x000800 /* delayed write-wait til buf needed */ 1757c478bd9Sstevel@tonic-gate #define B_STALE 0x001000 /* on av_* list; invalid contents */ 1767c478bd9Sstevel@tonic-gate #define B_DONTNEED 0x002000 /* after write, need not be cached */ 1777c478bd9Sstevel@tonic-gate #define B_REMAPPED 0x004000 /* buffer is kernel addressable */ 1787c478bd9Sstevel@tonic-gate #define B_FREE 0x008000 /* free page when done */ 179*2e0ea4c4SMichael Corcoran #define B_INVAL 0x010000 /* destroy page when done */ 1807c478bd9Sstevel@tonic-gate #define B_FORCE 0x020000 /* semi-permanent removal from cache */ 1817c478bd9Sstevel@tonic-gate #define B_NOCACHE 0x080000 /* don't cache block when released */ 1827c478bd9Sstevel@tonic-gate #define B_TRUNC 0x100000 /* truncate page without I/O */ 1837c478bd9Sstevel@tonic-gate #define B_SHADOW 0x200000 /* is b_shadow field valid? */ 1847c478bd9Sstevel@tonic-gate #define B_RETRYWRI 0x400000 /* retry write til works or bfinval */ 1857c478bd9Sstevel@tonic-gate #define B_FAILFAST 0x1000000 /* Fail promptly if device goes away */ 1867c478bd9Sstevel@tonic-gate #define B_STARTED 0x2000000 /* io:::start probe called for buf */ 1877c478bd9Sstevel@tonic-gate #define B_ABRWRITE 0x4000000 /* Application based recovery active */ 188ed0efa68SDonghai Qiao #define B_PAGE_NOWAIT 0x8000000 /* Skip the page if it is locked */ 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate /* 191*2e0ea4c4SMichael Corcoran * There is some confusion over the meaning of B_FREE and B_INVAL and what 192*2e0ea4c4SMichael Corcoran * the use of one over the other implies. 193*2e0ea4c4SMichael Corcoran * 194*2e0ea4c4SMichael Corcoran * In both cases, when we are done with the page (buffer) we want to free 195*2e0ea4c4SMichael Corcoran * up the page. In the case of B_FREE, the page will go to the cachelist. 196*2e0ea4c4SMichael Corcoran * In the case of B_INVAL, the page will be destroyed (hashed out of it's 197*2e0ea4c4SMichael Corcoran * vnode) and placed on the freelist. Beyond this, there is no difference 198*2e0ea4c4SMichael Corcoran * between the sole use of these two flags. In both cases, IO will be done 199*2e0ea4c4SMichael Corcoran * if the page is not yet committed to storage. 200*2e0ea4c4SMichael Corcoran * 201*2e0ea4c4SMichael Corcoran * In order to discard pages without writing them back, (B_INVAL | B_TRUNC) 202*2e0ea4c4SMichael Corcoran * should be used. 203*2e0ea4c4SMichael Corcoran * 204*2e0ea4c4SMichael Corcoran * Use (B_INVAL | B_FORCE) to force the page to be destroyed even if we 205*2e0ea4c4SMichael Corcoran * could not successfuly write out the page. 206*2e0ea4c4SMichael Corcoran */ 207*2e0ea4c4SMichael Corcoran 208*2e0ea4c4SMichael Corcoran /* 2097c478bd9Sstevel@tonic-gate * Insq/Remq for the buffer hash lists. 2107c478bd9Sstevel@tonic-gate */ 2117c478bd9Sstevel@tonic-gate #define bremhash(bp) { \ 2127c478bd9Sstevel@tonic-gate ASSERT((bp)->b_forw != NULL); \ 2137c478bd9Sstevel@tonic-gate ASSERT((bp)->b_back != NULL); \ 2147c478bd9Sstevel@tonic-gate (bp)->b_back->b_forw = (bp)->b_forw; \ 2157c478bd9Sstevel@tonic-gate (bp)->b_forw->b_back = (bp)->b_back; \ 2167c478bd9Sstevel@tonic-gate (bp)->b_forw = (bp)->b_back = NULL; \ 2177c478bd9Sstevel@tonic-gate } 2187c478bd9Sstevel@tonic-gate #define binshash(bp, dp) { \ 2197c478bd9Sstevel@tonic-gate ASSERT((bp)->b_forw == NULL); \ 2207c478bd9Sstevel@tonic-gate ASSERT((bp)->b_back == NULL); \ 2217c478bd9Sstevel@tonic-gate ASSERT((dp)->b_forw != NULL); \ 2227c478bd9Sstevel@tonic-gate ASSERT((dp)->b_back != NULL); \ 2237c478bd9Sstevel@tonic-gate (bp)->b_forw = (dp)->b_forw; \ 2247c478bd9Sstevel@tonic-gate (bp)->b_back = (dp); \ 2257c478bd9Sstevel@tonic-gate (dp)->b_forw->b_back = (bp); \ 2267c478bd9Sstevel@tonic-gate (dp)->b_forw = (bp); \ 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate 2297c478bd9Sstevel@tonic-gate 2307c478bd9Sstevel@tonic-gate /* 2317c478bd9Sstevel@tonic-gate * The hash structure maintains two lists: 2327c478bd9Sstevel@tonic-gate * 2337c478bd9Sstevel@tonic-gate * 1) The hash list of buffers (b_forw & b_back) 2347c478bd9Sstevel@tonic-gate * 2) The LRU free list of buffers on this hash bucket (av_forw & av_back) 2357c478bd9Sstevel@tonic-gate * 2367c478bd9Sstevel@tonic-gate * The dwbuf structure keeps a list of delayed write buffers per hash bucket 2377c478bd9Sstevel@tonic-gate * hence there are exactly the same number of dwbuf structures as there are 2387c478bd9Sstevel@tonic-gate * the hash buckets (hbuf structures) in the system. 2397c478bd9Sstevel@tonic-gate * 2407c478bd9Sstevel@tonic-gate * The number of buffers on the freelist may not be equal to the number of 2417c478bd9Sstevel@tonic-gate * buffers on the hash list. That is because when buffers are busy they are 2427c478bd9Sstevel@tonic-gate * taken off the freelist but not off the hash list. "b_length" field keeps 2437c478bd9Sstevel@tonic-gate * track of the number of free buffers (including delayed writes ones) on 2447c478bd9Sstevel@tonic-gate * the hash bucket. The "b_lock" mutex protects the free list as well as 2457c478bd9Sstevel@tonic-gate * the hash list. It also protects the counter "b_length". 2467c478bd9Sstevel@tonic-gate * 2477c478bd9Sstevel@tonic-gate * Enties b_forw, b_back, av_forw & av_back must be at the same offset 2487c478bd9Sstevel@tonic-gate * as the ones in buf structure. 2497c478bd9Sstevel@tonic-gate */ 2507c478bd9Sstevel@tonic-gate struct hbuf { 2517c478bd9Sstevel@tonic-gate int b_flags; 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate struct buf *b_forw; /* hash list forw pointer */ 2547c478bd9Sstevel@tonic-gate struct buf *b_back; /* hash list back pointer */ 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate struct buf *av_forw; /* free list forw pointer */ 2577c478bd9Sstevel@tonic-gate struct buf *av_back; /* free list back pointer */ 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate int b_length; /* # of entries on free list */ 2607c478bd9Sstevel@tonic-gate kmutex_t b_lock; /* lock to protect this structure */ 2617c478bd9Sstevel@tonic-gate }; 2627c478bd9Sstevel@tonic-gate 2637c478bd9Sstevel@tonic-gate 2647c478bd9Sstevel@tonic-gate /* 2657c478bd9Sstevel@tonic-gate * The delayed list pointer entries should match with the buf strcuture. 2667c478bd9Sstevel@tonic-gate */ 2677c478bd9Sstevel@tonic-gate struct dwbuf { 2687c478bd9Sstevel@tonic-gate int b_flags; /* not used */ 2697c478bd9Sstevel@tonic-gate 2707c478bd9Sstevel@tonic-gate struct buf *b_forw; /* not used */ 2717c478bd9Sstevel@tonic-gate struct buf *b_back; /* not used */ 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate struct buf *av_forw; /* delayed write forw pointer */ 2747c478bd9Sstevel@tonic-gate struct buf *av_back; /* delayed write back pointer */ 2757c478bd9Sstevel@tonic-gate }; 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate 2787c478bd9Sstevel@tonic-gate /* 2797c478bd9Sstevel@tonic-gate * Unlink a buffer from the available (free or delayed write) list and mark 2807c478bd9Sstevel@tonic-gate * it busy (internal interface). 2817c478bd9Sstevel@tonic-gate */ 2827c478bd9Sstevel@tonic-gate #define notavail(bp) \ 2837c478bd9Sstevel@tonic-gate {\ 2847c478bd9Sstevel@tonic-gate ASSERT(SEMA_HELD(&bp->b_sem)); \ 2857c478bd9Sstevel@tonic-gate ASSERT((bp)->av_forw != NULL); \ 2867c478bd9Sstevel@tonic-gate ASSERT((bp)->av_back != NULL); \ 2877c478bd9Sstevel@tonic-gate ASSERT((bp)->av_forw != (bp)); \ 2887c478bd9Sstevel@tonic-gate ASSERT((bp)->av_back != (bp)); \ 2897c478bd9Sstevel@tonic-gate (bp)->av_back->av_forw = (bp)->av_forw; \ 2907c478bd9Sstevel@tonic-gate (bp)->av_forw->av_back = (bp)->av_back; \ 2917c478bd9Sstevel@tonic-gate (bp)->b_flags |= B_BUSY; \ 2927c478bd9Sstevel@tonic-gate (bp)->av_forw = (bp)->av_back = NULL; \ 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate #if defined(_KERNEL) 2967c478bd9Sstevel@tonic-gate /* 2977c478bd9Sstevel@tonic-gate * Macros to avoid the extra function call needed for binary compat. 2987c478bd9Sstevel@tonic-gate * 2997c478bd9Sstevel@tonic-gate * B_RETRYWRI is not included in clear_flags for BWRITE(), BWRITE2(), 3007c478bd9Sstevel@tonic-gate * or brwrite() so that the retry operation is persistent until the 3017c478bd9Sstevel@tonic-gate * write either succeeds or the buffer is bfinval()'d. 3027c478bd9Sstevel@tonic-gate * 3037c478bd9Sstevel@tonic-gate */ 3047c478bd9Sstevel@tonic-gate #define BREAD(dev, blkno, bsize) \ 3057c478bd9Sstevel@tonic-gate bread_common(/* ufsvfsp */ NULL, dev, blkno, bsize) 3067c478bd9Sstevel@tonic-gate 3077c478bd9Sstevel@tonic-gate #define BWRITE(bp) \ 3087c478bd9Sstevel@tonic-gate bwrite_common(/* ufsvfsp */ NULL, bp, /* force_wait */ 0, \ 3097c478bd9Sstevel@tonic-gate /* do_relse */ 1, \ 3107c478bd9Sstevel@tonic-gate /* clear_flags */ (B_READ | B_DONE | B_ERROR | B_DELWRI)) 3117c478bd9Sstevel@tonic-gate 3127c478bd9Sstevel@tonic-gate #define BWRITE2(bp) \ 3137c478bd9Sstevel@tonic-gate bwrite_common(/* ufsvfsp */ NULL, bp, /* force_wait */ 1, \ 3147c478bd9Sstevel@tonic-gate /* do_relse */ 0, \ 3157c478bd9Sstevel@tonic-gate /* clear_flags */ (B_READ | B_DONE | B_ERROR | B_DELWRI)) 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate #define GETBLK(dev, blkno, bsize) \ 3187c478bd9Sstevel@tonic-gate getblk_common(/* ufsvfsp */ NULL, dev, blkno, bsize, /* errflg */ 0) 3197c478bd9Sstevel@tonic-gate 3207c478bd9Sstevel@tonic-gate 3217c478bd9Sstevel@tonic-gate /* 3227c478bd9Sstevel@tonic-gate * Macros for new retry write interfaces. 3237c478bd9Sstevel@tonic-gate */ 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate /* 3267c478bd9Sstevel@tonic-gate * Same as bdwrite() except write failures are retried. 3277c478bd9Sstevel@tonic-gate */ 3287c478bd9Sstevel@tonic-gate #define bdrwrite(bp) { \ 3297c478bd9Sstevel@tonic-gate (bp)->b_flags |= B_RETRYWRI; \ 3307c478bd9Sstevel@tonic-gate bdwrite((bp)); \ 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate 3337c478bd9Sstevel@tonic-gate /* 3347c478bd9Sstevel@tonic-gate * Same as bwrite() except write failures are retried. 3357c478bd9Sstevel@tonic-gate */ 3367c478bd9Sstevel@tonic-gate #define brwrite(bp) { \ 3377c478bd9Sstevel@tonic-gate (bp)->b_flags |= B_RETRYWRI; \ 3387c478bd9Sstevel@tonic-gate bwrite_common((bp), /* force_wait */ 0, /* do_relse */ 1, \ 3397c478bd9Sstevel@tonic-gate /* clear_flags */ (B_READ | B_DONE | B_ERROR | B_DELWRI)); \ 3407c478bd9Sstevel@tonic-gate } 3417c478bd9Sstevel@tonic-gate 3427c478bd9Sstevel@tonic-gate extern struct hbuf *hbuf; /* Hash table */ 3437c478bd9Sstevel@tonic-gate extern struct dwbuf *dwbuf; /* delayed write hash table */ 3447c478bd9Sstevel@tonic-gate extern struct buf *buf; /* The buffer pool itself */ 3457c478bd9Sstevel@tonic-gate extern struct buf bfreelist; /* head of available list */ 3467c478bd9Sstevel@tonic-gate 3477c478bd9Sstevel@tonic-gate extern void (*bio_lufs_strategy)(void *, buf_t *); /* UFS Logging */ 3487c478bd9Sstevel@tonic-gate extern void (*bio_snapshot_strategy)(void *, buf_t *); /* UFS snapshots */ 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate int bcheck(dev_t, struct buf *); 3517c478bd9Sstevel@tonic-gate int iowait(struct buf *); 3527c478bd9Sstevel@tonic-gate int hash2ints(int x, int y); 3537c478bd9Sstevel@tonic-gate int bio_busy(int); 3547c478bd9Sstevel@tonic-gate int biowait(struct buf *); 3557c478bd9Sstevel@tonic-gate int biomodified(struct buf *); 3567c478bd9Sstevel@tonic-gate int geterror(struct buf *); 3577c478bd9Sstevel@tonic-gate void minphys(struct buf *); 3587c478bd9Sstevel@tonic-gate /* 3597c478bd9Sstevel@tonic-gate * ufsvfsp is declared as a void * to avoid having everyone that uses 3607c478bd9Sstevel@tonic-gate * this header file include sys/fs/ufs_inode.h. 3617c478bd9Sstevel@tonic-gate */ 3627c478bd9Sstevel@tonic-gate void bwrite_common(void *ufsvfsp, struct buf *, int force_wait, 3637c478bd9Sstevel@tonic-gate int do_relse, int clear_flags); 3647c478bd9Sstevel@tonic-gate void bwrite(struct buf *); 3657c478bd9Sstevel@tonic-gate void bwrite2(struct buf *); 3667c478bd9Sstevel@tonic-gate void bdwrite(struct buf *); 3677c478bd9Sstevel@tonic-gate void bawrite(struct buf *); 3687c478bd9Sstevel@tonic-gate void brelse(struct buf *); 3697c478bd9Sstevel@tonic-gate void iodone(struct buf *); 3707c478bd9Sstevel@tonic-gate void clrbuf(struct buf *); 3717c478bd9Sstevel@tonic-gate void bflush(dev_t); 3727c478bd9Sstevel@tonic-gate void blkflush(dev_t, daddr_t); 3737c478bd9Sstevel@tonic-gate void binval(dev_t); 3747c478bd9Sstevel@tonic-gate int bfinval(dev_t, int); 3757c478bd9Sstevel@tonic-gate void binit(void); 3767c478bd9Sstevel@tonic-gate void biodone(struct buf *); 3777c478bd9Sstevel@tonic-gate void bioinit(struct buf *); 3787c478bd9Sstevel@tonic-gate void biofini(struct buf *); 3797c478bd9Sstevel@tonic-gate void bp_mapin(struct buf *); 3807c478bd9Sstevel@tonic-gate void *bp_mapin_common(struct buf *, int); 3817c478bd9Sstevel@tonic-gate void bp_mapout(struct buf *); 38236945f79Smrj int bp_copyin(struct buf *, void *, offset_t, size_t); 38336945f79Smrj int bp_copyout(void *, struct buf *, offset_t, size_t); 3847c478bd9Sstevel@tonic-gate void bp_init(size_t, uint_t); 3857c478bd9Sstevel@tonic-gate int bp_color(struct buf *); 3867c478bd9Sstevel@tonic-gate void pageio_done(struct buf *); 3877c478bd9Sstevel@tonic-gate struct buf *bread(dev_t, daddr_t, long); 3887c478bd9Sstevel@tonic-gate struct buf *bread_common(void *, dev_t, daddr_t, long); 3897c478bd9Sstevel@tonic-gate struct buf *breada(dev_t, daddr_t, daddr_t, long); 3907c478bd9Sstevel@tonic-gate struct buf *getblk(dev_t, daddr_t, long); 3917c478bd9Sstevel@tonic-gate struct buf *getblk_common(void *, dev_t, daddr_t, long, int); 3927c478bd9Sstevel@tonic-gate struct buf *ngeteblk(long); 3937c478bd9Sstevel@tonic-gate struct buf *geteblk(void); 3947c478bd9Sstevel@tonic-gate struct buf *pageio_setup(struct page *, size_t, struct vnode *, int); 3957c478bd9Sstevel@tonic-gate void bioerror(struct buf *bp, int error); 3967c478bd9Sstevel@tonic-gate void bioreset(struct buf *bp); 3977c478bd9Sstevel@tonic-gate struct buf *bioclone(struct buf *, off_t, size_t, dev_t, daddr_t, 3987c478bd9Sstevel@tonic-gate int (*)(struct buf *), struct buf *, int); 3997c478bd9Sstevel@tonic-gate size_t biosize(void); 4007c478bd9Sstevel@tonic-gate #endif /* defined(_KERNEL) */ 4017c478bd9Sstevel@tonic-gate 4027c478bd9Sstevel@tonic-gate #ifdef __cplusplus 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate #endif 4057c478bd9Sstevel@tonic-gate 4067c478bd9Sstevel@tonic-gate #endif /* _SYS_BUF_H */ 407