2 * Copyright (c) 1997, 1998
3 * Nan Yang Computer Services Limited. All rights reserved.
5 * This software is distributed under the so-called ``Berkeley
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
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
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.
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.
37 /* Information needed to set up a transfer */
41 XFR_NORMAL_WRITE
= 2, /* write request in normal mode */
42 XFR_RECOVERY_READ
= 4,
43 XFR_DEGRADED_WRITE
= 8,
44 XFR_PARITYLESS_WRITE
= 0x10,
45 XFR_NO_PARITY_STRIPE
= 0x20, /* parity stripe is not available */
46 XFR_DATA_BLOCK
= 0x40, /* data block in request */
47 XFR_PARITY_BLOCK
= 0x80, /* parity block in request */
48 XFR_BAD_SUBDISK
= 0x100, /* this subdisk is dead */
49 XFR_MALLOCED
= 0x200, /* this buffer is malloced */
51 XFR_PHASE2
= 0x800, /* debug only: 2nd phase write */
53 XFR_REVIVECONFLICT
= 0x1000, /* possible conflict with a revive */
54 XFR_BUFLOCKED
= 0x2000, /* BUF_LOCK performed on this buffer */
57 * operations that need a parity block
59 XFR_PARITYOP
= (XFR_NORMAL_WRITE
| XFR_RECOVERY_READ
|
63 * operations that use the group parameters
65 XFR_GROUPOP
= (XFR_DEGRADED_WRITE
| XFR_RECOVERY_READ
),
68 * operations that that use the data parameters
70 XFR_DATAOP
= (XFR_NORMAL_READ
| XFR_NORMAL_WRITE
|
71 XFR_PARITYLESS_WRITE
),
74 * operations requiring read before write
76 XFR_RBW
= (XFR_NORMAL_WRITE
| XFR_DEGRADED_WRITE
),
79 * operations that need a malloced buffer
81 XFR_NEEDS_MALLOC
= (XFR_NORMAL_WRITE
| XFR_RECOVERY_READ
|
86 * Describe one low-level request, part of a
87 * high-level request. This is an extended
88 * struct buf buffer, and the first element
89 * *must* be a struct buf. We pass this
90 * structure to the I/O routines instead of a
91 * struct buf in order to be able to locate the
92 * high-level request when it completes.
94 * All offsets and lengths are in sectors.
97 struct buf b
; /* buf structure */
98 struct rqgroup
*rqg
; /* pointer to our group */
100 vinum_off_t sdoffset
; /* offset in subdisk */
101 int useroffset
; /* offset of data in user buffer */
104 * dataoffset and datalen refer to "individual" data
105 * transfers which involve only this drive (normal read,
106 * parityless write) and also degraded write.
108 * groupoffset and grouplen refer to the other "group"
109 * operations (normal write, recovery read) which involve
110 * more than one drive. Both the offsets are relative to
111 * the start of the local buffer.
113 int dataoffset
; /* offset of the normal data */
114 int groupoffset
; /* offset of group data */
115 short datalen
; /* length of normal data (sectors) */
116 short grouplen
; /* length of group data (sectors) */
117 short buflen
; /* total buffer length to allocate */
118 short flags
; /* really enum xferinfo (see above) */
121 * Ways to find other components
123 short sdno
; /* subdisk number */
124 short driveno
; /* drive number */
128 * A group of requests built to satisfy an I/O
129 * transfer on a single plex.
132 struct rqgroup
*next
; /* pointer to next group */
133 struct request
*rq
; /* pointer to the request */
134 short count
; /* number of requests in this group */
135 short active
; /* and number active */
136 short plexno
; /* index of plex */
137 int badsdno
; /* index of bad subdisk or -1 */
138 enum xferinfo flags
; /* description of transfer */
139 struct rangelock
*lock
; /* lock for this transfer */
140 vinum_off_t lockbase
; /* and lock address */
141 struct rqelement rqe
[0]; /* and the elements of this request */
145 * Describe one high-level request and the
146 * work we have to do to satisfy it.
149 struct bio
*bio
; /* pointer to the high-level request */
152 int volno
; /* volume index */
153 int plexno
; /* or plex index */
155 int error
; /* current error indication */
156 int sdno
; /* reviving subdisk */
157 /* (XFR_REVIVECONFLICT) */
158 short isplex
; /* set if this is a plex request */
159 short active
; /* number of subrequests still active */
160 struct rqgroup
*rqg
; /* ptr to the first group of requests */
161 struct rqgroup
*lrqg
; /* and to the last group of requests */
162 struct request
*next
; /* link of waiting requests */
166 * Extended buffer header for subdisk I/O. Includes
167 * a pointer to the user I/O request.
170 struct buf b
; /* our buffer */
171 struct bio
*bio
; /* and pointer to parent */
172 short driveno
; /* drive index */
173 short sdno
; /* and subdisk index */
177 * Values returned by rqe and friends. Be careful
178 * with these: they are in order of increasing
179 * seriousness. Some routines check for
180 * > REQUEST_RECOVERED to indicate a failed request. XXX
183 REQUEST_OK
, /* request built OK */
184 REQUEST_RECOVERED
, /* request OK, but involves RAID5 recovery */
185 REQUEST_DEGRADED
, /* parts of request failed */
186 REQUEST_EOF
, /* parts of request failed: outside plex */
187 REQUEST_DOWN
, /* all of request failed: subdisk(s) down */
188 REQUEST_ENOMEM
/* all of request failed: ran out of memory */
194 * Trace entry for request info (DEBUG_LASTREQS)
197 loginfo_unused
, /* never been used */
198 loginfo_user_bp
, /* this is the bp when strategy is called */
199 loginfo_user_bpl
, /* and this is the bp at launch time */
200 loginfo_rqe
, /* user RQE */
201 loginfo_iodone
, /* iodone */
202 loginfo_raid5_data
, /* write RAID-5 data block */
203 loginfo_raid5_parity
, /* write RAID-5 parity block */
204 loginfo_sdio
, /* subdisk I/O */
205 loginfo_sdiol
, /* subdisk I/O launch */
206 loginfo_sdiodone
, /* subdisk iodone */
207 loginfo_lockwait
, /* wait for range lock */
208 loginfo_lock
, /* lock range */
209 loginfo_unlock
, /* unlock range */
213 * Info to pass to logrq
217 struct rqelement
*rqe
; /* addr of request, for correlation */
218 struct rangelock
*lockinfo
;
222 enum rqinfo_type type
; /* kind of event */
223 struct timeval timestamp
; /* time it happened */
224 struct bio
*bio
; /* point to user buffer */
225 int devmajor
; /* major and minor device info */
228 struct buf b
; /* yup, the *whole* buffer header */
230 struct rqelement rqe
; /* and the whole rqe */
231 struct rangelock lockinfo
;
235 #define RQINFO_SIZE 128 /* number of info slots in buffer */
237 void logrq(enum rqinfo_type type
, union rqinfou info
, struct bio
*ubio
);
241 /* Structures for the daemon */
244 * Types of request to the daemon
247 daemonrq_none
, /* dummy to catch bugs */
248 daemonrq_ioerror
, /* error occurred on I/O */
249 daemonrq_saveconfig
, /* save configuration */
250 daemonrq_return
, /* return to userland */
251 daemonrq_ping
, /* show sign of life */
252 daemonrq_init
, /* initialize a plex */
253 daemonrq_revive
, /* revive a subdisk */
254 daemonrq_closedrive
, /* close a drive */
258 * Info field for daemon requests and the request information
261 struct request
*rq
; /* for daemonrq_ioerror */
262 struct sd
*sd
; /* for daemonrq_revive */
263 struct plex
*plex
; /* for daemonrq_init */
264 struct drive
*drive
; /* for daemonrq_closedrive */
265 int nothing
; /* for passing NULL */
269 struct daemonq
*next
; /* pointer to next element in queue */
270 enum daemonrq type
; /* type of request */
271 int privateinuse
; /* private element, being used */
272 union daemoninfo info
; /* and the request information */
275 void queue_daemon_request(enum daemonrq type
, union daemoninfo info
);
277 extern int daemon_options
;
280 daemon_verbose
= 1, /* talk about what we're doing */
282 daemon_noupdate
= 4, /* don't update the disk config, for recovery */
285 void freerq(struct request
*rq
);
286 void unlockrange(int plexno
, struct rangelock
*);