aboutsummaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorLukas Ertl <le@FreeBSD.org>2004-06-23 23:52:55 +0000
committerLukas Ertl <le@FreeBSD.org>2004-06-23 23:52:55 +0000
commit3a1e11b485453996ee24a92a03ec0753ff6dfe5c (patch)
tree74cd4c748586cf1a9aebc23b58ba1c8d4c8be9d6 /sys/geom
parentbdf8ab4692a4f24cc321f4876f4d0c8b39dff4c9 (diff)
downloadsrc-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.c2
-rw-r--r--sys/geom/vinum/geom_vinum_raid5.c33
-rw-r--r--sys/geom/vinum/geom_vinum_raid5.h1
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);