summaryrefslogtreecommitdiffstats
path: root/sys/dev/vinum/request.h
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/vinum/request.h')
-rw-r--r--sys/dev/vinum/request.h191
1 files changed, 191 insertions, 0 deletions
diff --git a/sys/dev/vinum/request.h b/sys/dev/vinum/request.h
new file mode 100644
index 0000000..81fafd2
--- /dev/null
+++ b/sys/dev/vinum/request.h
@@ -0,0 +1,191 @@
+/*-
+ * Copyright (c) 1997, 1998
+ * Nan Yang Computer Services Limited. All rights reserved.
+ *
+ * This software is distributed under the so-called ``Berkeley
+ * License'':
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Nan Yang Computer
+ * Services Limited.
+ * 4. Neither the name of the Company nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * This software is provided ``as is'', and any express or implied
+ * warranties, including, but not limited to, the implied warranties of
+ * merchantability and fitness for a particular purpose are disclaimed.
+ * In no event shall the company or contributors be liable for any
+ * direct, indirect, incidental, special, exemplary, or consequential
+ * damages (including, but not limited to, procurement of substitute
+ * goods or services; loss of use, data, or profits; or business
+ * interruption) however caused and on any theory of liability, whether
+ * in contract, strict liability, or tort (including negligence or
+ * otherwise) arising in any way out of the use of this software, even if
+ * advised of the possibility of such damage.
+ *
+ * $Id: request.h,v 1.2 1998/10/21 08:32:32 grog Exp $
+ */
+
+/* Information needed to set up a transfer */
+
+/* struct buf is surprisingly big (about 300
+ * bytes), and it's part of the request, so this
+ * value is really important. Most requests
+ * don't need more than 2 subrequests per
+ * plex. The table is automatically extended if
+ * this value is too small. */
+#define RQELTS 2 /* default of 2 requests per transfer */
+
+enum xferinfo {
+ XFR_NORMAL_READ = 1,
+ XFR_NORMAL_WRITE = 2, /* write request in normal mode */
+ XFR_RECOVERY_READ = 4,
+ XFR_DEGRADED_WRITE = 8,
+ XFR_PARITYLESS_WRITE = 0x10,
+ XFR_NO_PARITY_STRIPE = 0x20, /* parity stripe is not available */
+ XFR_DATA_BLOCK = 0x40, /* data block in request */
+ XFR_PARITY_BLOCK = 0x80, /* parity block in request */
+ XFR_BAD_SUBDISK = 0x100, /* this subdisk is dead */
+ XFR_MALLOCED = 0x200, /* this buffer is malloced */
+#if DEBUG
+ XFR_PHASE2 = 0x800, /* documentation only: 2nd phase write */
+#endif
+ XFR_REVIVECONFLICT = 0x1000, /* possible conflict with a revive operation */
+ /* operations that need a parity block */
+ XFR_PARITYOP = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE),
+ /* operations that use the group parameters */
+ XFR_GROUPOP = (XFR_DEGRADED_WRITE | XFR_RECOVERY_READ),
+ /* operations that that use the data parameters */
+ XFR_DATAOP = (XFR_NORMAL_READ | XFR_NORMAL_WRITE | XFR_PARITYLESS_WRITE),
+ /* operations requiring read before write */
+ XFR_RBW = (XFR_NORMAL_WRITE | XFR_DEGRADED_WRITE),
+ /* operations that need a malloced buffer */
+ XFR_NEEDS_MALLOC = (XFR_NORMAL_WRITE | XFR_RECOVERY_READ | XFR_DEGRADED_WRITE)
+};
+
+/* Describe one low-level request, part
+ * of a high-level request. This is an
+ * extended struct buf buffer, and the first
+ * element *must* be a struct buf. We pass this structure
+ * to the I/O routines instead of a struct buf in oder
+ * to be able to locate the high-level request when it
+ * completes.
+ *
+ * All offsets and lengths are in "blocks", i.e. sectors */
+struct rqelement {
+ struct buf b; /* buf structure */
+ struct rqgroup *rqg; /* pointer to our group */
+ /* Information about the transfer */
+ daddr_t sdoffset; /* offset in subdisk */
+ int useroffset; /* offset in user buffer of normal data */
+ /* dataoffset and datalen refer to "individual"
+ * data transfers (normal read, parityless write)
+ * and also degraded write.
+ *
+ * groupoffset and grouplen refer to the other
+ * "group" operations (normal write, recovery read)
+ * Both the offsets are relative to the start of the
+ * local buffer */
+ int dataoffset; /* offset in buffer of the normal data */
+ int groupoffset; /* offset in buffer of group data */
+ short datalen; /* length of normal data (sectors) */
+ short grouplen; /* length of group data (sectors) */
+ short buflen; /* total buffer length to allocate */
+ short flags; /* really enum xferinfo (see above) */
+ /* Ways to find other components */
+ short sdno; /* subdisk number */
+ short driveno; /* drive number */
+};
+
+/* A group of requests built to satisfy a certain
+ * component of a user request */
+struct rqgroup {
+ struct rqgroup *next; /* pointer to next group */
+ struct request *rq; /* pointer to the request */
+ short count; /* number of requests in this group */
+ short active; /* and number active */
+ short plexno; /* index of plex */
+ int badsdno; /* index of bad subdisk or -1 */
+ enum xferinfo flags; /* description of transfer */
+ struct rqelement rqe[0]; /* and the elements of this request */
+};
+
+/* Describe one high-level request and the
+ * work we have to do to satisfy it */
+struct request {
+ struct buf *bp; /* pointer to the high-level request */
+ int flags;
+ union {
+ int volno; /* volume index */
+ int plexno; /* or plex index */
+ } volplex;
+ int error; /* current error indication */
+ short isplex; /* set if this is a plex request */
+ short active; /* number of subrequests still active */
+ struct rqgroup *rqg; /* pointer to the first group of requests */
+ struct rqgroup *lrqg; /* and to the first group of requests */
+ struct request *next; /* link of waiting requests */
+};
+
+/* Extended buffer header for subdisk I/O. Includes
+ * a pointer to the user I/O request. */
+struct sdbuf {
+ struct buf b; /* our buffer */
+ struct buf *bp; /* and pointer to parent */
+ short driveno; /* drive index */
+ short sdno; /* and subdisk index */
+};
+
+/* Values returned by rqe and friends.
+ * Be careful with these: they are in order of increasing
+ * seriousness. Some routines check for > REQUEST_RECOVERED
+ * to indicate a completely failed request. */
+enum requeststatus {
+ REQUEST_OK, /* request built OK */
+ REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */
+ REQUEST_EOF, /* request failed: outside plex */
+ REQUEST_DOWN, /* request failed: subdisk down */
+ REQUEST_ENOMEM /* ran out of memory */
+};
+
+#ifdef DEBUG
+/* Trace entry for request info (DEBUG_LASTREQS) */
+enum rqinfo_type {
+ loginfo_unused, /* never been used */
+ loginfo_user_bp, /* this is the bp when strategy is called */
+ loginfo_user_bpl, /* and this is the bp at launch time */
+ loginfo_rqe, /* user RQE */
+ loginfo_iodone, /* iodone */
+ loginfo_raid5_data, /* write RAID-5 data block */
+ loginfo_raid5_parity /* write RAID-5 parity block */
+};
+
+union rqinfou { /* info to pass to logrq */
+ struct buf *bp;
+ struct rqelement *rqe; /* address of request, for correlation */
+};
+
+struct rqinfo {
+ enum rqinfo_type type; /* kind of event */
+ struct timeval timestamp; /* time it happened */
+ struct buf *bp; /* point to user buffer */
+ union {
+ struct buf b; /* yup, the *whole* buffer header */
+ struct rqelement rqe; /* and the whole rqe */
+ } info;
+};
+
+#define RQINFO_SIZE 64 /* number of info slots in buffer */
+
+void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp);
+#endif
OpenPOWER on IntegriCloud