From db575f3b9ebfdf0d7ac8dd5f9b1d4b4d0e446e80 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Tue, 24 Feb 2009 18:45:56 -0700 Subject: 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 --- super-intel.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) (limited to 'super-intel.c') 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; -- cgit