diff options
author | Lukas Ertl <le@FreeBSD.org> | 2004-09-18 13:44:43 +0000 |
---|---|---|
committer | Lukas Ertl <le@FreeBSD.org> | 2004-09-18 13:44:43 +0000 |
commit | 67e3ab6ee55dd554915413ed430780e4169df3fa (patch) | |
tree | b26a5245ec9f7555a82415414ac98257151bf50c /sys/geom/vinum/geom_vinum_raid5.h | |
parent | 54516c29e84f00963a79ba79d96c99c9ec2247e9 (diff) | |
download | src-67e3ab6ee55dd554915413ed430780e4169df3fa.tar.gz src-67e3ab6ee55dd554915413ed430780e4169df3fa.zip |
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.
Notes
Notes:
svn path=/head/; revision=135426
Diffstat (limited to 'sys/geom/vinum/geom_vinum_raid5.h')
-rw-r--r-- | sys/geom/vinum/geom_vinum_raid5.h | 63 |
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 454311fa4a53..8074f4273c10 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_ */ |