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 * $DragonFly: src/sys/dev/raid/vinum/request.h,v 1.3 2006/02/17 19:18:06 dillon Exp $ 39 */ 40 41 /* Information needed to set up a transfer */ 42 43 enum xferinfo { 44 XFR_NORMAL_READ = 1, 45 XFR_NORMAL_WRITE = 2, /* write request in normal mode */ 46 XFR_RECOVERY_READ = 4, 47 XFR_DEGRADED_WRITE = 8, 48 XFR_PARITYLESS_WRITE = 0x10, 49 XFR_NO_PARITY_STRIPE = 0x20, /* parity stripe is not available */ 50 XFR_DATA_BLOCK = 0x40, /* data block in request */ 51 XFR_PARITY_BLOCK = 0x80, /* parity block in request */ 52 XFR_BAD_SUBDISK = 0x100, /* this subdisk is dead */ 53 XFR_MALLOCED = 0x200, /* this buffer is malloced */ 54 #if VINUMDEBUG 55 XFR_PHASE2 = 0x800, /* documentation only: 2nd phase write */ 56 #endif 57 XFR_REVIVECONFLICT = 0x1000, /* possible conflict with a revive operation */ 58 XFR_BUFLOCKED = 0x2000, /* BUF_LOCK performed on this buffer */ 59 /* operations that need a parity block */ 60 XFR_PARITYOP = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE), 61 /* operations that use the group parameters */ 62 XFR_GROUPOP = (XFR_DEGRADED_WRITE | XFR_RECOVERY_READ), 63 /* operations that that use the data parameters */ 64 XFR_DATAOP = (XFR_NORMAL_READ | XFR_NORMAL_WRITE | XFR_PARITYLESS_WRITE), 65 /* operations requiring read before write */ 66 XFR_RBW = (XFR_NORMAL_WRITE | XFR_DEGRADED_WRITE), 67 /* operations that need a malloced buffer */ 68 XFR_NEEDS_MALLOC = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE) 69 }; 70 71 /* 72 * Describe one low-level request, part of a 73 * high-level request. This is an extended 74 * struct buf buffer, and the first element 75 * *must* be a struct buf. We pass this 76 * structure to the I/O routines instead of a 77 * struct buf in order to be able to locate the 78 * high-level request when it completes. 79 * 80 * All offsets and lengths are in sectors. 81 */ 82 83 struct rqelement { 84 struct buf b; /* buf structure */ 85 struct rqgroup *rqg; /* pointer to our group */ 86 /* Information about the transfer */ 87 daddr_t sdoffset; /* offset in subdisk */ 88 int useroffset; /* offset in user buffer of normal data */ 89 /* 90 * dataoffset and datalen refer to "individual" data 91 * transfers which involve only this drive (normal read, 92 * parityless write) and also degraded write. 93 * 94 * groupoffset and grouplen refer to the other "group" 95 * operations (normal write, recovery read) which involve 96 * more than one drive. Both the offsets are relative to 97 * the start of the local buffer. 98 */ 99 int dataoffset; /* offset in buffer of the normal data */ 100 int groupoffset; /* offset in buffer of group data */ 101 short datalen; /* length of normal data (sectors) */ 102 short grouplen; /* length of group data (sectors) */ 103 short buflen; /* total buffer length to allocate */ 104 short flags; /* really enum xferinfo (see above) */ 105 /* Ways to find other components */ 106 short sdno; /* subdisk number */ 107 short driveno; /* drive number */ 108 }; 109 110 /* 111 * A group of requests built to satisfy an I/O 112 * transfer on a single plex. 113 */ 114 struct rqgroup { 115 struct rqgroup *next; /* pointer to next group */ 116 struct request *rq; /* pointer to the request */ 117 short count; /* number of requests in this group */ 118 short active; /* and number active */ 119 short plexno; /* index of plex */ 120 int badsdno; /* index of bad subdisk or -1 */ 121 enum xferinfo flags; /* description of transfer */ 122 struct rangelock *lock; /* lock for this transfer */ 123 daddr_t lockbase; /* and lock address */ 124 struct rqelement rqe[0]; /* and the elements of this request */ 125 }; 126 127 /* 128 * Describe one high-level request and the 129 * work we have to do to satisfy it. 130 */ 131 struct request { 132 struct bio *bio; /* pointer to the high-level request */ 133 enum xferinfo flags; 134 union { 135 int volno; /* volume index */ 136 int plexno; /* or plex index */ 137 } volplex; 138 int error; /* current error indication */ 139 int sdno; /* reviving subdisk (XFR_REVIVECONFLICT) */ 140 short isplex; /* set if this is a plex request */ 141 short active; /* number of subrequests still active */ 142 struct rqgroup *rqg; /* pointer to the first group of requests */ 143 struct rqgroup *lrqg; /* and to the last group of requests */ 144 struct request *next; /* link of waiting requests */ 145 }; 146 147 /* 148 * Extended buffer header for subdisk I/O. Includes 149 * a pointer to the user I/O request. 150 */ 151 struct sdbuf { 152 struct buf b; /* our buffer */ 153 struct bio *bio; /* and pointer to parent */ 154 short driveno; /* drive index */ 155 short sdno; /* and subdisk index */ 156 }; 157 158 /* 159 * Values returned by rqe and friends. Be careful 160 * with these: they are in order of increasing 161 * seriousness. Some routines check for 162 * > REQUEST_RECOVERED to indicate a failed request. XXX 163 */ 164 enum requeststatus { 165 REQUEST_OK, /* request built OK */ 166 REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */ 167 REQUEST_DEGRADED, /* parts of request failed */ 168 REQUEST_EOF, /* parts of request failed: outside plex */ 169 REQUEST_DOWN, /* all of request failed: subdisk(s) down */ 170 REQUEST_ENOMEM /* all of request failed: ran out of memory */ 171 }; 172 173 #ifdef VINUMDEBUG 174 /* Trace entry for request info (DEBUG_LASTREQS) */ 175 enum rqinfo_type { 176 loginfo_unused, /* never been used */ 177 loginfo_user_bp, /* this is the bp when strategy is called */ 178 loginfo_user_bpl, /* and this is the bp at launch time */ 179 loginfo_rqe, /* user RQE */ 180 loginfo_iodone, /* iodone */ 181 loginfo_raid5_data, /* write RAID-5 data block */ 182 loginfo_raid5_parity, /* write RAID-5 parity block */ 183 loginfo_sdio, /* subdisk I/O */ 184 loginfo_sdiol, /* subdisk I/O launch */ 185 loginfo_sdiodone, /* subdisk iodone */ 186 loginfo_lockwait, /* wait for range lock */ 187 loginfo_lock, /* lock range */ 188 loginfo_unlock, /* unlock range */ 189 }; 190 191 union rqinfou { /* info to pass to logrq */ 192 struct bio *bio; 193 struct rqelement *rqe; /* address of request, for correlation */ 194 struct rangelock *lockinfo; 195 }; 196 197 struct rqinfo { 198 enum rqinfo_type type; /* kind of event */ 199 struct timeval timestamp; /* time it happened */ 200 struct bio *bio; /* point to user buffer */ 201 int devmajor; /* major and minor device info */ 202 int devminor; 203 union { 204 struct buf b; /* yup, the *whole* buffer header */ 205 struct bio bio; 206 struct rqelement rqe; /* and the whole rqe */ 207 struct rangelock lockinfo; 208 } info; 209 }; 210 211 #define RQINFO_SIZE 128 /* number of info slots in buffer */ 212 213 void logrq(enum rqinfo_type type, union rqinfou info, struct bio *ubio); 214 #endif 215 216 /* Structures for the daemon */ 217 218 /* types of request to the daemon */ 219 enum daemonrq { 220 daemonrq_none, /* dummy to catch bugs */ 221 daemonrq_ioerror, /* error occurred on I/O */ 222 daemonrq_saveconfig, /* save configuration */ 223 daemonrq_return, /* return to userland */ 224 daemonrq_ping, /* show sign of life */ 225 daemonrq_init, /* initialize a plex */ 226 daemonrq_revive, /* revive a subdisk */ 227 daemonrq_closedrive, /* close a drive */ 228 }; 229 230 /* info field for daemon requests */ 231 union daemoninfo { /* and the request information */ 232 struct request *rq; /* for daemonrq_ioerror */ 233 struct sd *sd; /* for daemonrq_revive */ 234 struct plex *plex; /* for daemonrq_init */ 235 struct drive *drive; /* for daemonrq_closedrive */ 236 int nothing; /* for passing NULL */ 237 }; 238 239 struct daemonq { 240 struct daemonq *next; /* pointer to next element in queue */ 241 enum daemonrq type; /* type of request */ 242 int privateinuse; /* private element, being used */ 243 union daemoninfo info; /* and the request information */ 244 }; 245 246 void queue_daemon_request(enum daemonrq type, union daemoninfo info); 247 248 extern int daemon_options; 249 250 enum daemon_option { 251 daemon_verbose = 1, /* talk about what we're doing */ 252 daemon_stopped = 2, 253 daemon_noupdate = 4, /* don't update the disk config, for recovery */ 254 }; 255 256 void freerq(struct request *rq); 257 void unlockrange(int plexno, struct rangelock *); 258 /* Local Variables: */ 259 /* fill-column: 50 */ 260 /* End: */ 261