Super1: allow RAID0 layout setting to be removed.

Once the RAID0 layout has been set, the RAID0 array cannot be assembled
on an older kernel which doesn't understand layouts.
This is an intentional safety feature, but sometimes people need the
ability to roll-back to a previously working configuration.

So add "--update=layout-unspecified" to remove RAID0 layout information
from the superblock.
Running "--assemble --update=layout-unspecified" will cause the assembly
the fail when run on a newer kernel, but will allow it to work on
an older kernel.

Signed-off-by: NeilBrown <neilb@suse.de>
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
This commit is contained in:
NeilBrown 2020-10-14 13:12:48 +11:00 committed by Jes Sorensen
parent 7f3b2d1d16
commit 97b51a2c2d
4 changed files with 34 additions and 5 deletions

13
md.4
View File

@ -215,6 +215,19 @@ option or the
.B "--update=layout-alternate"
option.
Once you have updated the layout you will not be able to mount the array
on an older kernel. If you need to revert to an older kernel, the
layout information can be erased with the
.B "--update=layout-unspecificed"
option. If you use this option to
.B --assemble
while running a newer kernel, the array will NOT assemble, but the
metadata will be update so that it can be assembled on an older kernel.
No that setting the layout to "unspecified" removes protections against
this bug, and you must be sure that the kernel you use matches the
layout of the array.
.SS RAID1
A RAID1 array is also known as a mirrored set (though mirrors tend to

View File

@ -1213,6 +1213,7 @@ argument given to this flag can be one of
.BR no\-ppl ,
.BR layout\-original ,
.BR layout\-alternate ,
.BR layout\-unspecified ,
.BR metadata ,
or
.BR super\-minor .
@ -1368,8 +1369,9 @@ The
.B layout\-original
and
.B layout\-alternate
options are for RAID0 arrays in use before Linux 5.4. If the array was being
used with Linux 3.13 or earlier, then to assemble the array on a new kernel,
options are for RAID0 arrays with non-uniform devices size that were in
use before Linux 5.4. If the array was being used with Linux 3.13 or
earlier, then to assemble the array on a new kernel,
.B \-\-update=layout\-original
must be given. If the array was created and used with a kernel from Linux 3.14 to
Linux 5.3, then
@ -1379,6 +1381,15 @@ will happen normally.
For more information, see
.IR md (4).
The
.B layout\-unspecified
option reverts the effect of
.B layout\-orignal
or
.B layout\-alternate
and allows the array to be again used on a kernel prior to Linux 5.3.
This option should be used with great caution.
.TP
.BR \-\-freeze\-reshape
Option is intended to be used in start-up scripts during initrd boot phase.

View File

@ -796,7 +796,8 @@ int main(int argc, char *argv[])
if (strcmp(c.update, "revert-reshape") == 0)
continue;
if (strcmp(c.update, "layout-original") == 0 ||
strcmp(c.update, "layout-alternate") == 0)
strcmp(c.update, "layout-alternate") == 0 ||
strcmp(c.update, "layout-unspecified") == 0)
continue;
if (strcmp(c.update, "byteorder") == 0) {
if (ss) {
@ -828,7 +829,7 @@ int main(int argc, char *argv[])
" 'summaries', 'homehost', 'home-cluster', 'byteorder', 'devicesize',\n"
" 'no-bitmap', 'metadata', 'revert-reshape'\n"
" 'bbl', 'no-bbl', 'force-no-bbl', 'ppl', 'no-ppl'\n"
" 'layout-original', 'layout-alternate'\n"
" 'layout-original', 'layout-alternate', 'layout-unspecified'\n"
);
exit(outf == stdout ? 0 : 2);

View File

@ -1551,11 +1551,15 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
else if (strcmp(update, "nofailfast") == 0)
sb->devflags &= ~FailFast1;
else if (strcmp(update, "layout-original") == 0 ||
strcmp(update, "layout-alternate") == 0) {
strcmp(update, "layout-alternate") == 0 ||
strcmp(update, "layout-unspecified") == 0) {
if (__le32_to_cpu(sb->level) != 0) {
pr_err("%s: %s only supported for RAID0\n",
devname?:"", update);
rv = -1;
} else if (strcmp(update, "layout-unspecified") == 0) {
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
sb->layout = 0;
} else {
sb->feature_map |= __cpu_to_le32(MD_FEATURE_RAID0_LAYOUT);
sb->layout = __cpu_to_le32(update[7] == 'o' ? 1 : 2);