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