Page MenuHomeFreeBSD

D6153.id15751.diff
No OneTemporary

D6153.id15751.diff

Index: sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
===================================================================
--- sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
+++ sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
@@ -325,38 +325,66 @@
(void) nvlist_lookup_uint64(list, ZPOOL_CONFIG_POOL_GUID, pguid);
}
+/*
+ * Issue one or more bios to the vdev in parallel
+ * cmds, datas, offsets, and sizes are arrays of length ncmds. Each IO
+ * operation is described by parallel entries from each array. There may be
+ * more bios actually issued than entries in the array
+ */
static int
-vdev_geom_io(struct g_consumer *cp, int cmd, void *data, off_t offset, off_t size)
+vdev_geom_io(struct g_consumer *cp, int *cmds, void **datas, off_t *offsets,
+ off_t *sizes, int ncmds)
{
- struct bio *bp;
+ struct bio **bios;
u_char *p;
- off_t off, maxio;
- int error;
-
- ASSERT((offset % cp->provider->sectorsize) == 0);
- ASSERT((size % cp->provider->sectorsize) == 0);
+ off_t off, maxio, s, end;
+ int error, i, n_bios, j;
+ size_t bios_size;
- bp = g_alloc_bio();
- off = offset;
- offset += size;
- p = data;
maxio = MAXPHYS - (MAXPHYS % cp->provider->sectorsize);
error = 0;
+ n_bios = 0;
+ j = 0;
- for (; off < offset; off += maxio, p += maxio, size -= maxio) {
- g_reset_bio(bp);
- bp->bio_cmd = cmd;
- bp->bio_done = NULL;
- bp->bio_offset = off;
- bp->bio_length = MIN(size, maxio);
- bp->bio_data = p;
- g_io_request(bp, cp);
- error = biowait(bp, "vdev_geom_io");
- if (error != 0)
- break;
+ /* How many bios are required for all commands ? */
+ for (i = 0; i < ncmds; i++)
+ n_bios += (sizes[i] + maxio - 1) / maxio;
+
+ /* Allocate memory for the bios */
+ bios_size = n_bios * sizeof(struct bio*);
+ bios = kmem_alloc(bios_size, KM_SLEEP);
+ bzero(bios, bios_size);
+
+ /* Prepare and issue all of the bios */
+ for (i = 0; i < ncmds; i++) {
+ off = offsets[i];
+ p = datas[i];
+ s = sizes[i];
+ end = off + s;
+ ASSERT((off % cp->provider->sectorsize) == 0);
+ ASSERT((s % cp->provider->sectorsize) == 0);
+
+ for (; off < end; off += maxio, p += maxio, s -= maxio) {
+ bios[j] = g_alloc_bio();
+ g_reset_bio(bios[j]);
+ bios[j]->bio_cmd = cmds[i];
+ bios[j]->bio_done = NULL;
+ bios[j]->bio_offset = off;
+ bios[j]->bio_length = MIN(s, maxio);
+ bios[j]->bio_data = p;
+ g_io_request(bios[j], cp);
+ j++;
+ }
}
+ ASSERT(j == n_bios);
+
+ /* Wait for all of the bios to complete, and clean them up */
+ for (j=0; j < n_bios; j++) {
+ error = biowait(bios[j], "vdev_geom_io") || error;
+ g_destroy_bio(bios[j]);
+ }
+ kmem_free(bios, bios_size);
- g_destroy_bio(bp);
return (error);
}
@@ -364,12 +392,14 @@
vdev_geom_read_config(struct g_consumer *cp, nvlist_t **config)
{
struct g_provider *pp;
- vdev_label_t *label;
+ vdev_phys_t *vdev_lists[VDEV_LABELS];
char *p, *buf;
size_t buflen;
- uint64_t psize;
- off_t offset, size;
- uint64_t state, txg;
+ uint64_t psize, state, txg;
+ off_t offsets[VDEV_LABELS];
+ off_t size;
+ off_t sizes[VDEV_LABELS];
+ int cmds[VDEV_LABELS];
int error, l, len;
g_topology_assert_not();
@@ -380,22 +410,31 @@
psize = pp->mediasize;
psize = P2ALIGN(psize, (uint64_t)sizeof(vdev_label_t));
- size = sizeof(*label) + pp->sectorsize -
- ((sizeof(*label) - 1) % pp->sectorsize) - 1;
+ size = sizeof(*vdev_lists[0]) + pp->sectorsize -
+ ((sizeof(*vdev_lists[0]) - 1) % pp->sectorsize) - 1;
- label = kmem_alloc(size, KM_SLEEP);
- buflen = sizeof(label->vl_vdev_phys.vp_nvlist);
+ buflen = sizeof(vdev_lists[0]->vp_nvlist);
*config = NULL;
+ /* Create all of the IO requests */
for (l = 0; l < VDEV_LABELS; l++) {
+ cmds[l] = BIO_READ;
+ vdev_lists[l] = kmem_alloc(size, KM_SLEEP);
+ offsets[l] = vdev_label_offset(psize, l, 0) + VDEV_SKIP_SIZE;
+ sizes[l] = size;
+ ASSERT(offsets[l] % pp->sectorsize == 0);
+ }
- offset = vdev_label_offset(psize, l, 0);
- if ((offset % pp->sectorsize) != 0)
- continue;
+ /* Issue the IO requests */
+ error = vdev_geom_io(cp, cmds, (void**)vdev_lists, offsets, sizes,
+ VDEV_LABELS);
- if (vdev_geom_io(cp, BIO_READ, label, offset, size) != 0)
+ /* Parse the labels */
+ for (l = 0; l < VDEV_LABELS; l++) {
+ if (error != 0)
continue;
- buf = label->vl_vdev_phys.vp_nvlist;
+
+ buf = vdev_lists[l]->vp_nvlist;
if (nvlist_unpack(buf, buflen, config, 0) != 0)
continue;
@@ -418,7 +457,10 @@
break;
}
- kmem_free(label, size);
+ /* Free the label storage */
+ for (l = 0; l < VDEV_LABELS; l++)
+ kmem_free(vdev_lists[l], size);
+
return (*config == NULL ? ENOENT : 0);
}

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 2, 6:39 AM (15 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28410454
Default Alt Text
D6153.id15751.diff (4 KB)

Event Timeline