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.h272
1 files changed, 272 insertions, 0 deletions
diff --git a/sys/dev/vinum/request.h b/sys/dev/vinum/request.h
new file mode 100644
index 0000000..4e10748
--- /dev/null
+++ b/sys/dev/vinum/request.h
@@ -0,0 +1,272 @@
+/*-
+ * 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.21 2001/05/23 23:03:23 grog Exp grog $
+ * $FreeBSD$
+ */
+
+/* Information needed to set up a 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 */
+#ifdef VINUMDEBUG
+ XFR_PHASE2 = 0x800, /* documentation only: 2nd phase write */
+#endif
+ XFR_REVIVECONFLICT = 0x1000, /* possible conflict with a revive operation */
+ XFR_BUFLOCKED = 0x2000, /* BUF_LOCK performed on this buffer */
+ XFR_COPYBUF = 0x4000, /* data buffer was copied */
+ /* 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 order to be able to locate the
+ * high-level request when it completes.
+ *
+ * All offsets and lengths are in 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 which involve only this drive (normal read,
+ * parityless write) and also degraded write.
+ *
+ * groupoffset and grouplen refer to the other "group"
+ * operations (normal write, recovery read) which involve
+ * more than one drive. 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 an I/O
+ * transfer on a single plex.
+ */
+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 rangelock *lock; /* lock for this transfer */
+ daddr_t lockbase; /* and lock address */
+ 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 */
+ caddr_t save_data; /* for copied write buffers */
+ enum xferinfo flags;
+ union {
+ int volno; /* volume index */
+ int plexno; /* or plex index */
+ } volplex;
+ int error; /* current error indication */
+ int sdno; /* reviving subdisk (XFR_REVIVECONFLICT) */
+ 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 last 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 failed request. XXX
+ */
+enum requeststatus {
+ REQUEST_OK, /* request built OK */
+ REQUEST_RECOVERED, /* request OK, but involves RAID5 recovery */
+ REQUEST_DEGRADED, /* parts of request failed */
+ REQUEST_EOF, /* parts of request failed: outside plex */
+ REQUEST_DOWN, /* all of request failed: subdisk(s) down */
+ REQUEST_ENOMEM /* all of request failed: ran out of memory */
+};
+
+#ifdef VINUMDEBUG
+/* 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 */
+ loginfo_sdio, /* subdisk I/O */
+ loginfo_sdiol, /* subdisk I/O launch */
+ loginfo_sdiodone, /* subdisk iodone */
+ loginfo_lockwait, /* wait for range lock */
+ loginfo_lock, /* lock range */
+ loginfo_unlock, /* unlock range */
+};
+
+/*
+ * This is the rangelock structure with an added
+ * buffer pointer and plex number. We don't need
+ * the plex number for the locking protocol, but
+ * it does help a lot when logging.
+ */
+struct rangelockinfo {
+ daddr_t stripe; /* address + 1 of the range being locked */
+ struct buf *bp; /* user's buffer pointer */
+ int plexno;
+};
+
+union rqinfou { /* info to pass to logrq */
+ struct buf *bp;
+ struct rqelement *rqe; /* address of request, for correlation */
+ struct rangelockinfo *lockinfo;
+};
+
+struct rqinfo {
+ enum rqinfo_type type; /* kind of event */
+ struct timeval timestamp; /* time it happened */
+ struct buf *bp; /* point to user buffer */
+ int devmajor; /* major and minor device info */
+ int devminor;
+ union {
+ struct buf b; /* yup, the *whole* buffer header */
+ struct rqelement rqe; /* and the whole rqe */
+ struct rangelock lockinfo;
+ } info;
+};
+
+#define RQINFO_SIZE 128 /* number of info slots in buffer */
+
+void logrq(enum rqinfo_type type, union rqinfou info, struct buf *ubp);
+#endif
+
+/* Structures for the daemon */
+
+/* types of request to the daemon */
+enum daemonrq {
+ daemonrq_none, /* dummy to catch bugs */
+ daemonrq_ioerror, /* error occurred on I/O */
+ daemonrq_saveconfig, /* save configuration */
+ daemonrq_return, /* return to userland */
+ daemonrq_ping, /* show sign of life */
+ daemonrq_init, /* initialize a plex */
+ daemonrq_revive, /* revive a subdisk */
+ daemonrq_closedrive, /* close a drive */
+};
+
+/* info field for daemon requests */
+union daemoninfo { /* and the request information */
+ struct request *rq; /* for daemonrq_ioerror */
+ struct sd *sd; /* for daemonrq_revive */
+ struct plex *plex; /* for daemonrq_init */
+ struct drive *drive; /* for daemonrq_closedrive */
+ int nothing; /* for passing NULL */
+};
+
+struct daemonq {
+ struct daemonq *next; /* pointer to next element in queue */
+ enum daemonrq type; /* type of request */
+ int privateinuse; /* private element, being used */
+ union daemoninfo info; /* and the request information */
+};
+
+void queue_daemon_request(enum daemonrq type, union daemoninfo info);
+
+extern int daemon_options;
+
+enum daemon_option {
+ daemon_verbose = 1, /* talk about what we're doing */
+ daemon_stopped = 2,
+ daemon_noupdate = 4, /* don't update the disk config, for recovery */
+};
+
+void freerq(struct request *rq);
+void unlockrange(int plexno, struct rangelock *);
+/* Local Variables: */
+/* fill-column: 50 */
+/* End: */
OpenPOWER on IntegriCloud