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 #ifdef __cplusplus 31 extern "C" { 32 #endif 33 34 #include <vm/page.h> 35 #include <sys/buf.h> 36 37 typedef enum { 38 FDB_PAGEIO, /* fdbuffer is a page buffer */ 39 FDB_VADDR /* fdbuffer is a address buffer */ 40 } fdb_type_t; 41 42 #define FDB_READ 0x01 /* fdbuffer is readable */ 43 #define FDB_WRITE 0x02 /* fdbuffer is asked for write */ 44 #define FDB_DONE 0x04 /* fdbuffer buffer io done */ 45 #define FDB_ERROR 0x08 /* fdbuffer in error state */ 46 #define FDB_ASYNC 0x10 /* fdbuffer using async i/o requests */ 47 #define FDB_SYNC 0x20 /* fdbuffer using direct i/o requests */ 48 #define FDB_ICALLBACK 0x40 /* fdbuffer immediate call back */ 49 #define FDB_ZEROHOLE 0x80 /* fdbuffer auto-zero holes */ 50 51 typedef struct fdb_holes { 52 struct fdb_holes *next_hole; 53 u_offset_t off; /* start offset for this hole */ 54 size_t len; /* length of this hole */ 55 } fdb_holes_t; 56 57 struct fdbuffer; 58 59 typedef void (*fdb_iodone_t)(struct fdbuffer *fdbuf, void *kargp, buf_t *bp); 60 61 62 /* 63 * Implementation notes in the fdbuffer structure members: 64 * 65 * fd_state: The state variable carries four distinct types of information 66 * it could probably be a bit field as such. 67 * 68 * READ/WRITE: 69 * This information is stored in fdbuffer at the time the 70 * The buffer is created and is used for sanity check in 71 * subsequent calls to fdb_iosetup(). This information 72 * persists for the entire life of the buffer. 73 * 74 * [A]SYNC: 75 * The buffer can be either in sync or async mode. In 76 * async mode all calls are to be async and the i/o 77 * must take place for the entire range or the fdbuf 78 * i/o must be ended with a call to fdb_ioerrdone() 79 * In the async case the call back is made either 80 * for every i/o completed or only once at the end 81 * of i/o. This depends on how the call back function 82 * is registered. See fdb_set_iofunc(). The fdbuf has 83 * to be freed by the call back function. 84 * 85 * ZEROHOLE: 86 * This is the case the holes are to be zeroed. Note 87 * that we do not zero the holes when fdb_add_hole() is 88 * getting called. We leave the zeroing of the holes to 89 * when a list is requested or the buffer is freed. This 90 * so that we can avoid zeroing pages while holding ufs 91 * locks. 92 */ 93 94 95 typedef struct fdbuffer { 96 fdb_type_t fd_type; /* type of buffer */ 97 int fd_state; /* state of the fdbfer */ 98 size_t fd_len; /* length of this fdbuffer */ 99 size_t fd_iocount; /* total io acked, includes errors and holes */ 100 int fd_iodispatch; /* # of io's dispatched */ 101 int fd_err; /* last i/o error due from buf_t */ 102 ssize_t fd_resid; /* total len in error */ 103 104 buf_t *fd_parentbp; /* buf associated with parent buf */ 105 106 union { 107 page_t *pages; /* page list for FDPAGE_BUF */ 108 caddr_t addr; /* address for FDADDR_BUF */ 109 } fd_un; 110 111 fdb_holes_t *fd_holes; /* holes list if this fdbuffer has holes */ 112 113 page_t **fd_shadow; /* shadow pages used for direct i/o to uspace */ 114 struct proc *fd_procp; /* procp used in bp for direct i/o to uspace */ 115 116 /* 117 * Call this function when the I/O on the full range of fdbuffer 118 * is completed. The call is made only if the i/o requests 119 * are asynchronous. 120 */ 121 122 fdb_iodone_t fd_iofunc; 123 void *fd_iargp; /* iodone function argument to be passed */ 124 125 /* 126 * The mutex protects iodispatch, iocount, state, and resid 127 * flags and variables since they are examined and updated by 128 * async call backs. All other structure members are modified 129 * in a single threaded fashion and do not require a lock. 130 */ 131 kmutex_t fd_mutex; 132 133 } fdbuffer_t; 134 135 #define fd_pages fd_un.pages 136 #define fd_addr fd_un.addr 137 138 extern fdbuffer_t *fdb_page_create(page_t *pp, size_t len, int flag); 139 extern fdbuffer_t *fdb_addr_create(caddr_t addr, size_t len, int flag, 140 page_t **pplist, struct proc *procp); 141 142 extern void fdb_set_iofunc(fdbuffer_t *fdbuf, fdb_iodone_t iofunc, void *ioarg, 143 int flags); 144 extern fdb_holes_t *fdb_get_holes(fdbuffer_t *fdbuf); 145 extern int fdb_get_error(fdbuffer_t *fdbuf); 146 extern void fdb_free(fdbuffer_t *fdbuf); 147 /* 148 * Need to add: 149 * fdb_get_iolen 150 */ 151 extern void fdb_add_hole(fdbuffer_t *fdbuf, u_offset_t off, size_t len); 152 extern buf_t *fdb_iosetup(fdbuffer_t *fdbuf, u_offset_t off, size_t len, 153 struct vnode *vn, int flags); 154 extern int fdb_iodone(buf_t *bufp); 155 extern void fdb_ioerrdone(fdbuffer_t *fdbuf, int error); 156 extern void fdb_init(void); 157 158 #ifdef __cplusplus 159 } 160 #endif 161 162 #endif /* _SYS_FDBUFFER_H */ 163