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