Allow --update to add or remove space for a bad block list.
--update=bbl will add a bad block list to each device. --update=no-bblk will remove the bad block list providing that it is empty. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
bf95d0f38c
commit
688e99a77d
24
mdadm.8.in
24
mdadm.8.in
|
@ -1060,6 +1060,8 @@ argument given to this flag can be one of
|
|||
.BR byteorder ,
|
||||
.BR devicesize ,
|
||||
.BR no\-bitmap ,
|
||||
.BR bbl ,
|
||||
.BR no-\bbl ,
|
||||
or
|
||||
.BR super\-minor .
|
||||
|
||||
|
@ -1162,6 +1164,18 @@ option can be used when an array has an internal bitmap which is
|
|||
corrupt in some way so that assembling the array normally fails. It
|
||||
will cause any internal bitmap to be ignored.
|
||||
|
||||
The
|
||||
.B bbl
|
||||
option will reserve space in each device for a bad block list. This
|
||||
will be 4K in size and positioned near the end of any free space
|
||||
between the superblock and the data.
|
||||
|
||||
The
|
||||
.B no\-bbl
|
||||
option will cause any reservation of space for a bad block list to be
|
||||
removed. If the bad block list contains entries, this will fail, as
|
||||
removing the list could cause data corruption.
|
||||
|
||||
.TP
|
||||
.BR \-\-freeze\-reshape
|
||||
Option is intended to be used in start-up scripts during initrd boot phase.
|
||||
|
@ -1221,12 +1235,14 @@ When used on an array that has no metadata (i.e. it was built with
|
|||
it will be assumed that bitmap-based recovery is enough to make the
|
||||
device fully consistent with the array.
|
||||
|
||||
When
|
||||
When used with v1.x metadata,
|
||||
.B \-\-re\-add
|
||||
can be accompanied by
|
||||
.BR \-\-update=devicesize .
|
||||
See the description of this option when used in Assemble mode for an
|
||||
explanation of its use.
|
||||
.BR \-\-update=devicesize ,
|
||||
.BR \-\-update=bbl ", or"
|
||||
.BR \-\-update=no\-bbl .
|
||||
See the description of these option when used in Assemble mode for an
|
||||
explanation of their use.
|
||||
|
||||
If the device name given is
|
||||
.B missing
|
||||
|
|
10
mdadm.c
10
mdadm.c
|
@ -713,6 +713,10 @@ int main(int argc, char *argv[])
|
|||
continue;
|
||||
if (strcmp(c.update, "no-bitmap")==0)
|
||||
continue;
|
||||
if (strcmp(c.update, "bbl") == 0)
|
||||
continue;
|
||||
if (strcmp(c.update, "no-bbl") == 0)
|
||||
continue;
|
||||
if (strcmp(c.update, "byteorder")==0) {
|
||||
if (ss) {
|
||||
pr_err("must not set metadata"
|
||||
|
@ -760,8 +764,10 @@ int main(int argc, char *argv[])
|
|||
exit(2);
|
||||
}
|
||||
c.update = optarg;
|
||||
if (strcmp(c.update, "devicesize") != 0) {
|
||||
pr_err("only 'devicesize' can be"
|
||||
if (strcmp(c.update, "devicesize") != 0 &&
|
||||
strcmp(c.update, "bbl") != 0 &&
|
||||
strcmp(c.update, "no-bbl") != 0) {
|
||||
pr_err("only 'devicesize', 'bbl' and 'no-bbl' can be"
|
||||
" updated with --re-add\n");
|
||||
exit(2);
|
||||
}
|
||||
|
|
50
super1.c
50
super1.c
|
@ -850,6 +850,56 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
|
|||
}
|
||||
} else if (strcmp(update, "no-bitmap") == 0) {
|
||||
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
|
||||
} else if (strcmp(update, "bbl") == 0) {
|
||||
/* only possible if there is room after the bitmap, or if
|
||||
* there is no bitmap
|
||||
*/
|
||||
unsigned long long sb_offset = __le64_to_cpu(sb->super_offset);
|
||||
unsigned long long data_offset = __le64_to_cpu(sb->data_offset);
|
||||
long bitmap_offset = (long)__le64_to_cpu(sb->bitmap_offset);
|
||||
long bm_sectors = 0;
|
||||
long space;
|
||||
|
||||
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BITMAP_OFFSET)) {
|
||||
struct bitmap_super_s *bsb;
|
||||
bsb = (struct bitmap_super_s *)(((char*)sb)+MAX_SB_SIZE);
|
||||
bm_sectors = bitmap_sectors(bsb);
|
||||
}
|
||||
|
||||
if (sb_offset < data_offset) {
|
||||
/* 1.1 or 1.2. Put bbl just before data
|
||||
*/
|
||||
long bb_offset;
|
||||
space = data_offset - sb_offset;
|
||||
bb_offset = space - 8;
|
||||
if (bm_sectors && bitmap_offset > 0)
|
||||
space -= (bitmap_offset + bm_sectors);
|
||||
else
|
||||
space -= 8; /* The superblock */
|
||||
if (space >= 8) {
|
||||
sb->bblog_size = __cpu_to_le16(8);
|
||||
sb->bblog_offset = __cpu_to_le32(bb_offset);
|
||||
}
|
||||
} else {
|
||||
/* 1.0 - Put bbl just before super block */
|
||||
if (bm_sectors && bitmap_offset < 0)
|
||||
space = -bitmap_offset - bm_sectors;
|
||||
else
|
||||
space = sb_offset - data_offset -
|
||||
__le64_to_cpu(sb->data_size);
|
||||
if (space >= 8) {
|
||||
sb->bblog_size = __cpu_to_le16(8);
|
||||
sb->bblog_offset = __cpu_to_le32((unsigned)-8);
|
||||
}
|
||||
}
|
||||
} else if (strcmp(update, "no-bbl") == 0) {
|
||||
if (sb->feature_map & __cpu_to_le32(MD_FEATURE_BAD_BLOCKS))
|
||||
pr_err("Cannot remove active bbl from %s\n",devname);
|
||||
else {
|
||||
sb->bblog_size = 0;
|
||||
sb->bblog_shift = 0;
|
||||
sb->bblog_offset = 0;
|
||||
}
|
||||
} else if (strcmp(update, "homehost") == 0 &&
|
||||
homehost) {
|
||||
char *c;
|
||||
|
|
Loading…
Reference in New Issue