summaryrefslogtreecommitdiff
path: root/sys/geom
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2014-05-08 12:28:24 +0000
committerAlexander Motin <mav@FreeBSD.org>2014-05-08 12:28:24 +0000
commit9c3ac0d52ac0556276fa6eef1f56ada41a3f0b34 (patch)
tree8001244d067c1efaddd4dbac2f44bfe42836c83b /sys/geom
parent49813cd3bbf6945f40750f654dd1a29a74fbc915 (diff)
downloadsrc-test2-9c3ac0d52ac0556276fa6eef1f56ada41a3f0b34.tar.gz
src-test2-9c3ac0d52ac0556276fa6eef1f56ada41a3f0b34.zip
Notes
Diffstat (limited to 'sys/geom')
-rw-r--r--sys/geom/raid/g_raid.c22
-rw-r--r--sys/geom/raid/g_raid.h1
-rw-r--r--sys/geom/raid/tr_concat.c27
-rw-r--r--sys/geom/raid/tr_raid0.c27
-rw-r--r--sys/geom/raid/tr_raid1.c12
-rw-r--r--sys/geom/raid/tr_raid1e.c53
-rw-r--r--sys/geom/raid/tr_raid5.c9
7 files changed, 90 insertions, 61 deletions
diff --git a/sys/geom/raid/g_raid.c b/sys/geom/raid/g_raid.c
index 41a1f9668cb7..9933cf1f8d7b 100644
--- a/sys/geom/raid/g_raid.c
+++ b/sys/geom/raid/g_raid.c
@@ -993,20 +993,15 @@ g_raid_tr_flush_common(struct g_raid_tr_object *tr, struct bio *bp)
cbp->bio_caller1 = sd;
bioq_insert_tail(&queue, cbp);
}
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
@@ -1639,11 +1634,13 @@ static void
g_raid_launch_provider(struct g_raid_volume *vol)
{
struct g_raid_disk *disk;
+ struct g_raid_subdisk *sd;
struct g_raid_softc *sc;
struct g_provider *pp;
char name[G_RAID_MAX_VOLUMENAME];
char announce_buf[80], buf1[32];
off_t off;
+ int i;
sc = vol->v_softc;
sx_assert(&sc->sc_lock, SX_LOCKED);
@@ -1673,6 +1670,17 @@ g_raid_launch_provider(struct g_raid_volume *vol)
}
pp = g_new_providerf(sc->sc_geom, "%s", name);
+ if (vol->v_tr->tro_class->trc_accept_unmapped) {
+ pp->flags |= G_PF_ACCEPT_UNMAPPED;
+ for (i = 0; i < vol->v_disks_count; i++) {
+ sd = &vol->v_subdisks[i];
+ if (sd->sd_state == G_RAID_SUBDISK_S_NONE)
+ continue;
+ if ((sd->sd_disk->d_consumer->provider->flags &
+ G_PF_ACCEPT_UNMAPPED) == 0)
+ pp->flags &= ~G_PF_ACCEPT_UNMAPPED;
+ }
+ }
pp->private = vol;
pp->mediasize = vol->v_mediasize;
pp->sectorsize = vol->v_sectorsize;
diff --git a/sys/geom/raid/g_raid.h b/sys/geom/raid/g_raid.h
index 993b1000b5fe..8a96fa9f4698 100644
--- a/sys/geom/raid/g_raid.h
+++ b/sys/geom/raid/g_raid.h
@@ -376,6 +376,7 @@ struct g_raid_tr_class {
KOBJ_CLASS_FIELDS;
int trc_enable;
int trc_priority;
+ int trc_accept_unmapped;
LIST_ENTRY(g_raid_tr_class) trc_list;
};
diff --git a/sys/geom/raid/tr_concat.c b/sys/geom/raid/tr_concat.c
index 60db472fc5aa..44951d444785 100644
--- a/sys/geom/raid/tr_concat.c
+++ b/sys/geom/raid/tr_concat.c
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_concat_class = {
g_raid_tr_concat_methods,
sizeof(struct g_raid_tr_concat_object),
.trc_enable = 1,
- .trc_priority = 50
+ .trc_priority = 50,
+ .trc_accept_unmapped = 1
};
static int
@@ -227,7 +228,10 @@ g_raid_tr_iostart_concat(struct g_raid_tr_object *tr, struct bio *bp)
offset = bp->bio_offset;
remain = bp->bio_length;
- addr = bp->bio_data;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+ addr = NULL;
+ else
+ addr = bp->bio_data;
no = 0;
while (no < vol->v_disks_count &&
offset >= vol->v_subdisks[no].sd_size) {
@@ -244,8 +248,16 @@ g_raid_tr_iostart_concat(struct g_raid_tr_object *tr, struct bio *bp)
if (cbp == NULL)
goto failure;
cbp->bio_offset = offset;
- cbp->bio_data = addr;
cbp->bio_length = length;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+ bp->bio_cmd != BIO_DELETE) {
+ cbp->bio_ma_offset += (uintptr_t)addr;
+ cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+ cbp->bio_ma_offset %= PAGE_SIZE;
+ cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+ cbp->bio_length) / PAGE_SIZE;
+ } else
+ cbp->bio_data = addr;
cbp->bio_caller1 = sd;
bioq_insert_tail(&queue, cbp);
remain -= length;
@@ -257,20 +269,15 @@ g_raid_tr_iostart_concat(struct g_raid_tr_object *tr, struct bio *bp)
("Request ends after volume end (%ju, %ju)",
bp->bio_offset, bp->bio_length));
} while (remain > 0);
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
diff --git a/sys/geom/raid/tr_raid0.c b/sys/geom/raid/tr_raid0.c
index 7873be82e618..40d35fdbbad8 100644
--- a/sys/geom/raid/tr_raid0.c
+++ b/sys/geom/raid/tr_raid0.c
@@ -74,7 +74,8 @@ static struct g_raid_tr_class g_raid_tr_raid0_class = {
g_raid_tr_raid0_methods,
sizeof(struct g_raid_tr_raid0_object),
.trc_enable = 1,
- .trc_priority = 100
+ .trc_priority = 100,
+ .trc_accept_unmapped = 1
};
static int
@@ -204,7 +205,10 @@ g_raid_tr_iostart_raid0(struct g_raid_tr_object *tr, struct bio *bp)
g_raid_tr_flush_common(tr, bp);
return;
}
- addr = bp->bio_data;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+ addr = NULL;
+ else
+ addr = bp->bio_data;
strip_size = vol->v_strip_size;
/* Stripe number. */
@@ -225,8 +229,16 @@ g_raid_tr_iostart_raid0(struct g_raid_tr_object *tr, struct bio *bp)
if (cbp == NULL)
goto failure;
cbp->bio_offset = offset + start;
- cbp->bio_data = addr;
cbp->bio_length = length;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+ bp->bio_cmd != BIO_DELETE) {
+ cbp->bio_ma_offset += (uintptr_t)addr;
+ cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+ cbp->bio_ma_offset %= PAGE_SIZE;
+ cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+ cbp->bio_length) / PAGE_SIZE;
+ } else
+ cbp->bio_data = addr;
cbp->bio_caller1 = &vol->v_subdisks[no];
bioq_insert_tail(&queue, cbp);
if (++no >= vol->v_disks_count) {
@@ -238,20 +250,15 @@ g_raid_tr_iostart_raid0(struct g_raid_tr_object *tr, struct bio *bp)
addr += length;
start = 0;
} while (remain > 0);
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
diff --git a/sys/geom/raid/tr_raid1.c b/sys/geom/raid/tr_raid1.c
index 4465e328789c..833655bb854f 100644
--- a/sys/geom/raid/tr_raid1.c
+++ b/sys/geom/raid/tr_raid1.c
@@ -130,7 +130,8 @@ static struct g_raid_tr_class g_raid_tr_raid1_class = {
g_raid_tr_raid1_methods,
sizeof(struct g_raid_tr_raid1_object),
.trc_enable = 1,
- .trc_priority = 100
+ .trc_priority = 100,
+ .trc_accept_unmapped = 1
};
static void g_raid_tr_raid1_rebuild_abort(struct g_raid_tr_object *tr);
@@ -594,20 +595,15 @@ g_raid_tr_iostart_raid1_write(struct g_raid_tr_object *tr, struct bio *bp)
cbp->bio_caller1 = sd;
bioq_insert_tail(&queue, cbp);
}
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
diff --git a/sys/geom/raid/tr_raid1e.c b/sys/geom/raid/tr_raid1e.c
index 679b7669b6ed..d283606b59c5 100644
--- a/sys/geom/raid/tr_raid1e.c
+++ b/sys/geom/raid/tr_raid1e.c
@@ -134,7 +134,8 @@ static struct g_raid_tr_class g_raid_tr_raid1e_class = {
g_raid_tr_raid1e_methods,
sizeof(struct g_raid_tr_raid1e_object),
.trc_enable = 1,
- .trc_priority = 200
+ .trc_priority = 200,
+ .trc_accept_unmapped = 1
};
static void g_raid_tr_raid1e_rebuild_abort(struct g_raid_tr_object *tr);
@@ -701,7 +702,10 @@ g_raid_tr_iostart_raid1e_read(struct g_raid_tr_object *tr, struct bio *bp)
int best;
vol = tr->tro_volume;
- addr = bp->bio_data;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+ addr = NULL;
+ else
+ addr = bp->bio_data;
strip_size = vol->v_strip_size;
V2P(vol, bp->bio_offset, &no, &offset, &start);
remain = bp->bio_length;
@@ -721,8 +725,15 @@ g_raid_tr_iostart_raid1e_read(struct g_raid_tr_object *tr, struct bio *bp)
if (cbp == NULL)
goto failure;
cbp->bio_offset = offset + start;
- cbp->bio_data = addr;
cbp->bio_length = length;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0) {
+ cbp->bio_ma_offset += (uintptr_t)addr;
+ cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+ cbp->bio_ma_offset %= PAGE_SIZE;
+ cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+ cbp->bio_length) / PAGE_SIZE;
+ } else
+ cbp->bio_data = addr;
cbp->bio_caller1 = &vol->v_subdisks[no];
bioq_insert_tail(&queue, cbp);
no += N - best;
@@ -734,20 +745,15 @@ g_raid_tr_iostart_raid1e_read(struct g_raid_tr_object *tr, struct bio *bp)
addr += length;
start = 0;
}
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
@@ -766,7 +772,10 @@ g_raid_tr_iostart_raid1e_write(struct g_raid_tr_object *tr, struct bio *bp)
int i;
vol = tr->tro_volume;
- addr = bp->bio_data;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0)
+ addr = NULL;
+ else
+ addr = bp->bio_data;
strip_size = vol->v_strip_size;
V2P(vol, bp->bio_offset, &no, &offset, &start);
remain = bp->bio_length;
@@ -791,8 +800,16 @@ g_raid_tr_iostart_raid1e_write(struct g_raid_tr_object *tr, struct bio *bp)
if (cbp == NULL)
goto failure;
cbp->bio_offset = offset + start;
- cbp->bio_data = addr;
cbp->bio_length = length;
+ if ((bp->bio_flags & BIO_UNMAPPED) != 0 &&
+ bp->bio_cmd != BIO_DELETE) {
+ cbp->bio_ma_offset += (uintptr_t)addr;
+ cbp->bio_ma += cbp->bio_ma_offset / PAGE_SIZE;
+ cbp->bio_ma_offset %= PAGE_SIZE;
+ cbp->bio_ma_n = round_page(cbp->bio_ma_offset +
+ cbp->bio_length) / PAGE_SIZE;
+ } else
+ cbp->bio_data = addr;
cbp->bio_caller1 = sd;
bioq_insert_tail(&queue, cbp);
nextdisk:
@@ -806,20 +823,15 @@ nextdisk:
addr += length;
start = 0;
}
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);
@@ -1030,6 +1042,9 @@ rebuild_round_done:
cbp->bio_offset = offset + start;
cbp->bio_length = bp->bio_length;
cbp->bio_data = bp->bio_data;
+ cbp->bio_ma = bp->bio_ma;
+ cbp->bio_ma_offset = bp->bio_ma_offset;
+ cbp->bio_ma_n = bp->bio_ma_n;
g_destroy_bio(bp);
nsd = &vol->v_subdisks[disk];
G_RAID_LOGREQ(2, cbp, "Retrying read from %d",
diff --git a/sys/geom/raid/tr_raid5.c b/sys/geom/raid/tr_raid5.c
index 6e54d168ceaf..c90845e51376 100644
--- a/sys/geom/raid/tr_raid5.c
+++ b/sys/geom/raid/tr_raid5.c
@@ -324,20 +324,15 @@ g_raid_tr_iostart_raid5_read(struct g_raid_tr_object *tr, struct bio *bp)
addr += length;
start = 0;
} while (remain > 0);
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL) {
sd = cbp->bio_caller1;
cbp->bio_caller1 = NULL;
g_raid_subdisk_iostart(sd, cbp);
}
return;
failure:
- for (cbp = bioq_first(&queue); cbp != NULL;
- cbp = bioq_first(&queue)) {
- bioq_remove(&queue, cbp);
+ while ((cbp = bioq_takefirst(&queue)) != NULL)
g_destroy_bio(cbp);
- }
if (bp->bio_error == 0)
bp->bio_error = ENOMEM;
g_raid_iodone(bp, bp->bio_error);