]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Support new offset layout for raid10
authorNeil Brown <neilb@suse.de>
Mon, 15 May 2006 02:46:54 +0000 (02:46 +0000)
committerNeil Brown <neilb@suse.de>
Mon, 15 May 2006 02:46:54 +0000 (02:46 +0000)
Requires 2.6.18.

Signed-off-by: Neil Brown <neilb@suse.de>
ChangeLog
Detail.c
md.4
mdadm.8
mdadm.c
super0.c
super1.c

index 28e6240fc5ad28178b13a075a31d290a8741278b..8e1d951c4b7bf2b8642fcf533d5581dafcc51854 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -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
index 8fa044a5315cf8ecfe4c444d91cdf3e197c8fb41..882ec07835a5bc0529f336e26c2e0a81c601c06c 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -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);
                                }
                        }
diff --git a/md.4 b/md.4
index d76dd8c1d97fcbf3b5999842f9b12f54016be85b..d22ded4231ec017e4d16454b997062dd2e5e8096 100644 (file)
--- a/md.4
+++ b/md.4
@@ -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.
diff --git a/mdadm.8 b/mdadm.8
index e3052dcd967c5bbdc49342efa7da179fa44880e4..4ec2f76ace1d1ee2780ad4238340492cd8cf2716 100644 (file)
--- a/mdadm.8
+++ b/mdadm.8
@@ -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
diff --git a/mdadm.c b/mdadm.c
index 05784e1d3be0873f1946a12d98b4e52f0f429f9b..f31047476eec0478294059ad63ef40c2a152c533 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -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;
index 49474d07fca284697691ff5de6d677ed0d2c3b43..8bded15c426abde1df701ca6ea4caded7e7b2610 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -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:
index 1ab077691b5028886c6b53f8107906cd560d1c1f..77b5485d3dadb83abe1b1e6e7d112549719ebc9f 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -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: