1 /*- 2 * Copyright (c) 1997, 1998 3 * Nan Yang Computer Services Limited. All rights reserved. 4 * 5 * This software is distributed under the so-called ``Berkeley 6 * License'': 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 3. All advertising materials mentioning features or use of this software 17 * must display the following acknowledgement: 18 * This product includes software developed by Nan Yang Computer 19 * Services Limited. 20 * 4. Neither the name of the Company nor the names of its contributors 21 * may be used to endorse or promote products derived from this software 22 * without specific prior written permission. 23 * 24 * This software is provided ``as is'', and any express or implied 25 * warranties, including, but not limited to, the implied warranties of 26 * merchantability and fitness for a particular purpose are disclaimed. 27 * In no event shall the company or contributors be liable for any 28 * direct, indirect, incidental, special, exemplary, or consequential 29 * damages (including, but not limited to, procurement of substitute 30 * goods or services; loss of use, data, or profits; or business 31 * interruption) however caused and on any theory of liability, whether 32 * in contract, strict liability, or tort (including negligence or 33 * otherwise) arising in any way out of the use of this software, even if 34 * advised of the possibility of such damage. 35 * 36 * $Id: request.h,v 1.19 2000/11/24 03:41:51 grog Exp grog $ 37 * $FreeBSD: src/sys/dev/vinum/request.h,v 1.17.2.1 2001/03/13 02:59:42 grog Exp $ 38 */ 39 40 /* Information needed to set up a transfer */ 41 42 enum xferinfo { 43 XFR_NORMAL_READ = 1, 44 XFR_NORMAL_WRITE = 2, /* write request in normal mode */ 45 XFR_RECOVERY_READ = 4, 46 XFR_DEGRADED_WRITE = 8, 47 XFR_PARITYLESS_WRITE = 0x10, 48 XFR_NO_PARITY_STRIPE = 0x20, /* parity stripe is not available */ 49 XFR_DATA_BLOCK = 0x40, /* data block in request */ 50 XFR_PARITY_BLOCK = 0x80, /* parity block in request */ 51 XFR_BAD_SUBDISK = 0x100, /* this subdisk is dead */ 52 XFR_MALLOCED = 0x200, /* this buffer is malloced */ 53 #if VINUMDEBUG 54 XFR_PHASE2 = 0x800, /* documentation only: 2nd phase write */ 55 #endif 56 XFR_REVIVECONFLICT = 0x1000, /* possible conflict with a revive operation */ 57 XFR_BUFLOCKED = 0x2000, /* BUF_LOCK performed on this buffer */ 58 /* operations that need a parity block */ 59 XFR_PARITYOP = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE), 60 /* operations that use the group parameters */ 61 XFR_GROUPOP = (XFR_DEGRADED_WRITE | XFR_RECOVERY_READ), 62 /* operations that that use the data parameters */ 63 XFR_DATAOP = (XFR_NORMAL_READ | XFR_NORMAL_WRITE | XFR_PARITYLESS_WRITE), 64 /* operations requiring read before write */ 65 XFR_RBW = (XFR_NORMAL_WRITE | XFR_DEGRADED_WRITE), 66 /* operations that need a malloced buffer */ 67 XFR_NEEDS_MALLOC = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE) 68 }; 69 70 /* 71 * Describe one low-level request, part of a 72 * high-level request. This is an extended 73 * struct buf buffer, and the first element 74 * *must* be a struct buf. We pass this 75 * structure to the I/O routines instead of a 76 * struct buf in order to be able to locate the 77 * high-level request when it completes. 78 * 79 * All offsets and lengths are in sectors. 80 */ 81 82 struct rqelement { 83 struct buf b; /* buf structure */ 84 struct rqgroup *rqg; /* pointer to our group */ 85 /* Information about the transfer */ 86 daddr_t sdoffset; /* offset in subdisk */ 87 int useroffset; /* offset in user buffer of normal data */ 88 /* 89 * dataoffset and datalen refer to "individual" data 90 * transfers which involve only this drive (normal read, 91 * parityless write) and also degraded write. 92 * 93 * groupoffset and grouplen refer to the other "group" 94 * operations (normal write, recovery read) which involve 95 * more than one drive. Both the offsets are relative to 96 * the start of the local buffer. 97 */ 98 int dataoffset; /* offset in buffer of the normal data */ 99 int groupoffset; /* offset in buffer of group data */ 100 short datalen; /* length of normal data (sectors) */ 101 short grouplen; /* length of group data (sectors) */ 102 short buflen; /* total buffer length to allocate */ 103 short flags; /* really enum xferinfo (see above) */ 104 /* Ways to find other components */ 105 short sdno; /* subdisk number */ 106 short driveno; /* drive number */ 107 }; 108 109 /* 110 * A group of requests built to satisfy an I/O 111 * transfer on a single plex. 112 */ 113 struct rqgroup { 114 struct rqgroup *next; /* pointer to next group */ 115 struct request *rq; /* pointer to the request */ 116 short count; /* number of requests in this group */ 117 short active; /* and number active */ 118 short plexno; /* index of plex */ 119 int badsdno; /* index of bad subdisk or -1 */ 120 enum xferinfo flags; /* description of transfer */ 121 struct rangelock *lock; /* lock for this transfer */ 122 daddr_t lockbase; /* and lock address */ 123 struct rqelement rqe[0]; /* and the elements of this request */ 124 }; 125 126 /* 127 * Describe one high-level request and the 128 * work we have to do to satisfy it. 129 */ 130 struct request { 131 struct buf *bp; /* pointer to the high-level request */ 132 enum xferinfo flags; 133 union { 134 int volno; /* volume index */ 135 int plexno; /* or plex index */ 136 } volplex; 137 int error; /* current error indication */ 138 int sdno; /* reviving subdisk (XFR_REVIVECONFLICT) */ 139 short isplex; /* set if this is a plex request */ 140 short active; /* number of subrequests still active */ 141 struct rqgroup *rqg; /* pointer to the first group of requests */ 142 struct rqgroup *lrqg; /* and to the last group of requests */ 143 struct request *next; /* link of waiting requests */ 144 }; 145 146 /* 147 * Extended buffer header for subdisk I/O. Includes 148 * a pointer to the user I/O request. 149 */ 150 struct sdbuf { 151 struct buf b; /* our buffer */ 152 struct buf *bp; /* and pointer to parent */ 153 short driveno; /* drive index */ 154 short sdno; /* and subdisk index */ 155 }; 156 157 /* 158 * Values returned by rqe and friends. Be careful 159 * with these: they are in order of increasing 160 * seriousness. Some routines check for 161 * > REQUEST_RECOVERED to indicate a failed request. XXX 162 */ 163 enum requeststatus { 164 REQUEST_OK, /* request built OK */ 165 REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */ 166 REQUEST_DEGRADED, /* parts of request failed */ 167 REQUEST_EOF, /* parts of request failed: outside plex */ 168 REQUEST_DOWN, /* all of request failed: subdisk(s) down */ 169 REQUEST_ENOMEM /* all of request failed: ran out of memory */ 170 }; 171 172 #ifdef VINUMDEBUG 173 /* Trace entry for request info (DEBUG_LASTREQS) */ 174 enum rqinfo_type { 175 loginfo_unused, /* never been used */ 176 loginfo_user_bp, /* this is the bp when strategy is called */ 177 loginfo_user_bpl, /* and this is the bp at launch time */ 178 loginfo_rqe, /* user RQE */ 179 loginfo_iodone, /* iodone */ 180 loginfo_raid5_data, /* write RAID-5 data block */ 181 loginfo_raid5_parity, /* write RAID-5 parity block */ 182 loginfo_sdio, /* subdisk I/O */ 183 loginfo_sdiol, /* subdisk I/O launch */ 184 loginfo_sdiodone, /* subdisk iodone */ 185 loginfo_lockwait, /* wait for range lock */ 186 loginfo_lock, /* lock range */ 187 loginfo_unlock, /* unlock range */ 188 }; 189 190 union rqinfou { /* info to pass to logrq */ 191 struct buf *bp; 192 struct rqelement *rqe; /* address of request, for correlation */ 193 struct rangelock *lockinfo; 194 }; 195 196 struct rqinfo { 197 enum rqinfo_type type; /* kind of event */ 198 struct timeval timestamp; /* time it happened */ 199 struct buf *bp; /* point to user buffer */ 200 int devmajor; /* major and minor device info */ 201 int devminor; 202 union { 203 struct buf b; /* yup, the *whole* buffer header */ 204 struct rqelement rqe; /* and the whole rqe */ 205 struct rangelock lockinfo; 206 } info; 207 }; 208 209 #define RQINFO_SIZE 128 /* number of info slots in buffer */ 210 211 void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp); 212 #endif 213 214 /* Structures for the daemon */ 215 216 /* types of request to the daemon */ 217 enum daemonrq { 218 daemonrq_none, /* dummy to catch bugs */ 219 daemonrq_ioerror, /* error occurred on I/O */ 220 daemonrq_saveconfig, /* save configuration */ 221 daemonrq_return, /* return to userland */ 222 daemonrq_ping, /* show sign of life */ 223 daemonrq_init, /* initialize a plex */ 224 daemonrq_revive, /* revive a subdisk */ 225 daemonrq_closedrive, /* close a drive */ 226 }; 227 228 /* info field for daemon requests */ 229 union daemoninfo { /* and the request information */ 230 struct request *rq; /* for daemonrq_ioerror */ 231 struct sd *sd; /* for daemonrq_revive */ 232 struct plex *plex; /* for daemonrq_init */ 233 struct drive *drive; /* for daemonrq_closedrive */ 234 int nothing; /* for passing NULL */ 235 }; 236 237 struct daemonq { 238 struct daemonq *next; /* pointer to next element in queue */ 239 enum daemonrq type; /* type of request */ 240 int privateinuse; /* private element, being used */ 241 union daemoninfo info; /* and the request information */ 242 }; 243 244 void queue_daemon_request(enum daemonrq type, union daemoninfo info); 245 246 extern int daemon_options; 247 248 enum daemon_option { 249 daemon_verbose = 1, /* talk about what we're doing */ 250 daemon_stopped = 2, 251 daemon_noupdate = 4, /* don't update the disk config, for recovery */ 252 }; 253 254 void freerq(struct request *rq); 255 void unlockrange(int plexno, struct rangelock *); 256 /* Local Variables: */ 257 /* fill-column: 50 */ 258 /* End: */ 259