diff options
author | Lukas Ertl <le@FreeBSD.org> | 2004-06-23 23:52:55 +0000 |
---|---|---|
committer | Lukas Ertl <le@FreeBSD.org> | 2004-06-23 23:52:55 +0000 |
commit | 3a1e11b485453996ee24a92a03ec0753ff6dfe5c (patch) | |
tree | 74cd4c748586cf1a9aebc23b58ba1c8d4c8be9d6 /sys/geom | |
parent | bdf8ab4692a4f24cc321f4876f4d0c8b39dff4c9 (diff) | |
download | src-3a1e11b485453996ee24a92a03ec0753ff6dfe5c.tar.gz src-3a1e11b485453996ee24a92a03ec0753ff6dfe5c.zip |
Add a function to clean up RAID5 packets and use it when I/O has
finished or when building the complete packet fails.
Notes
Notes:
svn path=/head/; revision=131000
Diffstat (limited to 'sys/geom')
-rw-r--r-- | sys/geom/vinum/geom_vinum_plex.c | 2 | ||||
-rw-r--r-- | sys/geom/vinum/geom_vinum_raid5.c | 33 | ||||
-rw-r--r-- | sys/geom/vinum/geom_vinum_raid5.h | 1 |
3 files changed, 24 insertions, 12 deletions
diff --git a/sys/geom/vinum/geom_vinum_plex.c b/sys/geom/vinum/geom_vinum_plex.c index 1887366f0f50..c993917a7da2 100644 --- a/sys/geom/vinum/geom_vinum_plex.c +++ b/sys/geom/vinum/geom_vinum_plex.c @@ -275,6 +275,8 @@ gv_plex_start(struct bio *bp) boff); if (err) { + if (p->org == GV_PLEX_RAID5) + gv_free_raid5_packet(wp); bp->bio_completed += bcount; if (bp->bio_error == 0) bp->bio_error = err; diff --git a/sys/geom/vinum/geom_vinum_raid5.c b/sys/geom/vinum/geom_vinum_raid5.c index 3fc59d08a3d1..55eb582e40bf 100644 --- a/sys/geom/vinum/geom_vinum_raid5.c +++ b/sys/geom/vinum/geom_vinum_raid5.c @@ -70,6 +70,26 @@ gv_new_raid5_packet(void) return (wp); } +void +gv_free_raid5_packet(struct gv_raid5_packet *wp) +{ + struct gv_raid5_bit *r, *r2; + + /* Remove all the bits from this work packet. */ + TAILQ_FOREACH_SAFE(r, &wp->bits, list, r2) { + TAILQ_REMOVE(&wp->bits, r, list); + if (r->malloc) + g_free(r->buf); + if (r->bio != NULL) + g_destroy_bio(r->bio); + g_free(r); + } + + if (wp->bufmalloc == 1) + g_free(wp->buf); + g_free(wp); +} + /* * Check if the stripe that the work packet wants is already being used by * some other work packet. @@ -140,9 +160,7 @@ gv_raid5_worker(void *arg) mtx_lock(&p->worklist_mtx); } TAILQ_REMOVE(&p->worklist, wp, list); - if (wp->bufmalloc == 1) - g_free(wp->buf); - g_free(wp); + gv_free_raid5_packet(wp); restart++; /*break;*/ } @@ -238,15 +256,6 @@ gv_raid5_done(struct bio *bp) break; } - g_destroy_bio(bp); - - if (rbp != NULL) { - if (rbp->malloc == 1) - g_free(rbp->buf); - TAILQ_REMOVE(&wp->bits, rbp, list); - g_free(rbp); - } - /* This request group is done. */ if (wp->active == 0) wp->state = FINISH; diff --git a/sys/geom/vinum/geom_vinum_raid5.h b/sys/geom/vinum/geom_vinum_raid5.h index c43cb101594c..454311fa4a53 100644 --- a/sys/geom/vinum/geom_vinum_raid5.h +++ b/sys/geom/vinum/geom_vinum_raid5.h @@ -85,6 +85,7 @@ struct gv_raid5_packet { 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 *); void gv_raid5_worker(void *); struct gv_raid5_packet *gv_new_raid5_packet(void); |