Support new offset layout for raid10

Requires 2.6.18.

Signed-off-by: Neil Brown <neilb@suse.de>
This commit is contained in:
Neil Brown 2006-05-15 02:46:54 +00:00
parent a99d6b669c
commit b578481ca3
7 changed files with 45 additions and 17 deletions

View File

@ -4,6 +4,7 @@ Changes Prior to this release
- Arrange that SparesMissing (which is similar in import to
DegradedArray) generates an Email.
- Assume "DEVICE partitions" if no DEVICE line is given.
- Support new 'offset' layout for raid10.
Changes Prior to 2.4.1 release
- Honour --write-mostly when adding to an array without persistent

View File

@ -205,8 +205,9 @@ int Detail(char *dev, int brief, int test)
printf(" Layout : %s\n", c?c:"-unknown-");
}
if (array.level == 10) {
printf(" Layout : near=%d, far=%d\n",
array.layout&255, (array.layout>>8)&255);
printf(" Layout : near=%d, %s=%d\n",
array.layout&255, (array.layout&0x10000)?"offset":"far",
(array.layout>>8)&255);
}
switch (array.level) {
case 0:
@ -254,8 +255,9 @@ This is pretty boring
c?c:"-unknown-");
}
if (info.new_level == 10) {
printf(" New Layout : near=%d, far=%d\n",
printf(" New Layout : near=%d, %s=%d\n",
info.new_layout&255,
(info.new_layout&0x10000)?"offset":"far",
(info.new_layout>>8)&255);
}
}

10
md.4
View File

@ -203,7 +203,8 @@ drives.
When configuring a RAID10 array it is necessary to specify the number
of replicas of each data block that are required (this will normally
be 2) and whether the replicas should be 'near' or 'far'.
be 2) and whether the replicas should be 'near', 'offset' or 'far'.
(Note that the 'offset' layout is only available from 2.6.18).
When 'near' replicas are chosen, the multiple copies of a given chunk
are laid out consecutively across the stripes of the array, so the two
@ -220,6 +221,13 @@ of any given block are on different drives.
The 'far' arrangement can give sequential read performance equal to
that of a RAID0 array, but at the cost of degraded write performance.
When 'offset' replicas are chosen, the multiple copies of a given
chunk are laid out on consecutive drives and at consecutive offsets.
Effectively each stripe is duplicated and the copies are offset by one
device. This should give similar read characteristics to 'far' if a
suitably large chunk size is used, but without as much seeking for
writes.
It should be noted that the number of devices in a RAID10 array need
not be a multiple of the number of replica of each data block, those
there must be at least as many devices as replicas.

14
mdadm.8
View File

@ -398,12 +398,20 @@ and "flush" will clear any persistent faults.
To set the parity with "--grow", the level of the array ("faulty")
must be specified before the fault mode is specified.
Finally, the layout options for RAID10 are either 'n' or 'p' followed
Finally, the layout options for RAID10 are one of 'n', 'o' or 'p' followed
by a small number. The default is 'n2'.
.I n
signals 'near' copies (multiple copies of one data block are at
similar offsets in different devices) while
signals 'near' copies. Multiple copies of one data block are at
similar offsets in different devices.
.I o
signals 'offset' copies. Rather than the chunks being duplicated
within a stripe, whole stripes are duplicated but are rotated by one
device so duplicate blocks are on different devices. Thus subsequent
copies of a block are in the next drive, and are one chunk further
down.
.I f
signals 'far' copies
(multiple copies have very different offsets). See md(4) for more

View File

@ -403,16 +403,18 @@ int main(int argc, char *argv[])
break;
case 10:
/* 'f' or 'n' followed by a number <= raid_disks */
if ((optarg[0] != 'n' && optarg[0] != 'f') ||
/* 'f', 'o' or 'n' followed by a number <= raid_disks */
if ((optarg[0] != 'n' && optarg[0] != 'f' && optarg[0] != 'o') ||
(copies = strtoul(optarg+1, &cp, 10)) < 1 ||
copies > 200 ||
*cp) {
fprintf(stderr, Name ": layout for raid10 must be 'nNN' or 'fNN' where NN is a number, not %s\n", optarg);
fprintf(stderr, Name ": layout for raid10 must be 'nNN', 'oNN' or 'fNN' where NN is a number, not %s\n", optarg);
exit(2);
}
if (optarg[0] == 'n')
layout = 256 + copies;
else if (optarg[0] == 'o')
layout = 0x10000 + (copies<<8) + 1;
else
layout = 1 + (copies<<8);
break;

View File

@ -141,8 +141,10 @@ static void examine_super0(void *sbv)
printf(" New Layout : %s\n", c?c:"-unknown-");
}
if (sb->level == 10) {
printf(" New Layout : near=%d, far=%d\n",
sb->new_layout&255, (sb->new_layout>>8)&255);
printf(" New Layout : near=%d, %s=%d\n",
sb->new_layout&255,
(sb->new_layout&0x10000)?"offset":"far",
(sb->new_layout>>8)&255);
}
}
if (sb->new_chunk != sb->chunk_size)
@ -170,8 +172,10 @@ static void examine_super0(void *sbv)
printf(" Layout : %s\n", c?c:"-unknown-");
}
if (sb->level == 10) {
printf(" Layout : near=%d, far=%d\n",
sb->layout&255, (sb->layout>>8)&255);
printf(" Layout : near=%d, %s=%d\n",
sb->layout&255,
(sb->layout&0x10000)?"offset":"far",
(sb->layout>>8)&255);
}
switch(sb->level) {
case 0:

View File

@ -218,8 +218,9 @@ static void examine_super1(void *sbv)
printf(" New Layout : %s\n", c?c:"-unknown-");
}
if (__le32_to_cpu(sb->level) == 10) {
printf(" New Layout : near=%d, far=%d\n",
printf(" New Layout : near=%d, %s=%d\n",
__le32_to_cpu(sb->new_layout)&255,
(__le32_to_cpu(sb->new_layout)&0x10000)?"offset":"far",
(__le32_to_cpu(sb->new_layout)>>8)&255);
}
}
@ -250,8 +251,10 @@ static void examine_super1(void *sbv)
}
if (__le32_to_cpu(sb->level) == 10) {
int lo = __le32_to_cpu(sb->layout);
printf(" Layout : near=%d, far=%d\n",
lo&255, (lo>>8)&255);
printf(" Layout : near=%d, %s=%d\n",
lo&255,
(lo&0x10000)?"offset":"far",
(lo>>8)&255);
}
switch(__le32_to_cpu(sb->level)) {
case 0: