diff --git a/lib/activate/activate.c b/lib/activate/activate.c index 075eb71e4..253d1e7f5 100644 --- a/lib/activate/activate.c +++ b/lib/activate/activate.c @@ -15,16 +15,51 @@ static void _build_lv_name(char *buffer, size_t s, struct logical_volume *lv) snprintf(buffer, s, "%s_%s", lv->vg->name, lv->name); } +/* + * Creates a target for the next contiguous run of + * extents. + */ +static int _emit_target(struct dm_task *dmt, struct logical_volume *lv, + unsigned int *ple) +{ + char params[1024]; + unsigned int le = *ple; + uint64_t esize = lv->vg->extent_size; + int i, count = 0; + struct pe_specifier *pes, *first = NULL; + + for (i = le; i < lv->le_count; i++) { + pes = lv->map + i; + + if (!first) + first = pes; + + else if (first->pv != pes->pv || first->pe != pes->pe + 1) + break; /* no longer contig. */ + + count++; + } + + snprintf(params, sizeof(params), "%s %llu", + dev_name(first->pv->dev), + first->pv->pe_start + (esize * first->pe)); + + if (!dm_task_add_target(dmt, esize * le, esize * count, + "linear", params)) { + stack; + return 0; + } + + *ple = i; + return 1; +} + int lv_activate(struct logical_volume *lv) { int r = 0; - int i; + uint32_t le = 0; - uint64_t esize = lv->vg->extent_size; - uint64_t start = 0ull; - char params[1024]; char name[128]; - struct pe_specifier *pes; struct dm_task *dmt; if (!(dmt = dm_task_create(DM_DEVICE_CREATE))) { @@ -35,18 +70,15 @@ int lv_activate(struct logical_volume *lv) _build_lv_name(name, sizeof(name), lv); dm_task_set_name(dmt, name); - for (i = 0; i < lv->le_count; i++) { - pes = lv->map + i; - snprintf(params, sizeof(params), "%s %llu", - dev_name(pes->pv->dev), - pes->pv->pe_start + (esize * pes->pe)); - - if (!dm_task_add_target(dmt, start, esize, "linear", params)) { - stack; + /* + * Merge adjacent extents. + */ + while (le < lv->le_count) { + if (!_emit_target(dmt, lv, &le)) { + log_err("unable to activate logical volume '%s'", + lv->name); goto out; } - - start += esize; } if (!(r = dm_task_run(dmt))) diff --git a/lib/format1/disk-rep.h b/lib/format1/disk-rep.h index a6fd49d80..a7f3041dc 100644 --- a/lib/format1/disk-rep.h +++ b/lib/format1/disk-rep.h @@ -178,8 +178,8 @@ int calculate_extent_count(struct physical_volume *pv); * Low level io routines which read/write * disk_lists. */ -struct disk_list *read_pvd(struct device *dev, struct pool *mem, - const char *vg_name); +struct disk_list *read_disk(struct device *dev, struct pool *mem, + const char *vg_name); int read_pvs_in_vg(const char *vg_name, struct dev_filter *filter, struct pool *mem, struct list *results); diff --git a/lib/format1/import-export.c b/lib/format1/import-export.c index 853fb8f80..eb4cfce82 100644 --- a/lib/format1/import-export.c +++ b/lib/format1/import-export.c @@ -579,7 +579,7 @@ void export_pv_act(struct list *pvs) } } -int export_vg_number(struct list *pvs, const char *vg_name, +int export_vg_number(struct list *pvs, const char *vg_name, struct dev_filter *filter) { struct list *pvh;