diff options
author | Neil Brown <neilb@suse.de> | 2007-10-16 13:52:35 +1000 |
---|---|---|
committer | Neil Brown <neilb@suse.de> | 2007-10-16 13:52:35 +1000 |
commit | 6e9eac4f089a44e9091967a3e6198aeae7e845a3 (patch) | |
tree | 3c7f9118e6ef2e044ac7e28608375e9045f154eb | |
parent | cc4c7f14b1d53849c4d6f18a1a92f212bdbc68c2 (diff) | |
download | mdadm-6e9eac4f089a44e9091967a3e6198aeae7e845a3.tar.gz mdadm-6e9eac4f089a44e9091967a3e6198aeae7e845a3.tar.xz mdadm-6e9eac4f089a44e9091967a3e6198aeae7e845a3.zip |
Fix restarting of a reshaping array.
The last release broke the ability to assemble an array that
was in the middle of a reshape.
This patch adds code to test if the critical section needs
to be restored or not so that - if we have failed to restore it,
we know whether to fail or not.
-rw-r--r-- | Grow.c | 21 |
1 files changed, 21 insertions, 0 deletions
@@ -868,6 +868,8 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt int i, j; int old_disks; unsigned long long *offsets; + unsigned long long nstripe, ostripe, last_block; + int ndata, odata; if (info->delta_disks < 0) return 1; /* cannot handle a shrink */ @@ -978,5 +980,24 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt /* And we are done! */ return 0; } + /* Didn't find any backup data, try to see if any + * was needed. + */ + nstripe = ostripe = 0; + odata = info->array.raid_disks - info->delta_disks - 1; + if (info->array.level == 6) odata--; /* number of data disks */ + ndata = info->array.raid_disks - 1; + if (info->new_level == 6) ndata--; + last_block = 0; + while (nstripe >= ostripe) { + nstripe += info->new_chunk / 512; + last_block = nstripe * ndata; + ostripe = last_block / odata / (info->array.chunk_size/512) * + (info->array.chunk_size/512); + } + + if (info->reshape_progress >= last_block) + return 0; + /* needed to recover critical section! */ return 1; } |