Fix writing of second backup superblock during grow

There 'rv' tests were confused and sometimes wrong.
This resulted in not writing the second bsb.

Also fix the test script so the the critical section is long enough
that we have some hope of interrupting it.

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2010-08-05 21:39:17 +10:00
parent 8d848be1ed
commit 7204495377
2 changed files with 21 additions and 9 deletions

22
Grow.c
View File

@ -1350,17 +1350,21 @@ int grow_backup(struct mdinfo *sra,
bsb.sb_csum2 = bsb_csum((char*)&bsb, bsb.sb_csum2 = bsb_csum((char*)&bsb,
((char*)&bsb.sb_csum2)-((char*)&bsb)); ((char*)&bsb.sb_csum2)-((char*)&bsb));
rv = -1;
if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0) if ((unsigned long long)lseek64(destfd[i], destoffsets[i] - 4096, 0)
!= destoffsets[i] - 4096) != destoffsets[i] - 4096)
rv = 1; break;
rv = rv ?: write(destfd[i], &bsb, 512); if (write(destfd[i], &bsb, 512) != 512)
break;
if (destoffsets[i] > 4096) { if (destoffsets[i] > 4096) {
if ((unsigned long long)lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) != if ((unsigned long long)lseek64(destfd[i], destoffsets[i]+stripes*chunk*odata, 0) !=
destoffsets[i]+stripes*chunk*odata) destoffsets[i]+stripes*chunk*odata)
rv = 1; break;
rv = rv ?: write(destfd[i], &bsb, 512); if (write(destfd[i], &bsb, 512) != 512)
break;
} }
fsync(destfd[i]); fsync(destfd[i]);
rv = 0;
} }
return rv; return rv;
@ -1431,8 +1435,10 @@ int wait_backup(struct mdinfo *sra,
((char*)&bsb.sb_csum2)-((char*)&bsb)); ((char*)&bsb.sb_csum2)-((char*)&bsb));
if ((unsigned long long)lseek64(destfd[i], destoffsets[i]-4096, 0) != if ((unsigned long long)lseek64(destfd[i], destoffsets[i]-4096, 0) !=
destoffsets[i]-4096) destoffsets[i]-4096)
rv = 1; rv = -1;
rv = rv ?: write(destfd[i], &bsb, 512); if (rv == 0 &&
write(destfd[i], &bsb, 512) != 512)
rv = -1;
fsync(destfd[i]); fsync(destfd[i]);
} }
return rv; return rv;
@ -1441,8 +1447,8 @@ int wait_backup(struct mdinfo *sra,
static void fail(char *msg) static void fail(char *msg)
{ {
int rv; int rv;
rv = write(2, msg, strlen(msg)); rv = (write(2, msg, strlen(msg)) != (int)strlen(msg));
rv |= write(2, "\n", 1); rv |= (write(2, "\n", 1) != 1);
exit(rv ? 1 : 2); exit(rv ? 1 : 2);
} }

View File

@ -12,7 +12,13 @@ do
do dd if=/dev/urandom of=$d bs=1024 || true do dd if=/dev/urandom of=$d bs=1024 || true
done done
mdadm -CR $md0 -amd -l5 -c 256 -n$disks --assume-clean $devs case $disks in
2 | 3) chunk=1024;;
4 ) chunk=512;;
5 ) chunk=256;;
esac
mdadm -CR $md0 -amd -l5 -c $chunk -n$disks --assume-clean $devs
mdadm $md0 --add $dev6 mdadm $md0 --add $dev6
echo 20 > /proc/sys/dev/raid/speed_limit_max echo 20 > /proc/sys/dev/raid/speed_limit_max
mdadm --grow $md0 -n $[disks+1] mdadm --grow $md0 -n $[disks+1]