<html><head></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jul 3, 2012, at 8:21 PM, NeilBrown wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><span class="Apple-style-span" style="border-collapse: separate; font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: -webkit-auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; font-size: medium; ">On Tue, 26 Jun 2012 07:03:51 -0500 Jonathan Brassow <<a href="mailto:jbrassow@redhat.com">jbrassow@redhat.com</a>><br>wrote:<br><br><blockquote type="cite">dm raid: add md raid10 support<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Support the MD RAID10 personality through dm-raid.c<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Signed-off-by: Jonathan Brassow <<a href="mailto:jbrassow@redhat.com">jbrassow@redhat.com</a>><br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">Index: linux-upstream/drivers/md/dm-raid.c<br></blockquote><blockquote type="cite">===================================================================<br></blockquote><blockquote type="cite">--- linux-upstream.orig/drivers/md/dm-raid.c<br></blockquote><blockquote type="cite">+++ linux-upstream/drivers/md/dm-raid.c<br></blockquote><blockquote type="cite">@@ -11,6 +11,7 @@<br></blockquote><blockquote type="cite">#include "md.h"<br></blockquote><blockquote type="cite">#include "raid1.h"<br></blockquote><blockquote type="cite">#include "raid5.h"<br></blockquote><blockquote type="cite">+#include "raid10.h"<br></blockquote><blockquote type="cite">#include "bitmap.h"<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">#include <linux/device-mapper.h><br></blockquote><blockquote type="cite">@@ -52,7 +53,11 @@ struct raid_dev {<br></blockquote><blockquote type="cite">#define DMPF_MAX_RECOVERY_RATE 0x20<br></blockquote><blockquote type="cite">#define DMPF_MAX_WRITE_BEHIND  0x40<br></blockquote><blockquote type="cite">#define DMPF_STRIPE_CACHE      0x80<br></blockquote><blockquote type="cite">-#define DMPF_REGION_SIZE       0X100<br></blockquote><blockquote type="cite">+#define DMPF_REGION_SIZE       0x100<br></blockquote><blockquote type="cite">+#define DMPF_RAID10_NEAR_COPIES 0x200<br></blockquote><blockquote type="cite">+#define DMPF_RAID10_FAR_COPIES  0x400<br></blockquote><blockquote type="cite">+#define DMPF_RAID10_FAR_OFFSET  0x800<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">struct raid_set {<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">       </span>struct dm_target *ti;<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">@@ -66,6 +71,15 @@ struct raid_set {<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; "> </span>struct raid_dev dev[0];<br></blockquote><blockquote type="cite">};<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">+/* near_copies in first byte */<br></blockquote><blockquote type="cite">+/* far_copies in second byte */<br></blockquote><blockquote type="cite">+/* far_offset in 17th bit */<br></blockquote><blockquote type="cite">+#define ALGORITHM_RAID10(near_copies, far_copies, far_offset) \<br></blockquote><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>((near_copies & 0xFF) | ((far_copies & 0xFF) << 8) | ((!!far_offset) << 16))<br></blockquote><blockquote type="cite">+#define RAID10_NC(layout) (layout & 0xFF)<br></blockquote><blockquote type="cite">+#define RAID10_FC(layout) ((layout >> 8) & 0xFF)<br></blockquote><blockquote type="cite">+#define RAID10_FO(layout) (layout & 0x10000)<br></blockquote><blockquote type="cite">+<br></blockquote><blockquote type="cite">/* Supported raid types and properties. */<br></blockquote><blockquote type="cite">static struct raid_type {<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span>const char *name;<span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; "> </span>/* RAID algorithm. */<br></blockquote><blockquote type="cite">@@ -76,6 +90,8 @@ static struct raid_type {<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">       </span>const unsigned algorithm;<span class="Apple-tab-span" style="white-space: pre; ">        </span>/* RAID algorithm. */<br></blockquote><blockquote type="cite">} raid_types[] = {<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span>{"raid1",    "RAID1 (mirroring)",               0, 2, 1, 0 /* NONE */},<br></blockquote><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">   </span>{"raid10",   "RAID10 (striped mirrors)",        0, 2, 10, -1 /* Varies */},<br></blockquote><blockquote type="cite">+<span class="Apple-tab-span" style="white-space: pre; ">       </span>{"raid1e",   "RAID1E (Enhanced RAID1)",         0, 2, 10, -1 /* Varies */},<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">   </span>{"raid4",    "RAID4 (dedicated parity disk)",<span class="Apple-tab-span" style="white-space: pre; "> </span>1, 2, 5, ALGORITHM_PARITY_0},<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">       </span>{"raid5_la", "RAID5 (left asymmetric)",<span class="Apple-tab-span" style="white-space: pre; ">      </span><span class="Apple-tab-span" style="white-space: pre; "> </span>1, 2, 5, ALGORITHM_LEFT_ASYMMETRIC},<br></blockquote><blockquote type="cite"><span class="Apple-tab-span" style="white-space: pre; ">        </span>{"raid5_ra", "RAID5 (right asymmetric)",<span class="Apple-tab-span" style="white-space: pre; ">     </span>1, 2, 5, ALGORITHM_RIGHT_ASYMMETRIC},<br></blockquote><blockquote type="cite">@@ -339,10 +355,17 @@ static int validate_region_size(struct r<br></blockquote><blockquote type="cite"> *    [max_write_behind <sectors>]<span class="Apple-tab-span" style="white-space: pre; ">        </span>See '-write-behind=' (man mdadm)<br></blockquote><blockquote type="cite"> *    [stripe_cache <sectors>]<span class="Apple-tab-span" style="white-space: pre; ">    </span><span class="Apple-tab-span" style="white-space: pre; "> </span>Stripe cache size for higher RAIDs<br></blockquote><blockquote type="cite"> *    [region_size <sectors>]           Defines granularity of bitmap<br></blockquote><blockquote type="cite">+ *<br></blockquote><blockquote type="cite">+ * RAID10-only options:<br></blockquote><blockquote type="cite">+ *    [raid10_near_copies   <# copies>] Near copies. (Default: 2)<br></blockquote><blockquote type="cite">+ *    [raid10_far_copies    <# copies>] Far copies.  (Default: 1)<br></blockquote><blockquote type="cite">+ *    [raid10_far_offset    <0/1>]      Offset is device size(0) or stripe(1).<br></blockquote><br>Can I suggest that you don't do it like this?  i.e. don't copy the<br>mistakes I made :-)<br><br>I don't think there is any value in supporting multiple near and far copies.<br>There are two dimensions of the layout:<br>- number of copies.  Defaults to 2<br>- location of the copies:  near, far, offset<br><br>Some day I could implement an alternate version of 'far' or 'offset' which<br>improves redundancy slightly.<br>Instead of<span class="Apple-converted-space"> </span><br>  A B C D<br>  ...<br>  D A B C<br><br>it would be<br><br>  A B C D<span class="Apple-converted-space"> </span><br>  ....<br>  B A D C<br><br>i.e. treat the devices as pair and swap the device for the second copy.<br>This doesn't generalise to an odd number of devices, but increases the number<br>of pairs of devices that can concurrently fail without losing date.<br>(for 4 devices, there are 6 pairs.  With current 'far' mode there are only 2<br>pair of devices that can concurrently fail (0,2 and 1,3).  With the proposed<br>far mode there are 4 (0,2 0,3 1,2, 1,3).<br><br>Adding this with your current proposal would be messy.<br>Adding it with the two dimensions I suggest would simply involve adding<br>another 'location' - 'farswap' or 'far2' or something.<br><br>I note you didn't make 'dm-raid1e' a module alias.  Was that deliberate?<br></span></blockquote></div><br><div>The missed module alias was an oversight, thanks for catching that.  (Similar - as you can see from this patch - to the oversight I had when introducing raid1. :)  I have gone back and forth on whether to include the alternate "raid1e" or not.  There are different RAID1E algorithms, as described in the kernel doc.  Perhaps there should also be aliases similar to raid5 and raid6 - like raid1e_as (i.e. RAID1E - Adjacent Stripe), etc.  However, there are several combinations that don't have a real name.  Any thoughts?  I would be just fine leaving "raid1e" out as I would leaving it in.  These days, RAID10 is really a subset of RAID1E - perhaps I should be considering taking "raid10" out.  ;)</div><div><br></div><div>I like your suggestion of changing the parameter names.  I've found the original names somewhat confusing.  ('far_offset' seems to imply to me that the copy would not be the very next stripe, but _offset_ somehow - it seems to have the reverse meaning to me.  I think this comes from the fact that it acts as a modifier to 'far_copy'.)  I toyed with a couple different ways of doing this but figured it was best to just go along.  Anyway, what you are suggesting seems to be:</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>raid10_copies <number> (Default: 2)</div><div><span class="Apple-tab-span" style="white-space:pre">    </span>raid10_layout <string> (Default: "near"/"adjacent")</div><div>Where <string> could be "near", "far", "offset" and "some-future-thing".  That seems nice to me and seems to clear up some of the confusion caused by "far_offset" seeming to be a modifier to "far_copies".</div><div><br></div><div>Let me know what you think about the above, and I'll get v2 ready.</div><div><br></div><div> brassow</div><div><br></div><div>P.S.  While it doesn't affect this singular patch, I see people posting their set of patches as a reply to the summary '0 of' patch.  This keeps things together better, and I'll assume this is the way I should post from now on.</div></body></html>