xref: /dragonfly/sys/dev/raid/vinum/request.h (revision 984263bc)
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