summaryrefslogtreecommitdiffstats
path: root/sys/geom/vinum/geom_vinum_raid5.h
diff options
context:
space:
mode:
authorle <le@FreeBSD.org>2004-09-18 13:44:43 +0000
committerle <le@FreeBSD.org>2004-09-18 13:44:43 +0000
commit18ba8315a7f99725d24144b4ba8f020a09eb6c80 (patch)
treeb26a5245ec9f7555a82415414ac98257151bf50c /sys/geom/vinum/geom_vinum_raid5.h
parent1991acc23e3343dcdae467ab20ed1b0e729ea778 (diff)
downloadFreeBSD-src-18ba8315a7f99725d24144b4ba8f020a09eb6c80.zip
FreeBSD-src-18ba8315a7f99725d24144b4ba8f020a09eb6c80.tar.gz
Re-vamp how I/O is handled in volumes and plexes.
Analogous to the drive level, give each volume and plex a worker thread that picks up and processes incoming and completed BIOs. This should fix the data corruption issues that have come up a few weeks ago and improve performance, especially of RAID5 plexes. The volume level needs a little work, though.
Diffstat (limited to 'sys/geom/vinum/geom_vinum_raid5.h')
-rw-r--r--sys/geom/vinum/geom_vinum_raid5.h63
1 files changed, 21 insertions, 42 deletions
diff --git a/sys/geom/vinum/geom_vinum_raid5.h b/sys/geom/vinum/geom_vinum_raid5.h
index 454311f..8074f42 100644
--- a/sys/geom/vinum/geom_vinum_raid5.h
+++ b/sys/geom/vinum/geom_vinum_raid5.h
@@ -32,22 +32,23 @@
/*
* A single RAID5 request usually needs more than one I/O transaction,
* depending on the state of the associated subdisks and the direction of the
- * transaction (read or write). Every subrequest of a RAID5 request,
- * represented by a gv_raid_packet, is defined by a gv_raid5_bit.
+ * transaction (read or write).
*/
-/* A subrequest of a RAID5 read/write operation. */
-struct gv_raid5_bit {
- struct bio *bio; /* BIO of this subrequest. */
- caddr_t buf; /* Data buffer of this subrequest. */
- int malloc; /* Flag if data buffer was malloced. */
- struct g_consumer *consumer; /* Consumer to send the BIO to. */
- TAILQ_ENTRY(gv_raid5_bit) list; /* Entry in the list of this request. */
-};
+#define GV_ENQUEUE(bp, cbp, pbp) \
+ do { \
+ if (bp->bio_driver1 == NULL) { \
+ bp->bio_driver1 = cbp; \
+ } else { \
+ pbp = bp->bio_driver1; \
+ while (pbp->bio_caller1 != NULL) \
+ pbp = pbp->bio_caller1; \
+ pbp->bio_caller1 = cbp; \
+ } \
+ } while (0);
-/* Container for one or more gv_raid5_bits; represents a RAID5 I/O request. */
struct gv_raid5_packet {
- caddr_t buf; /* Data buffer of this RAID5 request. */
+ caddr_t data; /* Data buffer of this sub-request- */
off_t length; /* Size of data buffer. */
off_t lockbase; /* Deny access to our plex offset. */
off_t offset; /* The drive offset of the subdisk. */
@@ -56,39 +57,17 @@ struct gv_raid5_packet {
int rqcount; /* Count of subrequests. */
struct bio *bio; /* Pointer to the original bio. */
- caddr_t data; /* Pointer to the original data. */
-
- struct g_consumer *original; /* Consumer to the data stripe. */
- struct g_consumer *parity; /* Consumer to the parity stripe. */
-
- /* State of this RAID5 packet. */
- enum {
- SETUP, /* Newly created. */
- VALID, /* Ready for processing. */
- IO, /* Currently doing I/O. */
- FINISH /* Packet has finished. */
- } state;
-
- /* Type of this RAID5 transaction. */
- enum {
- JUNK, /* Newly created, not valid. */
- NORMAL, /* Normal read or write. */
- ISPARITY, /* Containing only parity data. */
- NOPARITY, /* Parity stripe not available. */
- DEGRADED, /* Data stripe not available. */
- COMBINED /* Data and parity stripes ok, others not. */
- } type;
+ struct bio *parity; /* The bio containing the parity data. */
+ struct bio *waiting; /* A bio that need to wait for other bios. */
- TAILQ_HEAD(,gv_raid5_bit) bits; /* List of subrequests. */
- TAILQ_ENTRY(gv_raid5_packet) list; /* Entry in plex's packet list. */
+ TAILQ_HEAD(,gv_bioq) bits; /* List of subrequests. */
+ TAILQ_ENTRY(gv_raid5_packet) list; /* Entry in plex's packet list. */
};
-int gv_build_raid5_req(struct gv_raid5_packet *, struct bio *, caddr_t,
- long, off_t);
-void gv_free_raid5_packet(struct gv_raid5_packet *);
-void gv_raid5_done(struct bio *);
+int gv_stripe_active(struct gv_plex *, struct bio *);
+int gv_build_raid5_req(struct gv_plex *, struct gv_raid5_packet *,
+ struct bio *, caddr_t, off_t, off_t);
void gv_raid5_worker(void *);
-struct gv_raid5_packet *gv_new_raid5_packet(void);
-struct gv_raid5_bit *gv_new_raid5_bit(void);
+void gv_plex_done(struct bio *);
#endif /* !_GEOM_VINUM_RAID5_H_ */
OpenPOWER on IntegriCloud