]> sourceware.org Git - lvm2.git/commitdiff
Additional validation of LV segments read from metadata. [HM]
authorAlasdair Kergon <agk@redhat.com>
Mon, 1 Sep 2003 19:55:16 +0000 (19:55 +0000)
committerAlasdair Kergon <agk@redhat.com>
Mon, 1 Sep 2003 19:55:16 +0000 (19:55 +0000)
lib/metadata/merge.c

index 8b51a49f920c65b30c418842850d22fff9887c15..af3217cf6c3c7b74cafc099127dd28a2595fa140 100644 (file)
@@ -8,36 +8,51 @@
 #include "metadata.h"
 
 /*
- * Returns success if the segments were
- * successfully merged.  If the do merge, 'first'
- * will be adjusted to contain both areas.
+ * Test whether two segments could be merged by the current merging code
  */
-static int _merge(struct lv_segment *first, struct lv_segment *second)
+static int _segments_compatible(struct lv_segment *first,
+                               struct lv_segment *second)
 {
-       unsigned int s;
        uint32_t width;
+       unsigned s;
 
-       if (!first ||
-           (first->type != SEG_STRIPED) ||
-           (first->type != second->type) ||
+       /* FIXME Relax the seg type restriction */
+       if (!first || !second ||
+           (first->type != SEG_STRIPED) || (second->type != first->type) ||
            (first->area_count != second->area_count) ||
            (first->stripe_size != second->stripe_size))
                return 0;
 
        for (s = 0; s < first->area_count; s++) {
-               width = first->area_len;
 
-               /* FIXME Relax this to first type != second type ? */
-               if (first->area[s].type != AREA_PV ||
-                   second->area[s].type != AREA_PV)
+               /* 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))
                        return 0;
 
+               width = first->area_len;
+
                if ((first->area[s].u.pv.pv != second->area[s].u.pv.pv) ||
                    (first->area[s].u.pv.pe + width != second->area[s].u.pv.pe))
                        return 0;
        }
 
-       /* we should merge */
+       return 1;
+}
+
+/*
+ * Attempt to merge two adjacent segments.
+ * Currently only supports SEG_STRIPED on AREA_PV.
+ * Returns success if successful, in which case 'first' 
+ * gets adjusted to contain both areas.
+ */
+static int _merge(struct lv_segment *first, struct lv_segment *second)
+{
+
+       if (!_segments_compatible(first, second))
+               return 0;
+
        first->len += second->len;
        first->area_len += second->area_len;
 
@@ -61,7 +76,27 @@ int lv_merge_segments(struct logical_volume *lv)
        return 1;
 }
 
+/*
+ * Verify that an LV's segments are consecutive, complete and don't overlap.
+ */
 int lv_check_segments(struct logical_volume *lv)
 {
+       struct lv_segment *seg;
+       uint32_t le = 0;
+       unsigned seg_count = 0;
+
+       list_iterate_items(seg, &lv->segments) {
+               seg_count++;
+               if (seg->le != le) {
+                       log_error("LV %s invalid: segment %u should begin at "
+                                 "LE %" PRIu32 " (found %" PRIu32 ").",
+                                 lv->name, seg_count, le, seg->le);
+                       return 0;
+               }
+
+               le += seg->len;
+       }
+
        return 1;
 }
+
This page took 0.035596 seconds and 5 git commands to generate.