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