Create: allow per-metadata default layouts
authorDan Williams <dan.j.williams@intel.com>
Tue, 20 Jan 2009 08:36:50 +0000 (01:36 -0700)
committerDan Williams <dan.j.williams@intel.com>
Tue, 20 Jan 2009 08:36:50 +0000 (01:36 -0700)
Let handlers specifiy their own defaults, specifically needed for the
imsm-raid5 case where mdadm defaults to 'ls' and imsm to 'la'.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Create.c
mdadm.h
super-intel.c

index 422b46d..a7275d3 100644 (file)
--- a/Create.c
+++ b/Create.c
 #include       "md_p.h"
 #include       <ctype.h>
 
+static int default_layout(struct supertype *st, int level, int verbose)
+{
+       int layout = UnSet;
+
+       if (st && st->ss->default_layout)
+               layout = st->ss->default_layout(level);
+
+       if (layout == UnSet)
+               switch(level) {
+               default: /* no layout */
+                       layout = 0;
+                       break;
+               case 10:
+                       layout = 0x102; /* near=2, far=1 */
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to n1\n");
+                       break;
+               case 5:
+               case 6:
+                       layout = map_name(r5layout, "default");
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to %s\n", map_num(r5layout, layout));
+                       break;
+               case LEVEL_FAULTY:
+                       layout = map_name(faultylayout, "default");
+
+                       if (verbose > 0)
+                               fprintf(stderr,
+                                       Name ": layout defaults to %s\n", map_num(faultylayout, layout));
+                       break;
+               }
+
+       return layout;
+}
+
+
 int Create(struct supertype *st, char *mddev,
           int chunk, int level, int layout, unsigned long long size, int raiddisks, int sparedisks,
           char *name, char *homehost, int *uuid,
@@ -78,6 +116,7 @@ int Create(struct supertype *st, char *mddev,
        unsigned long long bitmapsize;
        struct mdinfo info, *infos;
        int did_default = 0;
+       int do_default_layout = 0;
        unsigned long safe_mode_delay = 0;
        char chosen_name[1024];
        struct map_ent *map = NULL;
@@ -175,32 +214,12 @@ int Create(struct supertype *st, char *mddev,
        }
 
        /* now set some defaults */
-       if (layout == UnSet)
-               switch(level) {
-               default: /* no layout */
-                       layout = 0;
-                       break;
-               case 10:
-                       layout = 0x102; /* near=2, far=1 */
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to n1\n");
-                       break;
-               case 5:
-               case 6:
-                       layout = map_name(r5layout, "default");
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to %s\n", map_num(r5layout, layout));
-                       break;
-               case LEVEL_FAULTY:
-                       layout = map_name(faultylayout, "default");
 
-                       if (verbose > 0)
-                               fprintf(stderr,
-                                       Name ": layout defaults to %s\n", map_num(faultylayout, layout));
-                       break;
-               }
+
+       if (layout == UnSet) {
+               do_default_layout = 1;
+               layout = default_layout(st, level, verbose);
+       }
 
        if (level == 10)
                /* check layout fits in array*/
@@ -280,6 +299,8 @@ int Create(struct supertype *st, char *mddev,
                        char *name = "default";
                        for(i=0; !st && superlist[i]; i++) {
                                st = superlist[i]->match_metadata_desc(name);
+                               if (do_default_layout)
+                                       layout = default_layout(st, level, verbose);
                                if (st && !st->ss->validate_geometry
                                                (st, level, layout, raiddisks,
                                                 chunk, size*2, dname, &freesize,
@@ -297,6 +318,8 @@ int Create(struct supertype *st, char *mddev,
                            st->minor_version != 90)
                                did_default = 1;
                } else {
+                       if (do_default_layout)
+                               layout = default_layout(st, level, verbose);
                        if (!st->ss->validate_geometry(st, level, layout,
                                                       raiddisks,
                                                       chunk, size*2, dname,
diff --git a/mdadm.h b/mdadm.h
index 8220535..3ee2790 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -545,6 +545,8 @@ extern struct superswitch {
                                 int verbose);
 
        struct mdinfo *(*container_content)(struct supertype *st);
+       /* Allow a metadata handler to override mdadm's default layouts */
+       int (*default_layout)(int level); /* optional */
 
 /* for mdmon */
        int (*open_new)(struct supertype *c, struct active_array *a,
index ce9a5c1..ac0c2de 100644 (file)
@@ -1101,7 +1101,7 @@ static int imsm_level_to_layout(int level)
        case 10:
                return 0x102;
        }
-       return -1;
+       return UnSet;
 }
 
 static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
@@ -4143,6 +4143,7 @@ struct superswitch super_imsm = {
        .free_super     = free_super_imsm,
        .match_metadata_desc = match_metadata_desc_imsm,
        .container_content = container_content_imsm,
+       .default_layout = imsm_level_to_layout,
 
        .external       = 1,
        .name = "imsm",