@@ -326,7 +326,9 @@ static void print_usage(void)
fprintf(stderr, "options:\n");
fprintf(stderr, "\t -A --alloc-start the offset to start the FS\n");
fprintf(stderr, "\t -b --byte-count total number of bytes in the FS\n");
- fprintf(stderr, "\t -d --data data profile, raid0, raid1, raid5, raid6, raid10, dup or single\n");
+ fprintf(stderr, "\t -d --data data profile: <n>c[d][<m>s[<p>p]]\n");
+ fprintf(stderr, "\t\tfor n copies (d=reduced dev redundancy), m stripes, p parity stripes\n");
+ fprintf(stderr, "\t\tor raid0, raid1, raid10, dup or single (deprecated)\n");
fprintf(stderr, "\t -l --leafsize size of btree leaves\n");
fprintf(stderr, "\t -L --label set a label\n");
fprintf(stderr, "\t -m --metadata metadata profile, values like data profile\n");
@@ -346,8 +348,36 @@ static void print_version(void)
exit(0);
}
-static u64 parse_profile(char *s)
+static u64 make_profile(int copies, int dup, int stripes, int parity)
{
+ if(copies == 1 && !dup && stripes == 0 && parity == 0)
+ return 0;
+ else if(copies == 2 && dup && stripes == 0 && parity == 0)
+ return BTRFS_BLOCK_GROUP_DUP;
+ else if(copies == 2 && !dup && stripes == 0 && parity == 0)
+ return BTRFS_BLOCK_GROUP_RAID1;
+ else if(copies == 2 && !dup && stripes == -1 && parity == 0)
+ return BTRFS_BLOCK_GROUP_RAID10;
+ else if(copies == 1 && !dup && stripes == -1 && parity == 0)
+ return BTRFS_BLOCK_GROUP_RAID0;
+ else if(copies == 1 && !dup && stripes == -1 && parity == 1)
+ return BTRFS_BLOCK_GROUP_RAID5;
+ else if(copies == 1 && !dup && stripes == -1 && parity == 2)
+ return BTRFS_BLOCK_GROUP_RAID6;
+
+ return (u64)-1;
+}
+
+static u64 parse_profile(const char *s)
+{
+ char *pos, *parse_end;
+ int copies = 1;
+ int stripes = 0;
+ int parity = 0;
+ int dup = 0;
+ u64 profile = (u64)-1;
+
+ /* Look for exact match with historical forms first */
if (strcmp(s, "raid0") == 0) {
return BTRFS_BLOCK_GROUP_RAID0;
} else if (strcmp(s, "raid1") == 0) {
@@ -362,12 +392,54 @@ static u64 parse_profile(char *s)
return BTRFS_BLOCK_GROUP_DUP;
} else if (strcmp(s, "single") == 0) {
return 0;
+ }
+
+ /* Attempt to parse new ncmspp form */
+ /* <n>c is required and n must be an unsigned decimal number */
+ copies = strtoul(s, &parse_end, 10);
+ if(parse_end == s || (*parse_end != 'c' && *parse_end != 'C'))
+ goto unknown;
+
+ /* c may be followed by d to indicate non-redundant/DUP */
+ pos = parse_end + 1;
+ if(*pos == 'd' || *pos == 'D') {
+ dup = 1;
+ pos++;
+ }
+ if(*pos == 0)
+ goto done;
+
+ /* <m>s is optional, and <m> may be an integer, or a literal "x" */
+ if(*pos == 'x' || *pos == 'X') {
+ stripes = -1;
+ parse_end = pos+1;
} else {
- fprintf(stderr, "Unknown profile %s\n", s);
- print_usage();
+ stripes = strtoul(pos, &parse_end, 10);
}
- /* not reached */
- return 0;
+ if(parse_end == pos || (*parse_end != 's' && *parse_end != 'S'))
+ goto unknown;
+
+ pos = parse_end + 1;
+ if(*pos == 0)
+ goto done;
+
+ /* <p>p is optional, and p must be an integer */
+ parity = strtoul(pos, &parse_end, 10);
+ if(parse_end == pos || (*parse_end != 'p' && *parse_end != 'P'))
+ goto unknown;
+ pos = parse_end + 1;
+ if(*pos != 0)
+ goto unknown;
+
+done:
+ profile = make_profile(copies, dup, stripes, parity);
+ if(profile == (u64)-1)
+ fprintf(stderr, "Unknown or unavailable profile '%s'\n", s);
+ return profile;
+
+unknown:
+ fprintf(stderr, "Unparseable profile '%s'\n", s);
+ return (u64)-1;
}
static char *parse_label(char *input)
@@ -1447,6 +1519,11 @@ int main(int ac, char **av)
printf("\nWARNING! - %s IS EXPERIMENTAL\n", BTRFS_BUILD_VERSION);
printf("WARNING! - see http://btrfs.wiki.kernel.org before using\n\n");
+ if (data_profile == (u64)-1 || metadata_profile == (u64)-1) {
+ fprintf(stderr, "Cannot handle requested replication profile. Aborting\n");
+ exit(1);
+ }
+
if (source_dir == 0) {
file = av[optind++];
ret = is_swap_device(file);
@@ -1666,7 +1743,7 @@ raid_groups:
flags |= BTRFS_FEATURE_INCOMPAT_RAID56;
btrfs_set_super_incompat_flags(super, flags);
- printf("Setting RAID5/6 feature flag\n");
+ printf("Setting parity-RAID feature flag\n");
}
printf("fs created label %s on %s\n\tnodesize %u leafsize %u "
Teach mkfs.btrfs about ncmspp format for replication levels, which avoids the semantic uncertainty over the "RAID-XYZ" naming. Signed-off-by: Hugo Mills <hugo@carfax.org.uk> --- mkfs.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 84 insertions(+), 7 deletions(-)