summaryrefslogtreecommitdiffstats
path: root/super-intel.c
diff options
context:
space:
mode:
authorDan Williams <dan.j.williams@intel.com>2009-02-24 18:45:56 -0700
committerDan Williams <dan.j.williams@intel.com>2009-02-24 18:45:56 -0700
commitdb575f3b9ebfdf0d7ac8dd5f9b1d4b4d0e446e80 (patch)
tree2e4088a3326c586f599339e25d56f7b26f9ba2f5 /super-intel.c
parentecf45690f2f4316b308eca3fd54af78a7c945726 (diff)
downloadmdadm-db575f3b9ebfdf0d7ac8dd5f9b1d4b4d0e446e80.tar.gz
mdadm-db575f3b9ebfdf0d7ac8dd5f9b1d4b4d0e446e80.tar.xz
mdadm-db575f3b9ebfdf0d7ac8dd5f9b1d4b4d0e446e80.zip
imsm: retry load_imsm_mpb if we suspect mdmon has made modifications
If the checksum verification fails and mdmon is running we retry the load to get a consistent snapshot of the mpb. Found by tests/08imsm-overlap. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Diffstat (limited to 'super-intel.c')
-rw-r--r--super-intel.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/super-intel.c b/super-intel.c
index 3f83255..f55d707 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -1820,7 +1820,7 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
Name ": IMSM checksum %x != %x on %s\n",
check_sum, __le32_to_cpu(super->anchor->check_sum),
devname);
- return 2;
+ return 3;
}
/* FIXME the BBM log is disk specific so we cannot use this global
@@ -1974,6 +1974,8 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
char nm[20];
int dfd;
int rv;
+ int devnum = fd2devnum(fd);
+ int retry;
/* check if this disk is a member of an active array */
sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
@@ -1998,6 +2000,15 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
return 2;
}
rv = load_imsm_mpb(dfd, super, NULL);
+
+ /* retry the load if we might have raced against mdmon */
+ if (rv == 3 && mdmon_running(devnum))
+ for (retry = 0; retry < 3; retry++) {
+ usleep(3000);
+ rv = load_imsm_mpb(dfd, super, NULL);
+ if (rv != 3)
+ break;
+ }
if (!keep_fd)
close(dfd);
if (rv == 0) {
@@ -2011,7 +2022,7 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
}
} else {
free_imsm(super);
- return 2;
+ return rv;
}
}
@@ -2061,7 +2072,7 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
}
*sbp = super;
- st->container_dev = fd2devnum(fd);
+ st->container_dev = devnum;
if (st->ss == NULL) {
st->ss = &super_imsm;
st->minor_version = 0;