1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 1998 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #ifndef _SYS_FDBUFFER_H 28*0Sstevel@tonic-gate #define _SYS_FDBUFFER_H 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #ifdef __cplusplus 33*0Sstevel@tonic-gate extern "C" { 34*0Sstevel@tonic-gate #endif 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include <vm/page.h> 37*0Sstevel@tonic-gate #include <sys/buf.h> 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate typedef enum { 40*0Sstevel@tonic-gate FDB_PAGEIO, /* fdbuffer is a page buffer */ 41*0Sstevel@tonic-gate FDB_VADDR /* fdbuffer is a address buffer */ 42*0Sstevel@tonic-gate } fdb_type_t; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate #define FDB_READ 0x01 /* fdbuffer is readable */ 45*0Sstevel@tonic-gate #define FDB_WRITE 0x02 /* fdbuffer is asked for write */ 46*0Sstevel@tonic-gate #define FDB_DONE 0x04 /* fdbuffer buffer io done */ 47*0Sstevel@tonic-gate #define FDB_ERROR 0x08 /* fdbuffer in error state */ 48*0Sstevel@tonic-gate #define FDB_ASYNC 0x10 /* fdbuffer using async i/o requests */ 49*0Sstevel@tonic-gate #define FDB_SYNC 0x20 /* fdbuffer using direct i/o requests */ 50*0Sstevel@tonic-gate #define FDB_ICALLBACK 0x40 /* fdbuffer immediate call back */ 51*0Sstevel@tonic-gate #define FDB_ZEROHOLE 0x80 /* fdbuffer auto-zero holes */ 52*0Sstevel@tonic-gate 53*0Sstevel@tonic-gate typedef struct fdb_holes { 54*0Sstevel@tonic-gate struct fdb_holes *next_hole; 55*0Sstevel@tonic-gate u_offset_t off; /* start offset for this hole */ 56*0Sstevel@tonic-gate size_t len; /* length of this hole */ 57*0Sstevel@tonic-gate } fdb_holes_t; 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate struct fdbuffer; 60*0Sstevel@tonic-gate 61*0Sstevel@tonic-gate typedef void (*fdb_iodone_t)(struct fdbuffer *fdbuf, void *kargp, buf_t *bp); 62*0Sstevel@tonic-gate 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate /* 65*0Sstevel@tonic-gate * Implementation notes in the fdbuffer structure members: 66*0Sstevel@tonic-gate * 67*0Sstevel@tonic-gate * fd_state: The state variable carries four distinct types of information 68*0Sstevel@tonic-gate * it could probably be a bit field as such. 69*0Sstevel@tonic-gate * 70*0Sstevel@tonic-gate * READ/WRITE: 71*0Sstevel@tonic-gate * This information is stored in fdbuffer at the time the 72*0Sstevel@tonic-gate * The buffer is created and is used for sanity check in 73*0Sstevel@tonic-gate * subsequent calls to fdb_iosetup(). This information 74*0Sstevel@tonic-gate * persists for the entire life of the buffer. 75*0Sstevel@tonic-gate * 76*0Sstevel@tonic-gate * [A]SYNC: 77*0Sstevel@tonic-gate * The buffer can be either in sync or async mode. In 78*0Sstevel@tonic-gate * async mode all calls are to be async and the i/o 79*0Sstevel@tonic-gate * must take place for the entire range or the fdbuf 80*0Sstevel@tonic-gate * i/o must be ended with a call to fdb_ioerrdone() 81*0Sstevel@tonic-gate * In the async case the call back is made either 82*0Sstevel@tonic-gate * for every i/o completed or only once at the end 83*0Sstevel@tonic-gate * of i/o. This depends on how the call back function 84*0Sstevel@tonic-gate * is registered. See fdb_set_iofunc(). The fdbuf has 85*0Sstevel@tonic-gate * to be freed by the call back function. 86*0Sstevel@tonic-gate * 87*0Sstevel@tonic-gate * ZEROHOLE: 88*0Sstevel@tonic-gate * This is the case the holes are to be zeroed. Note 89*0Sstevel@tonic-gate * that we do not zero the holes when fdb_add_hole() is 90*0Sstevel@tonic-gate * getting called. We leave the zeroing of the holes to 91*0Sstevel@tonic-gate * when a list is requested or the buffer is freed. This 92*0Sstevel@tonic-gate * so that we can avoid zeroing pages while holding ufs 93*0Sstevel@tonic-gate * locks. 94*0Sstevel@tonic-gate */ 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate 97*0Sstevel@tonic-gate typedef struct fdbuffer { 98*0Sstevel@tonic-gate fdb_type_t fd_type; /* type of buffer */ 99*0Sstevel@tonic-gate int fd_state; /* state of the fdbfer */ 100*0Sstevel@tonic-gate size_t fd_len; /* length of this fdbuffer */ 101*0Sstevel@tonic-gate size_t fd_iocount; /* total io acked, includes errors and holes */ 102*0Sstevel@tonic-gate int fd_iodispatch; /* # of io's dispatched */ 103*0Sstevel@tonic-gate int fd_err; /* last i/o error due from buf_t */ 104*0Sstevel@tonic-gate ssize_t fd_resid; /* total len in error */ 105*0Sstevel@tonic-gate 106*0Sstevel@tonic-gate buf_t *fd_parentbp; /* buf associated with parent buf */ 107*0Sstevel@tonic-gate 108*0Sstevel@tonic-gate union { 109*0Sstevel@tonic-gate page_t *pages; /* page list for FDPAGE_BUF */ 110*0Sstevel@tonic-gate caddr_t addr; /* address for FDADDR_BUF */ 111*0Sstevel@tonic-gate } fd_un; 112*0Sstevel@tonic-gate 113*0Sstevel@tonic-gate fdb_holes_t *fd_holes; /* holes list if this fdbuffer has holes */ 114*0Sstevel@tonic-gate 115*0Sstevel@tonic-gate page_t **fd_shadow; /* shadow pages used for direct i/o to uspace */ 116*0Sstevel@tonic-gate struct proc *fd_procp; /* procp used in bp for direct i/o to uspace */ 117*0Sstevel@tonic-gate 118*0Sstevel@tonic-gate /* 119*0Sstevel@tonic-gate * Call this function when the I/O on the full range of fdbuffer 120*0Sstevel@tonic-gate * is completed. The call is made only if the i/o requests 121*0Sstevel@tonic-gate * are asynchronous. 122*0Sstevel@tonic-gate */ 123*0Sstevel@tonic-gate 124*0Sstevel@tonic-gate fdb_iodone_t fd_iofunc; 125*0Sstevel@tonic-gate void *fd_iargp; /* iodone function argument to be passed */ 126*0Sstevel@tonic-gate 127*0Sstevel@tonic-gate /* 128*0Sstevel@tonic-gate * The mutex protects iodispatch, iocount, state, and resid 129*0Sstevel@tonic-gate * flags and variables since they are examined and updated by 130*0Sstevel@tonic-gate * async call backs. All other structure members are modified 131*0Sstevel@tonic-gate * in a single threaded fashion and do not require a lock. 132*0Sstevel@tonic-gate */ 133*0Sstevel@tonic-gate kmutex_t fd_mutex; 134*0Sstevel@tonic-gate 135*0Sstevel@tonic-gate } fdbuffer_t; 136*0Sstevel@tonic-gate 137*0Sstevel@tonic-gate #define fd_pages fd_un.pages 138*0Sstevel@tonic-gate #define fd_addr fd_un.addr 139*0Sstevel@tonic-gate 140*0Sstevel@tonic-gate extern fdbuffer_t *fdb_page_create(page_t *pp, size_t len, int flag); 141*0Sstevel@tonic-gate extern fdbuffer_t *fdb_addr_create(caddr_t addr, size_t len, int flag, 142*0Sstevel@tonic-gate page_t **pplist, struct proc *procp); 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate extern void fdb_set_iofunc(fdbuffer_t *fdbuf, fdb_iodone_t iofunc, void *ioarg, 145*0Sstevel@tonic-gate int flags); 146*0Sstevel@tonic-gate extern fdb_holes_t *fdb_get_holes(fdbuffer_t *fdbuf); 147*0Sstevel@tonic-gate extern int fdb_get_error(fdbuffer_t *fdbuf); 148*0Sstevel@tonic-gate extern void fdb_free(fdbuffer_t *fdbuf); 149*0Sstevel@tonic-gate /* 150*0Sstevel@tonic-gate * Need to add: 151*0Sstevel@tonic-gate * fdb_get_iolen 152*0Sstevel@tonic-gate */ 153*0Sstevel@tonic-gate extern void fdb_add_hole(fdbuffer_t *fdbuf, u_offset_t off, size_t len); 154*0Sstevel@tonic-gate extern buf_t *fdb_iosetup(fdbuffer_t *fdbuf, u_offset_t off, size_t len, 155*0Sstevel@tonic-gate struct vnode *vn, int flags); 156*0Sstevel@tonic-gate extern void fdb_iodone(buf_t *bufp); 157*0Sstevel@tonic-gate extern void fdb_ioerrdone(fdbuffer_t *fdbuf, int error); 158*0Sstevel@tonic-gate extern void fdb_init(void); 159*0Sstevel@tonic-gate 160*0Sstevel@tonic-gate #ifdef __cplusplus 161*0Sstevel@tonic-gate } 162*0Sstevel@tonic-gate #endif 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate #endif /* _SYS_FDBUFFER_H */ 165