Version 2.02.00 -
===================================
+ Split lv_segment_area from lv_segment to permit extension.
Replacement deactivation code using libdevmapper dependency tree.
Simplify dev_manager_info().
Attempt to load missing targets using modprobe.
uint32_t extents_copied)
{
struct lv_segment *seg;
- uint32_t sz = sizeof(*seg) + (area_count * sizeof(seg->area[0]));
+ uint32_t areas_sz = area_count * sizeof(*seg->areas);
- if (!(seg = dm_pool_zalloc(mem, sz))) {
+ if (!(seg = dm_pool_zalloc(mem, sizeof(*seg)))) {
+ stack;
+ return NULL;
+ }
+
+ if (!(seg->areas = dm_pool_zalloc(mem, areas_sz))) {
+ dm_pool_free(mem, seg);
stack;
return NULL;
}
int set_lv_segment_area_pv(struct lv_segment *seg, uint32_t area_num,
struct physical_volume *pv, uint32_t pe)
{
- seg->area[area_num].type = AREA_PV;
+ seg->areas[area_num].type = AREA_PV;
if (!(seg_pvseg(seg, area_num) =
assign_peg_to_lvseg(pv, pe, seg->area_len, seg, area_num))) {
struct logical_volume *lv, uint32_t le,
uint32_t flags)
{
- seg->area[area_num].type = AREA_LV;
+ seg->areas[area_num].type = AREA_LV;
seg_lv(seg, area_num) = lv;
seg_le(seg, area_num) = le;
lv->status |= flags;
}
+/*
+ * Prepare for adding parallel areas to an existing segment.
+ */
+static int _lv_segment_add_areas(struct logical_volume *lv,
+ struct lv_segment *seg,
+ uint32_t new_area_count)
+{
+ struct lv_segment_area *newareas;
+ uint32_t areas_sz = new_area_count * sizeof(*newareas);
+
+ if (!(newareas = dm_pool_zalloc(lv->vg->cmd->mem, areas_sz))) {
+ stack;
+ return 0;
+ }
+
+ memcpy(newareas, seg->areas, seg->area_count * sizeof(*seg->areas));
+
+ seg->areas = newareas;
+ seg->area_count = new_area_count;
+
+ return 1;
+}
+
/*
* Reduce the size of an lv_segment. New size can be zero.
*/
struct list tags;
};
+/* There will be one area for each stripe */
+struct lv_segment_area {
+ area_type_t type;
+ union {
+ struct {
+ struct pv_segment *pvseg;
+ } pv;
+ struct {
+ struct logical_volume *lv;
+ uint32_t le;
+ } lv;
+ } u;
+};
+
struct segment_type;
struct lv_segment {
struct list list;
struct list tags;
- /* There will be one area for each stripe */
- struct {
- area_type_t type;
- union {
- struct {
- struct pv_segment *pvseg;
- } pv;
- struct {
- struct logical_volume *lv;
- uint32_t le;
- } lv;
- } u;
- } area[0];
+ struct lv_segment_area *areas;
};
-#define seg_type(seg, s) (seg)->area[(s)].type
-#define seg_pvseg(seg, s) (seg)->area[(s)].u.pv.pvseg
-#define seg_pv(seg, s) (seg)->area[(s)].u.pv.pvseg->pv
-#define seg_dev(seg, s) (seg)->area[(s)].u.pv.pvseg->pv->dev
-#define seg_pe(seg, s) (seg)->area[(s)].u.pv.pvseg->pe
-#define seg_lv(seg, s) (seg)->area[(s)].u.lv.lv
-#define seg_le(seg, s) (seg)->area[(s)].u.lv.le
+#define seg_type(seg, s) (seg)->areas[(s)].type
+#define seg_pvseg(seg, s) (seg)->areas[(s)].u.pv.pvseg
+#define seg_pv(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv
+#define seg_dev(seg, s) (seg)->areas[(s)].u.pv.pvseg->pv->dev
+#define seg_pe(seg, s) (seg)->areas[(s)].u.pv.pvseg->pe
+#define seg_lv(seg, s) (seg)->areas[(s)].u.lv.lv
+#define seg_le(seg, s) (seg)->areas[(s)].u.lv.le
struct logical_volume {
union lvid lvid;
/* FIXME Relax this to first area type != second area type */
/* plus the additional AREA_LV checks needed */
- if ((first->area[s].type != AREA_PV) ||
- (second->area[s].type != AREA_PV))
+ if ((first->areas[s].type != AREA_PV) ||
+ (second->areas[s].type != AREA_PV))
return 0;
width = first->area_len;
seg1->area_len += seg2->area_len;
for (s = 0; s < seg1->area_count; s++)
- if (seg1->area[s].type == AREA_PV)
+ if (seg1->areas[s].type == AREA_PV)
merge_pv_segments(seg_pvseg(seg1, s),
seg_pvseg(seg2, s));