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.22 2003/04/24 04:37:08 grog Exp $
37 * $FreeBSD$
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 #ifdef 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 XFR_COPYBUF = 0x4000, /* data buffer was copied */
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 struct timeval launchtime; /* time of launch, for info function */
109 };
110
111 /*
112 * A group of requests built to satisfy an I/O
113 * transfer on a single plex.
114 */
115 struct rqgroup {
116 struct rqgroup *next; /* pointer to next group */
117 struct request *rq; /* pointer to the request */
118 short count; /* number of requests in this group */
119 short active; /* and number active */
120 short plexno; /* index of plex */
121 int badsdno; /* index of bad subdisk or -1 */
122 enum xferinfo flags; /* description of transfer */
123 struct rangelock *lock; /* lock for this transfer */
124 daddr_t lockbase; /* and lock address */
125 struct rqelement rqe[0]; /* and the elements of this request */
126 };
127
128 /*
129 * Describe one high-level request and the
130 * work we have to do to satisfy it.
131 */
132 struct request {
133 struct buf *bp; /* pointer to the high-level request */
134 caddr_t save_data; /* for copied write buffers */
135 enum xferinfo flags;
136 union {
137 int volno; /* volume index */
138 int plexno; /* or plex index */
139 } volplex;
140 int error; /* current error indication */
141 int sdno; /* reviving subdisk (XFR_REVIVECONFLICT) */
142 short isplex; /* set if this is a plex request */
143 short active; /* number of subrequests still active */
144 struct rqgroup *rqg; /* pointer to the first group of requests */
145 struct rqgroup *lrqg; /* and to the last group of requests */
146 struct request *next; /* link of waiting requests */
147 };
148
149 /*
150 * Extended buffer header for subdisk I/O. Includes
151 * a pointer to the user I/O request.
152 */
153 struct sdbuf {
154 struct buf b; /* our buffer */
155 struct buf *bp; /* and pointer to parent */
156 short driveno; /* drive index */
157 short sdno; /* and subdisk index */
158 };
159
160 /*
161 * Values returned by rqe and friends. Be careful
162 * with these: they are in order of increasing
163 * seriousness. Some routines check for
164 * > REQUEST_RECOVERED to indicate a failed request. XXX
165 */
166 enum requeststatus {
167 REQUEST_OK, /* request built OK */
168 REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */
169 REQUEST_DEGRADED, /* parts of request failed */
170 REQUEST_EOF, /* parts of request failed: outside plex */
171 REQUEST_DOWN, /* all of request failed: subdisk(s) down */
172 REQUEST_ENOMEM /* all of request failed: ran out of memory */
173 };
174
175 #ifdef VINUMDEBUG
176 /* Trace entry for request info (DEBUG_LASTREQS) */
177 enum rqinfo_type {
178 loginfo_unused, /* never been used */
179 loginfo_user_bp, /* this is the bp when strategy is called */
180 loginfo_user_bpl, /* and this is the bp at launch time */
181 loginfo_rqe, /* user RQE */
182 loginfo_iodone, /* iodone */
183 loginfo_raid5_data, /* write RAID-5 data block */
184 loginfo_raid5_parity, /* write RAID-5 parity block */
185 loginfo_sdio, /* subdisk I/O */
186 loginfo_sdiol, /* subdisk I/O launch */
187 loginfo_sdiodone, /* subdisk iodone */
188 loginfo_lockwait, /* wait for range lock */
189 loginfo_lock, /* lock range */
190 loginfo_unlock, /* unlock range */
191 };
192
193 /*
194 * This is the rangelock structure with an added
195 * buffer pointer and plex number. We don't need
196 * the plex number for the locking protocol, but
197 * it does help a lot when logging.
198 */
199 struct rangelockinfo {
200 daddr_t stripe; /* address + 1 of the range being locked */
201 struct buf *bp; /* user's buffer pointer */
202 int plexno;
203 };
204
205 union rqinfou { /* info to pass to logrq */
206 struct buf *bp;
207 struct rqelement *rqe; /* address of request, for correlation */
208 struct rangelockinfo *lockinfo;
209 };
210
211 struct rqinfo {
212 enum rqinfo_type type; /* kind of event */
213 struct timeval timestamp; /* time it happened */
214 struct buf *bp; /* point to user buffer */
215 int devmajor; /* major and minor device info */
216 int devminor;
217 union {
218 struct buf b; /* yup, the *whole* buffer header */
219 struct rqelement rqe; /* and the whole rqe */
220 struct rangelock lockinfo;
221 } info;
222 };
223
224 #define RQINFO_SIZE 128 /* number of info slots in buffer */
225
226 void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp);
227 #endif
228
229 /* Structures for the daemon */
230
231 /* types of request to the daemon */
232 enum daemonrq {
233 daemonrq_none, /* dummy to catch bugs */
234 daemonrq_ioerror, /* error occurred on I/O */
235 daemonrq_saveconfig, /* save configuration */
236 daemonrq_return, /* return to userland */
237 daemonrq_ping, /* show sign of life */
238 daemonrq_init, /* initialize a plex */
239 daemonrq_revive, /* revive a subdisk */
240 daemonrq_closedrive, /* close a drive */
241 };
242
243 /* info field for daemon requests */
244 union daemoninfo { /* and the request information */
245 struct request *rq; /* for daemonrq_ioerror */
246 struct sd *sd; /* for daemonrq_revive */
247 struct plex *plex; /* for daemonrq_init */
248 struct drive *drive; /* for daemonrq_closedrive */
249 int nothing; /* for passing NULL */
250 };
251
252 struct daemonq {
253 struct daemonq *next; /* pointer to next element in queue */
254 enum daemonrq type; /* type of request */
255 int privateinuse; /* private element, being used */
256 union daemoninfo info; /* and the request information */
257 };
258
259 void queue_daemon_request(enum daemonrq type, union daemoninfo info);
260
261 extern int daemon_options;
262
263 enum daemon_option {
264 daemon_verbose = 1, /* talk about what we're doing */
265 daemon_stopped = 2,
266 daemon_noupdate = 4, /* don't update the disk config, for recovery */
267 };
268
269 void freerq(struct request *rq);
270 void unlockrange(int plexno, struct rangelock *);
271 /* Local Variables: */
272 /* fill-column: 50 */
273 /* End: */
Cache object: a08c874cd8ab0983e9ea9acca1b0d4fe
|