summaryrefslogtreecommitdiffstats
path: root/lib/metadata/merge.c
blob: 67413a95621cdc3ff3f348bc37c12ea2b83464e6 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
 * Copyright (C) 2001 Sistina Software
 *
 * This file is released under the LGPL.
 */

#include "lib.h"
#include "metadata.h"

/*
 * Returns success if the segments were
 * successfully merged.  If the do merge, 'first'
 * will be adjusted to contain both areas.
 */
static int _merge(struct lv_segment *first, struct lv_segment *second)
{
	int s;
	uint32_t width;

	if (!first ||
	    (first->type != SEG_STRIPED) ||
	    (first->type != second->type) ||
	    (first->stripes != second->stripes) ||
	    (first->stripe_size != second->stripe_size))
		return 0;

	for (s = 0; s < first->stripes; s++) {
		width = first->len / first->stripes;

		if ((first->area[s].pv != second->area[s].pv) ||
		    (first->area[s].pe + width != second->area[s].pe))
			return 0;
	}

	/* we should merge */
	first->len += second->len;

	return 1;
}

int lv_merge_segments(struct logical_volume *lv)
{
	struct list *segh;
	struct lv_segment *current, *prev = NULL;

	list_iterate(segh, &lv->segments) {
		current = list_item(segh, struct lv_segment);

		if (_merge(prev, current))
			list_del(&current->list);
		else
			prev = current;
	}

	return 1;
}

int lv_check_segments(struct logical_volume *lv)
{
	return 1;
}