forked from pool/mdadm
87 lines
2.9 KiB
Diff
87 lines
2.9 KiB
Diff
|
From f43f5b32991c7f5a188940b00989c27f87feee81 Mon Sep 17 00:00:00 2001
|
||
|
From: NeilBrown <neilb@suse.de>
|
||
|
Date: Wed, 2 Apr 2014 15:26:35 +1100
|
||
|
Subject: [PATCH 4/4] DDF: Don't fail compare_super_ddf due to re-configure
|
||
|
changes.
|
||
|
|
||
|
It is possible that one device has seem some reconfig but the other
|
||
|
hasn't. In that case they are still the "same" DDF, even though
|
||
|
one might be older. Such age will be detected by 'seq' differences.
|
||
|
|
||
|
If A is new and B is old, then it is import that
|
||
|
mdadm -I B
|
||
|
mdadm -I A
|
||
|
|
||
|
doesn't get confused because A has the same uuid as B, but compare_super fails.
|
||
|
|
||
|
So: if the seq numbers are different, then just accept as two
|
||
|
different superblocks.
|
||
|
If they are the same, then look to copy data from new to old.
|
||
|
|
||
|
Signed-off-by: NeilBrown <neilb@suse.de>
|
||
|
---
|
||
|
super-ddf.c | 44 +++++++++++---------------------------------
|
||
|
1 file changed, 11 insertions(+), 33 deletions(-)
|
||
|
|
||
|
--- mdadm-3.3.orig/super-ddf.c
|
||
|
+++ mdadm-3.3/super-ddf.c
|
||
|
@@ -3937,47 +3937,25 @@ static int compare_super_ddf(struct supe
|
||
|
if (memcmp(first->anchor.guid, second->anchor.guid, DDF_GUID_LEN) != 0)
|
||
|
return 2;
|
||
|
|
||
|
- if (first->max_part != second->max_part ||
|
||
|
- !be16_eq(first->phys->used_pdes, second->phys->used_pdes) ||
|
||
|
- !be16_eq(first->virt->populated_vdes,
|
||
|
- second->virt->populated_vdes)) {
|
||
|
- dprintf("%s: PD/VD number mismatch\n", __func__);
|
||
|
- return 3;
|
||
|
- }
|
||
|
+ /* It is only OK to compare info in the anchor. Anything else
|
||
|
+ * could be changing due to a reconfig so must be ignored.
|
||
|
+ * guid really should be enough anyway.
|
||
|
+ */
|
||
|
|
||
|
- max_pds = be16_to_cpu(first->phys->used_pdes);
|
||
|
- for (dl2 = second->dlist; dl2; dl2 = dl2->next) {
|
||
|
- for (pd = 0; pd < max_pds; pd++)
|
||
|
- if (be32_eq(first->phys->entries[pd].refnum,
|
||
|
- dl2->disk.refnum))
|
||
|
- break;
|
||
|
- if (pd == max_pds) {
|
||
|
- dprintf("%s: no match for disk %08x\n", __func__,
|
||
|
- be32_to_cpu(dl2->disk.refnum));
|
||
|
- return 3;
|
||
|
- }
|
||
|
+ if (!be32_eq(first->active->seq, second->active->seq)) {
|
||
|
+ dprintf("%s: sequence number mismatch %u<->%u\n", __func__,
|
||
|
+ be32_to_cpu(first->active->seq),
|
||
|
+ be32_to_cpu(second->active->seq));
|
||
|
+ return 0;
|
||
|
}
|
||
|
|
||
|
- max_vds = be16_to_cpu(first->active->max_vd_entries);
|
||
|
- for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
|
||
|
- if (!be32_eq(vl2->conf.magic, DDF_VD_CONF_MAGIC))
|
||
|
- continue;
|
||
|
- for (vd = 0; vd < max_vds; vd++)
|
||
|
- if (!memcmp(first->virt->entries[vd].guid,
|
||
|
- vl2->conf.guid, DDF_GUID_LEN))
|
||
|
- break;
|
||
|
- if (vd == max_vds) {
|
||
|
- dprintf("%s: no match for VD config\n", __func__);
|
||
|
- return 3;
|
||
|
- }
|
||
|
- }
|
||
|
- /* FIXME should I look at anything else? */
|
||
|
-
|
||
|
/*
|
||
|
At this point we are fairly sure that the meta data matches.
|
||
|
But the new disk may contain additional local data.
|
||
|
Add it to the super block.
|
||
|
*/
|
||
|
+ max_vds = be16_to_cpu(first->active->max_vd_entries);
|
||
|
+ max_pds = be16_to_cpu(first->phys->used_pdes);
|
||
|
for (vl2 = second->conflist; vl2; vl2 = vl2->next) {
|
||
|
for (vl1 = first->conflist; vl1; vl1 = vl1->next)
|
||
|
if (!memcmp(vl1->conf.guid, vl2->conf.guid,
|