diff options
author | Neil Brown <neilb@suse.de> | 2007-09-24 14:26:44 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2007-09-24 14:26:44 +1000 |
commit | 23dc1ae8771a5bbacf03365218bd693fb19776ba (patch) | |
tree | 588e20575a40b609313b4ce4b339e06c4e46db62 | |
parent | ff7f2ebbe90131ec314bfbdbedbb93526fee12e0 (diff) | |
download | mdadm-23dc1ae8771a5bbacf03365218bd693fb19776ba.tar.gz mdadm-23dc1ae8771a5bbacf03365218bd693fb19776ba.tar.xz mdadm-23dc1ae8771a5bbacf03365218bd693fb19776ba.zip |
Don't corrupt 'supertype' when speculatively calling load_super1
When load_super1 is trying to see which sub-version of v1 superblock
is present, failure will cause it to clear st->ss, which is not good.
So use a temporary 'super_type' for the 'test if this version works'
calls, then copy that into 'st' on success.
-rw-r--r-- | super1.c | 19 |
1 files changed, 10 insertions, 9 deletions
@@ -996,34 +996,35 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname) if (st->ss == NULL || st->minor_version == -1) { int bestvers = -1; + struct supertype tst; __u64 bestctime = 0; /* guess... choose latest ctime */ - st->ss = &super1; - for (st->minor_version = 0; st->minor_version <= 2 ; st->minor_version++) { + tst.ss = &super1; + for (tst.minor_version = 0; tst.minor_version <= 2 ; tst.minor_version++) { switch(load_super1(st, fd, sbp, devname)) { case 0: super = *sbp; if (bestvers == -1 || bestctime < __le64_to_cpu(super->ctime)) { - bestvers = st->minor_version; + bestvers = tst.minor_version; bestctime = __le64_to_cpu(super->ctime); } free(super); *sbp = NULL; break; - case 1: st->ss = NULL; return 1; /*bad device */ + case 1: return 1; /*bad device */ case 2: break; /* bad, try next */ } } if (bestvers != -1) { int rv; - st->minor_version = bestvers; - st->ss = &super1; - st->max_devs = 384; + tst.minor_version = bestvers; + tst.ss = &super1; + tst.max_devs = 384; rv = load_super1(st, fd, sbp, devname); - if (rv) st->ss = NULL; + if (rv == 0) + *st = tst; return rv; } - st->ss = NULL; return 2; } if (!get_dev_size(fd, devname, &dsize)) |