Blob Blame History Raw
From cab114c5ca870e5f1b57fb2602cd9a038271c2e0 Mon Sep 17 00:00:00 2001
From: Corey Hickey <bugfood-c@fatooh.org>
Date: Mon, 11 Feb 2019 17:18:38 -0800
Subject: [RHEL7.7 PATCH 16/24] 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>
---
 Grow.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/Grow.c b/Grow.c
index 6d32661..764374f 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;
 				}
-- 
2.7.5