summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorey Hickey <bugfood-c@fatooh.org>2019-02-11 17:18:38 -0800
committerJes Sorensen <jsorensen@fb.com>2019-02-13 15:07:32 -0500
commitcab114c5ca870e5f1b57fb2602cd9a038271c2e0 (patch)
tree372871f1508092cc18dce92a32d644e856bf1d41
parente3615ecb5b6ad8eb408296878aad5628e0e27166 (diff)
downloadmdadm-cab114c5ca870e5f1b57fb2602cd9a038271c2e0.tar.gz
Fix reshape for decreasing data offset
...when not changing the number of disks. This patch needs context to explain. These are the relevant parts of the original code (condensed and annotated): if (dir > 0) { /* Increase data offset (reshape backwards) */ if (data_offset < sd->data_offset + min) { pr_err("--data-offset too small on %s\n", dn); goto release; } } else { /* Decrease data offset (reshape forwards) */ if (data_offset < sd->data_offset - min) { pr_err("--data-offset too small on %s\n", dn); goto release; } } When this code is reached, mdadm has already decided on a reshape direction. When increasing the data offset, the reshape runs backwards (dir==1); when decreasing the data offset, the reshape runs forwards (dir==-1). The conditional within the backwards reshape is correct: the requested offset must be larger than the old offset plus a minimum delta; thus the reshape has room to work. For the forwards reshape, the requested offset needs to be smaller than the old offset minus a minimum delta; to do this correctly, the comparison must be reversed. Also update the error message. Note: I have tested this change on a RAID 5 on Linux 4.18.0 and verified that there were no errors from the kernel and that the device data remained intact. I do not know if there are considerations for different RAID levels. Signed-off-by: Corey Hickey <bugfood-c@fatooh.org> Signed-off-by: Jes Sorensen <jsorensen@fb.com>
-rw-r--r--Grow.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/Grow.c b/Grow.c
index 6d326618..764374fc 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2613,8 +2613,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
goto release;
}
if (data_offset != INVALID_SECTORS &&
- data_offset < sd->data_offset - min) {
- pr_err("--data-offset too small on %s\n",
+ data_offset > sd->data_offset - min) {
+ pr_err("--data-offset too large on %s\n",
dn);
goto release;
}