The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/geom/raid/md_jmicron.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*-
    2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
    3  *
    4  * Copyright (c) 2010 Alexander Motin <mav@FreeBSD.org>
    5  * Copyright (c) 2000 - 2008 Søren Schmidt <sos@FreeBSD.org>
    6  * All rights reserved.
    7  *
    8  * Redistribution and use in source and binary forms, with or without
    9  * modification, are permitted provided that the following conditions
   10  * are met:
   11  * 1. Redistributions of source code must retain the above copyright
   12  *    notice, this list of conditions and the following disclaimer.
   13  * 2. Redistributions in binary form must reproduce the above copyright
   14  *    notice, this list of conditions and the following disclaimer in the
   15  *    documentation and/or other materials provided with the distribution.
   16  *
   17  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
   18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE
   21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   27  * SUCH DAMAGE.
   28  */
   29 
   30 #include <sys/cdefs.h>
   31 __FBSDID("$FreeBSD$");
   32 
   33 #include <sys/param.h>
   34 #include <sys/bio.h>
   35 #include <sys/endian.h>
   36 #include <sys/kernel.h>
   37 #include <sys/kobj.h>
   38 #include <sys/limits.h>
   39 #include <sys/lock.h>
   40 #include <sys/malloc.h>
   41 #include <sys/mutex.h>
   42 #include <sys/systm.h>
   43 #include <sys/taskqueue.h>
   44 #include <geom/geom.h>
   45 #include <geom/geom_dbg.h>
   46 #include "geom/raid/g_raid.h"
   47 #include "g_raid_md_if.h"
   48 
   49 static MALLOC_DEFINE(M_MD_JMICRON, "md_jmicron_data", "GEOM_RAID JMicron metadata");
   50 
   51 #define JMICRON_MAX_DISKS       8
   52 #define JMICRON_MAX_SPARE       2
   53 
   54 struct jmicron_raid_conf {
   55     uint8_t             signature[2];
   56 #define JMICRON_MAGIC           "JM"
   57 
   58     uint16_t            version;
   59 #define JMICRON_VERSION         0x0001
   60 
   61     uint16_t            checksum;
   62     uint8_t             filler_1[10];
   63     uint32_t            disk_id;
   64     uint32_t            offset;
   65     uint32_t            disk_sectors_high;
   66     uint16_t            disk_sectors_low;
   67     uint8_t             filler_2[2];
   68     uint8_t             name[16];
   69     uint8_t             type;
   70 #define JMICRON_T_RAID0         0
   71 #define JMICRON_T_RAID1         1
   72 #define JMICRON_T_RAID01        2
   73 #define JMICRON_T_CONCAT        3
   74 #define JMICRON_T_RAID5         5
   75 
   76     uint8_t             stripe_shift;
   77     uint16_t            flags;
   78 #define JMICRON_F_READY         0x0001
   79 #define JMICRON_F_BOOTABLE      0x0002
   80 #define JMICRON_F_BADSEC        0x0004
   81 #define JMICRON_F_ACTIVE        0x0010
   82 #define JMICRON_F_UNSYNC        0x0020
   83 #define JMICRON_F_NEWEST        0x0040
   84 
   85     uint8_t             filler_3[4];
   86     uint32_t            spare[JMICRON_MAX_SPARE];
   87     uint32_t            disks[JMICRON_MAX_DISKS];
   88 #define JMICRON_DISK_MASK       0xFFFFFFF0
   89 #define JMICRON_SEG_MASK        0x0000000F
   90     uint8_t             filler_4[32];
   91     uint8_t             filler_5[384];
   92 };
   93 
   94 struct g_raid_md_jmicron_perdisk {
   95         struct jmicron_raid_conf        *pd_meta;
   96         int                              pd_disk_pos;
   97         int                              pd_disk_id;
   98         off_t                            pd_disk_size;
   99 };
  100 
  101 struct g_raid_md_jmicron_object {
  102         struct g_raid_md_object  mdio_base;
  103         uint32_t                 mdio_config_id;
  104         struct jmicron_raid_conf        *mdio_meta;
  105         struct callout           mdio_start_co; /* STARTING state timer. */
  106         int                      mdio_total_disks;
  107         int                      mdio_disks_present;
  108         int                      mdio_started;
  109         int                      mdio_incomplete;
  110         struct root_hold_token  *mdio_rootmount; /* Root mount delay token. */
  111 };
  112 
  113 static g_raid_md_create_t g_raid_md_create_jmicron;
  114 static g_raid_md_taste_t g_raid_md_taste_jmicron;
  115 static g_raid_md_event_t g_raid_md_event_jmicron;
  116 static g_raid_md_ctl_t g_raid_md_ctl_jmicron;
  117 static g_raid_md_write_t g_raid_md_write_jmicron;
  118 static g_raid_md_fail_disk_t g_raid_md_fail_disk_jmicron;
  119 static g_raid_md_free_disk_t g_raid_md_free_disk_jmicron;
  120 static g_raid_md_free_t g_raid_md_free_jmicron;
  121 
  122 static kobj_method_t g_raid_md_jmicron_methods[] = {
  123         KOBJMETHOD(g_raid_md_create,    g_raid_md_create_jmicron),
  124         KOBJMETHOD(g_raid_md_taste,     g_raid_md_taste_jmicron),
  125         KOBJMETHOD(g_raid_md_event,     g_raid_md_event_jmicron),
  126         KOBJMETHOD(g_raid_md_ctl,       g_raid_md_ctl_jmicron),
  127         KOBJMETHOD(g_raid_md_write,     g_raid_md_write_jmicron),
  128         KOBJMETHOD(g_raid_md_fail_disk, g_raid_md_fail_disk_jmicron),
  129         KOBJMETHOD(g_raid_md_free_disk, g_raid_md_free_disk_jmicron),
  130         KOBJMETHOD(g_raid_md_free,      g_raid_md_free_jmicron),
  131         { 0, 0 }
  132 };
  133 
  134 static struct g_raid_md_class g_raid_md_jmicron_class = {
  135         "JMicron",
  136         g_raid_md_jmicron_methods,
  137         sizeof(struct g_raid_md_jmicron_object),
  138         .mdc_enable = 1,
  139         .mdc_priority = 100
  140 };
  141 
  142 static void
  143 g_raid_md_jmicron_print(struct jmicron_raid_conf *meta)
  144 {
  145         int k;
  146 
  147         if (g_raid_debug < 1)
  148                 return;
  149 
  150         printf("********* ATA JMicron RAID Metadata *********\n");
  151         printf("signature           <%c%c>\n", meta->signature[0], meta->signature[1]);
  152         printf("version             %04x\n", meta->version);
  153         printf("checksum            0x%04x\n", meta->checksum);
  154         printf("disk_id             0x%08x\n", meta->disk_id);
  155         printf("offset              0x%08x\n", meta->offset);
  156         printf("disk_sectors_high   0x%08x\n", meta->disk_sectors_high);
  157         printf("disk_sectors_low    0x%04x\n", meta->disk_sectors_low);
  158         printf("name                <%.16s>\n", meta->name);
  159         printf("type                %d\n", meta->type);
  160         printf("stripe_shift        %d\n", meta->stripe_shift);
  161         printf("flags               %04x\n", meta->flags);
  162         printf("spare              ");
  163         for (k = 0; k < JMICRON_MAX_SPARE; k++)
  164                 printf(" 0x%08x", meta->spare[k]);
  165         printf("\n");
  166         printf("disks              ");
  167         for (k = 0; k < JMICRON_MAX_DISKS; k++)
  168                 printf(" 0x%08x", meta->disks[k]);
  169         printf("\n");
  170         printf("=================================================\n");
  171 }
  172 
  173 static struct jmicron_raid_conf *
  174 jmicron_meta_copy(struct jmicron_raid_conf *meta)
  175 {
  176         struct jmicron_raid_conf *nmeta;
  177 
  178         nmeta = malloc(sizeof(*meta), M_MD_JMICRON, M_WAITOK);
  179         memcpy(nmeta, meta, sizeof(*meta));
  180         return (nmeta);
  181 }
  182 
  183 static int
  184 jmicron_meta_total_disks(struct jmicron_raid_conf *meta)
  185 {
  186         int pos;
  187 
  188         for (pos = 0; pos < JMICRON_MAX_DISKS; pos++) {
  189                 if (meta->disks[pos] == 0)
  190                         break;
  191         }
  192         return (pos);
  193 }
  194 
  195 static int
  196 jmicron_meta_total_spare(struct jmicron_raid_conf *meta)
  197 {
  198         int pos, n;
  199 
  200         n = 0;
  201         for (pos = 0; pos < JMICRON_MAX_SPARE; pos++) {
  202                 if (meta->spare[pos] != 0)
  203                         n++;
  204         }
  205         return (n);
  206 }
  207 
  208 /*
  209  * Generate fake Configuration ID based on disk IDs.
  210  * Note: it will change after each disk set change.
  211  */
  212 static uint32_t
  213 jmicron_meta_config_id(struct jmicron_raid_conf *meta)
  214 {
  215         int pos;
  216         uint32_t config_id;
  217 
  218         config_id = 0;
  219         for (pos = 0; pos < JMICRON_MAX_DISKS; pos++)
  220                 config_id += meta->disks[pos] << pos;
  221         return (config_id);
  222 }
  223 
  224 static void
  225 jmicron_meta_get_name(struct jmicron_raid_conf *meta, char *buf)
  226 {
  227         int i;
  228 
  229         strncpy(buf, meta->name, 16);
  230         buf[16] = 0;
  231         for (i = 15; i >= 0; i--) {
  232                 if (buf[i] > 0x20)
  233                         break;
  234                 buf[i] = 0;
  235         }
  236 }
  237 
  238 static void
  239 jmicron_meta_put_name(struct jmicron_raid_conf *meta, char *buf)
  240 {
  241 
  242         memset(meta->name, 0x20, 16);
  243         memcpy(meta->name, buf, MIN(strlen(buf), 16));
  244 }
  245 
  246 static int
  247 jmicron_meta_find_disk(struct jmicron_raid_conf *meta, uint32_t id)
  248 {
  249         int pos;
  250 
  251         id &= JMICRON_DISK_MASK;
  252         for (pos = 0; pos < JMICRON_MAX_DISKS; pos++) {
  253                 if ((meta->disks[pos] & JMICRON_DISK_MASK) == id)
  254                         return (pos);
  255         }
  256         for (pos = 0; pos < JMICRON_MAX_SPARE; pos++) {
  257                 if ((meta->spare[pos] & JMICRON_DISK_MASK) == id)
  258                         return (-3);
  259         }
  260         return (-1);
  261 }
  262 
  263 static struct jmicron_raid_conf *
  264 jmicron_meta_read(struct g_consumer *cp)
  265 {
  266         struct g_provider *pp;
  267         struct jmicron_raid_conf *meta;
  268         char *buf;
  269         int error, i;
  270         uint16_t checksum, *ptr;
  271 
  272         pp = cp->provider;
  273         if (pp->sectorsize < sizeof(*meta))
  274                 return (NULL);
  275         /* Read the anchor sector. */
  276         buf = g_read_data(cp,
  277             pp->mediasize - pp->sectorsize, pp->sectorsize, &error);
  278         if (buf == NULL) {
  279                 G_RAID_DEBUG(1, "Cannot read metadata from %s (error=%d).",
  280                     pp->name, error);
  281                 return (NULL);
  282         }
  283         meta = (struct jmicron_raid_conf *)buf;
  284 
  285         /* Check if this is an JMicron RAID struct */
  286         if (strncmp(meta->signature, JMICRON_MAGIC, strlen(JMICRON_MAGIC))) {
  287                 G_RAID_DEBUG(1, "JMicron signature check failed on %s", pp->name);
  288                 g_free(buf);
  289                 return (NULL);
  290         }
  291         meta = malloc(sizeof(*meta), M_MD_JMICRON, M_WAITOK);
  292         memcpy(meta, buf, min(sizeof(*meta), pp->sectorsize));
  293         g_free(buf);
  294 
  295         /* Check metadata checksum. */
  296         for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i < 64; i++)
  297                 checksum += *ptr++;
  298         if (checksum != 0) {
  299                 G_RAID_DEBUG(1, "JMicron checksum check failed on %s", pp->name);
  300                 free(meta, M_MD_JMICRON);
  301                 return (NULL);
  302         }
  303 
  304         return (meta);
  305 }
  306 
  307 static int
  308 jmicron_meta_write(struct g_consumer *cp, struct jmicron_raid_conf *meta)
  309 {
  310         struct g_provider *pp;
  311         char *buf;
  312         int error, i;
  313         uint16_t checksum, *ptr;
  314 
  315         pp = cp->provider;
  316 
  317         /* Recalculate checksum for case if metadata were changed. */
  318         meta->checksum = 0;
  319         for (checksum = 0, ptr = (uint16_t *)meta, i = 0; i < 64; i++)
  320                 checksum += *ptr++;
  321         meta->checksum -= checksum;
  322 
  323         /* Create and fill buffer. */
  324         buf = malloc(pp->sectorsize, M_MD_JMICRON, M_WAITOK | M_ZERO);
  325         memcpy(buf, meta, sizeof(*meta));
  326 
  327         error = g_write_data(cp,
  328             pp->mediasize - pp->sectorsize, buf, pp->sectorsize);
  329         if (error != 0) {
  330                 G_RAID_DEBUG(1, "Cannot write metadata to %s (error=%d).",
  331                     pp->name, error);
  332         }
  333 
  334         free(buf, M_MD_JMICRON);
  335         return (error);
  336 }
  337 
  338 static int
  339 jmicron_meta_erase(struct g_consumer *cp)
  340 {
  341         struct g_provider *pp;
  342         char *buf;
  343         int error;
  344 
  345         pp = cp->provider;
  346         buf = malloc(pp->sectorsize, M_MD_JMICRON, M_WAITOK | M_ZERO);
  347         error = g_write_data(cp,
  348             pp->mediasize - pp->sectorsize, buf, pp->sectorsize);
  349         if (error != 0) {
  350                 G_RAID_DEBUG(1, "Cannot erase metadata on %s (error=%d).",
  351                     pp->name, error);
  352         }
  353         free(buf, M_MD_JMICRON);
  354         return (error);
  355 }
  356 
  357 static struct g_raid_disk *
  358 g_raid_md_jmicron_get_disk(struct g_raid_softc *sc, int id)
  359 {
  360         struct g_raid_disk      *disk;
  361         struct g_raid_md_jmicron_perdisk *pd;
  362 
  363         TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
  364                 pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
  365                 if (pd->pd_disk_pos == id)
  366                         break;
  367         }
  368         return (disk);
  369 }
  370 
  371 static int
  372 g_raid_md_jmicron_supported(int level, int qual, int disks, int force)
  373 {
  374 
  375         if (disks > 8)
  376                 return (0);
  377         switch (level) {
  378         case G_RAID_VOLUME_RL_RAID0:
  379                 if (disks < 1)
  380                         return (0);
  381                 if (!force && (disks < 2 || disks > 6))
  382                         return (0);
  383                 break;
  384         case G_RAID_VOLUME_RL_RAID1:
  385                 if (disks < 1)
  386                         return (0);
  387                 if (!force && (disks != 2))
  388                         return (0);
  389                 break;
  390         case G_RAID_VOLUME_RL_RAID1E:
  391                 if (disks < 2)
  392                         return (0);
  393                 if (!force && (disks != 4))
  394                         return (0);
  395                 break;
  396         case G_RAID_VOLUME_RL_SINGLE:
  397                 if (disks != 1)
  398                         return (0);
  399                 if (!force)
  400                         return (0);
  401                 break;
  402         case G_RAID_VOLUME_RL_CONCAT:
  403                 if (disks < 2)
  404                         return (0);
  405                 break;
  406         case G_RAID_VOLUME_RL_RAID5:
  407                 if (disks < 3)
  408                         return (0);
  409                 if (qual != G_RAID_VOLUME_RLQ_R5LA)
  410                         return (0);
  411                 if (!force)
  412                         return (0);
  413                 break;
  414         default:
  415                 return (0);
  416         }
  417         if (level != G_RAID_VOLUME_RL_RAID5 && qual != G_RAID_VOLUME_RLQ_NONE)
  418                 return (0);
  419         return (1);
  420 }
  421 
  422 static int
  423 g_raid_md_jmicron_start_disk(struct g_raid_disk *disk)
  424 {
  425         struct g_raid_softc *sc;
  426         struct g_raid_subdisk *sd, *tmpsd;
  427         struct g_raid_disk *olddisk, *tmpdisk;
  428         struct g_raid_md_object *md;
  429         struct g_raid_md_jmicron_object *mdi;
  430         struct g_raid_md_jmicron_perdisk *pd, *oldpd;
  431         struct jmicron_raid_conf *meta;
  432         int disk_pos, resurrection = 0;
  433 
  434         sc = disk->d_softc;
  435         md = sc->sc_md;
  436         mdi = (struct g_raid_md_jmicron_object *)md;
  437         meta = mdi->mdio_meta;
  438         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
  439         olddisk = NULL;
  440 
  441         /* Find disk position in metadata by its serial. */
  442         if (pd->pd_meta != NULL)
  443                 disk_pos = jmicron_meta_find_disk(meta, pd->pd_disk_id);
  444         else
  445                 disk_pos = -1;
  446         if (disk_pos < 0) {
  447                 G_RAID_DEBUG1(1, sc, "Unknown, probably new or stale disk");
  448                 /* If we are in the start process, that's all for now. */
  449                 if (!mdi->mdio_started)
  450                         goto nofit;
  451                 /*
  452                  * If we have already started - try to get use of the disk.
  453                  * Try to replace OFFLINE disks first, then FAILED.
  454                  */
  455                 TAILQ_FOREACH(tmpdisk, &sc->sc_disks, d_next) {
  456                         if (tmpdisk->d_state != G_RAID_DISK_S_OFFLINE &&
  457                             tmpdisk->d_state != G_RAID_DISK_S_FAILED)
  458                                 continue;
  459                         /* Make sure this disk is big enough. */
  460                         TAILQ_FOREACH(sd, &tmpdisk->d_subdisks, sd_next) {
  461                                 if (sd->sd_offset + sd->sd_size + 512 >
  462                                     pd->pd_disk_size) {
  463                                         G_RAID_DEBUG1(1, sc,
  464                                             "Disk too small (%ju < %ju)",
  465                                             pd->pd_disk_size,
  466                                             sd->sd_offset + sd->sd_size + 512);
  467                                         break;
  468                                 }
  469                         }
  470                         if (sd != NULL)
  471                                 continue;
  472                         if (tmpdisk->d_state == G_RAID_DISK_S_OFFLINE) {
  473                                 olddisk = tmpdisk;
  474                                 break;
  475                         } else if (olddisk == NULL)
  476                                 olddisk = tmpdisk;
  477                 }
  478                 if (olddisk == NULL) {
  479 nofit:
  480                         if (disk_pos == -3 || pd->pd_disk_pos == -3) {
  481                                 g_raid_change_disk_state(disk,
  482                                     G_RAID_DISK_S_SPARE);
  483                                 return (1);
  484                         } else {
  485                                 g_raid_change_disk_state(disk,
  486                                     G_RAID_DISK_S_STALE);
  487                                 return (0);
  488                         }
  489                 }
  490                 oldpd = (struct g_raid_md_jmicron_perdisk *)olddisk->d_md_data;
  491                 disk_pos = oldpd->pd_disk_pos;
  492                 resurrection = 1;
  493         }
  494 
  495         if (olddisk == NULL) {
  496                 /* Find placeholder by position. */
  497                 olddisk = g_raid_md_jmicron_get_disk(sc, disk_pos);
  498                 if (olddisk == NULL)
  499                         panic("No disk at position %d!", disk_pos);
  500                 if (olddisk->d_state != G_RAID_DISK_S_OFFLINE) {
  501                         G_RAID_DEBUG1(1, sc, "More than one disk for pos %d",
  502                             disk_pos);
  503                         g_raid_change_disk_state(disk, G_RAID_DISK_S_STALE);
  504                         return (0);
  505                 }
  506                 oldpd = (struct g_raid_md_jmicron_perdisk *)olddisk->d_md_data;
  507         }
  508 
  509         /* Replace failed disk or placeholder with new disk. */
  510         TAILQ_FOREACH_SAFE(sd, &olddisk->d_subdisks, sd_next, tmpsd) {
  511                 TAILQ_REMOVE(&olddisk->d_subdisks, sd, sd_next);
  512                 TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
  513                 sd->sd_disk = disk;
  514         }
  515         oldpd->pd_disk_pos = -2;
  516         pd->pd_disk_pos = disk_pos;
  517         /* Update global metadata just in case. */
  518         meta->disks[disk_pos] = pd->pd_disk_id;
  519 
  520         /* If it was placeholder -- destroy it. */
  521         if (olddisk->d_state == G_RAID_DISK_S_OFFLINE) {
  522                 g_raid_destroy_disk(olddisk);
  523         } else {
  524                 /* Otherwise, make it STALE_FAILED. */
  525                 g_raid_change_disk_state(olddisk, G_RAID_DISK_S_STALE_FAILED);
  526         }
  527 
  528         /* Welcome the new disk. */
  529         g_raid_change_disk_state(disk, G_RAID_DISK_S_ACTIVE);
  530         TAILQ_FOREACH(sd, &disk->d_subdisks, sd_next) {
  531                 /*
  532                  * Different disks may have different sizes/offsets,
  533                  * especially in concat mode. Update.
  534                  */
  535                 if (!resurrection) {
  536                         sd->sd_offset =
  537                             (off_t)pd->pd_meta->offset * 16 * 512; //ZZZ
  538                         sd->sd_size =
  539                             (((off_t)pd->pd_meta->disk_sectors_high << 16) +
  540                               pd->pd_meta->disk_sectors_low) * 512;
  541                 }
  542 
  543                 if (resurrection) {
  544                         /* Stale disk, almost same as new. */
  545                         g_raid_change_subdisk_state(sd,
  546                             G_RAID_SUBDISK_S_NEW);
  547                 } else if ((meta->flags & JMICRON_F_BADSEC) != 0 &&
  548                     (pd->pd_meta->flags & JMICRON_F_BADSEC) == 0) {
  549                         /* Cold-inserted or rebuilding disk. */
  550                         g_raid_change_subdisk_state(sd,
  551                             G_RAID_SUBDISK_S_NEW);
  552                 } else if (pd->pd_meta->flags & JMICRON_F_UNSYNC) {
  553                         /* Dirty or resyncing disk.. */
  554                         g_raid_change_subdisk_state(sd,
  555                             G_RAID_SUBDISK_S_STALE);
  556                 } else {
  557                         /* Up to date disk. */
  558                         g_raid_change_subdisk_state(sd,
  559                             G_RAID_SUBDISK_S_ACTIVE);
  560                 }
  561                 g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
  562                     G_RAID_EVENT_SUBDISK);
  563         }
  564 
  565         /* Update status of our need for spare. */
  566         if (mdi->mdio_started) {
  567                 mdi->mdio_incomplete =
  568                     (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) <
  569                      mdi->mdio_total_disks);
  570         }
  571 
  572         return (resurrection);
  573 }
  574 
  575 static void
  576 g_disk_md_jmicron_retaste(void *arg, int pending)
  577 {
  578 
  579         G_RAID_DEBUG(1, "Array is not complete, trying to retaste.");
  580         g_retaste(&g_raid_class);
  581         free(arg, M_MD_JMICRON);
  582 }
  583 
  584 static void
  585 g_raid_md_jmicron_refill(struct g_raid_softc *sc)
  586 {
  587         struct g_raid_md_object *md;
  588         struct g_raid_md_jmicron_object *mdi;
  589         struct g_raid_disk *disk;
  590         struct task *task;
  591         int update, na;
  592 
  593         md = sc->sc_md;
  594         mdi = (struct g_raid_md_jmicron_object *)md;
  595         update = 0;
  596         do {
  597                 /* Make sure we miss anything. */
  598                 na = g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE);
  599                 if (na == mdi->mdio_total_disks)
  600                         break;
  601 
  602                 G_RAID_DEBUG1(1, md->mdo_softc,
  603                     "Array is not complete (%d of %d), "
  604                     "trying to refill.", na, mdi->mdio_total_disks);
  605 
  606                 /* Try to get use some of STALE disks. */
  607                 TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
  608                         if (disk->d_state == G_RAID_DISK_S_STALE) {
  609                                 update += g_raid_md_jmicron_start_disk(disk);
  610                                 if (disk->d_state == G_RAID_DISK_S_ACTIVE)
  611                                         break;
  612                         }
  613                 }
  614                 if (disk != NULL)
  615                         continue;
  616 
  617                 /* Try to get use some of SPARE disks. */
  618                 TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
  619                         if (disk->d_state == G_RAID_DISK_S_SPARE) {
  620                                 update += g_raid_md_jmicron_start_disk(disk);
  621                                 if (disk->d_state == G_RAID_DISK_S_ACTIVE)
  622                                         break;
  623                         }
  624                 }
  625         } while (disk != NULL);
  626 
  627         /* Write new metadata if we changed something. */
  628         if (update)
  629                 g_raid_md_write_jmicron(md, NULL, NULL, NULL);
  630 
  631         /* Update status of our need for spare. */
  632         mdi->mdio_incomplete = (g_raid_ndisks(sc, G_RAID_DISK_S_ACTIVE) <
  633             mdi->mdio_total_disks);
  634 
  635         /* Request retaste hoping to find spare. */
  636         if (mdi->mdio_incomplete) {
  637                 task = malloc(sizeof(struct task),
  638                     M_MD_JMICRON, M_WAITOK | M_ZERO);
  639                 TASK_INIT(task, 0, g_disk_md_jmicron_retaste, task);
  640                 taskqueue_enqueue(taskqueue_swi, task);
  641         }
  642 }
  643 
  644 static void
  645 g_raid_md_jmicron_start(struct g_raid_softc *sc)
  646 {
  647         struct g_raid_md_object *md;
  648         struct g_raid_md_jmicron_object *mdi;
  649         struct g_raid_md_jmicron_perdisk *pd;
  650         struct jmicron_raid_conf *meta;
  651         struct g_raid_volume *vol;
  652         struct g_raid_subdisk *sd;
  653         struct g_raid_disk *disk;
  654         off_t size;
  655         int j, disk_pos;
  656         char buf[17];
  657 
  658         md = sc->sc_md;
  659         mdi = (struct g_raid_md_jmicron_object *)md;
  660         meta = mdi->mdio_meta;
  661 
  662         /* Create volumes and subdisks. */
  663         jmicron_meta_get_name(meta, buf);
  664         vol = g_raid_create_volume(sc, buf, -1);
  665         size = ((off_t)meta->disk_sectors_high << 16) + meta->disk_sectors_low;
  666         size *= 512; //ZZZ
  667         vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_NONE;
  668         if (meta->type == JMICRON_T_RAID0) {
  669                 vol->v_raid_level = G_RAID_VOLUME_RL_RAID0;
  670                 vol->v_mediasize = size * mdi->mdio_total_disks;
  671         } else if (meta->type == JMICRON_T_RAID1) {
  672                 vol->v_raid_level = G_RAID_VOLUME_RL_RAID1;
  673                 vol->v_mediasize = size;
  674         } else if (meta->type == JMICRON_T_RAID01) {
  675                 vol->v_raid_level = G_RAID_VOLUME_RL_RAID1E;
  676                 vol->v_mediasize = size * mdi->mdio_total_disks / 2;
  677         } else if (meta->type == JMICRON_T_CONCAT) {
  678                 if (mdi->mdio_total_disks == 1)
  679                         vol->v_raid_level = G_RAID_VOLUME_RL_SINGLE;
  680                 else
  681                         vol->v_raid_level = G_RAID_VOLUME_RL_CONCAT;
  682                 vol->v_mediasize = 0;
  683         } else if (meta->type == JMICRON_T_RAID5) {
  684                 vol->v_raid_level = G_RAID_VOLUME_RL_RAID5;
  685                 vol->v_raid_level_qualifier = G_RAID_VOLUME_RLQ_R5LA;
  686                 vol->v_mediasize = size * (mdi->mdio_total_disks - 1);
  687         } else {
  688                 vol->v_raid_level = G_RAID_VOLUME_RL_UNKNOWN;
  689                 vol->v_mediasize = 0;
  690         }
  691         vol->v_strip_size = 1024 << meta->stripe_shift; //ZZZ
  692         vol->v_disks_count = mdi->mdio_total_disks;
  693         vol->v_sectorsize = 512; //ZZZ
  694         for (j = 0; j < vol->v_disks_count; j++) {
  695                 sd = &vol->v_subdisks[j];
  696                 sd->sd_offset = (off_t)meta->offset * 16 * 512; //ZZZ
  697                 sd->sd_size = size;
  698         }
  699         g_raid_start_volume(vol);
  700 
  701         /* Create disk placeholders to store data for later writing. */
  702         for (disk_pos = 0; disk_pos < mdi->mdio_total_disks; disk_pos++) {
  703                 pd = malloc(sizeof(*pd), M_MD_JMICRON, M_WAITOK | M_ZERO);
  704                 pd->pd_disk_pos = disk_pos;
  705                 pd->pd_disk_id = meta->disks[disk_pos];
  706                 disk = g_raid_create_disk(sc);
  707                 disk->d_md_data = (void *)pd;
  708                 disk->d_state = G_RAID_DISK_S_OFFLINE;
  709                 sd = &vol->v_subdisks[disk_pos];
  710                 sd->sd_disk = disk;
  711                 TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
  712         }
  713 
  714         /* Make all disks found till the moment take their places. */
  715         do {
  716                 TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
  717                         if (disk->d_state == G_RAID_DISK_S_NONE) {
  718                                 g_raid_md_jmicron_start_disk(disk);
  719                                 break;
  720                         }
  721                 }
  722         } while (disk != NULL);
  723 
  724         mdi->mdio_started = 1;
  725         G_RAID_DEBUG1(0, sc, "Array started.");
  726         g_raid_md_write_jmicron(md, NULL, NULL, NULL);
  727 
  728         /* Pickup any STALE/SPARE disks to refill array if needed. */
  729         g_raid_md_jmicron_refill(sc);
  730 
  731         g_raid_event_send(vol, G_RAID_VOLUME_E_START, G_RAID_EVENT_VOLUME);
  732 
  733         callout_stop(&mdi->mdio_start_co);
  734         G_RAID_DEBUG1(1, sc, "root_mount_rel %p", mdi->mdio_rootmount);
  735         root_mount_rel(mdi->mdio_rootmount);
  736         mdi->mdio_rootmount = NULL;
  737 }
  738 
  739 static void
  740 g_raid_md_jmicron_new_disk(struct g_raid_disk *disk)
  741 {
  742         struct g_raid_softc *sc;
  743         struct g_raid_md_object *md;
  744         struct g_raid_md_jmicron_object *mdi;
  745         struct jmicron_raid_conf *pdmeta;
  746         struct g_raid_md_jmicron_perdisk *pd;
  747 
  748         sc = disk->d_softc;
  749         md = sc->sc_md;
  750         mdi = (struct g_raid_md_jmicron_object *)md;
  751         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
  752         pdmeta = pd->pd_meta;
  753 
  754         if (mdi->mdio_started) {
  755                 if (g_raid_md_jmicron_start_disk(disk))
  756                         g_raid_md_write_jmicron(md, NULL, NULL, NULL);
  757         } else {
  758                 /*
  759                  * If we haven't started yet - update common metadata
  760                  * to get subdisks details, avoiding data from spare disks.
  761                  */
  762                 if (mdi->mdio_meta == NULL ||
  763                     jmicron_meta_find_disk(mdi->mdio_meta,
  764                      mdi->mdio_meta->disk_id) == -3) {
  765                         if (mdi->mdio_meta != NULL)
  766                                 free(mdi->mdio_meta, M_MD_JMICRON);
  767                         mdi->mdio_meta = jmicron_meta_copy(pdmeta);
  768                         mdi->mdio_total_disks = jmicron_meta_total_disks(pdmeta);
  769                 }
  770                 mdi->mdio_meta->flags |= pdmeta->flags & JMICRON_F_BADSEC;
  771 
  772                 mdi->mdio_disks_present++;
  773                 G_RAID_DEBUG1(1, sc, "Matching disk (%d of %d+%d up)",
  774                     mdi->mdio_disks_present,
  775                     mdi->mdio_total_disks,
  776                     jmicron_meta_total_spare(mdi->mdio_meta));
  777 
  778                 /* If we collected all needed disks - start array. */
  779                 if (mdi->mdio_disks_present == mdi->mdio_total_disks +
  780                     jmicron_meta_total_spare(mdi->mdio_meta))
  781                         g_raid_md_jmicron_start(sc);
  782         }
  783 }
  784 
  785 static void
  786 g_raid_jmicron_go(void *arg)
  787 {
  788         struct g_raid_softc *sc;
  789         struct g_raid_md_object *md;
  790         struct g_raid_md_jmicron_object *mdi;
  791 
  792         sc = arg;
  793         md = sc->sc_md;
  794         mdi = (struct g_raid_md_jmicron_object *)md;
  795         if (!mdi->mdio_started) {
  796                 G_RAID_DEBUG1(0, sc, "Force array start due to timeout.");
  797                 g_raid_event_send(sc, G_RAID_NODE_E_START, 0);
  798         }
  799 }
  800 
  801 static int
  802 g_raid_md_create_jmicron(struct g_raid_md_object *md, struct g_class *mp,
  803     struct g_geom **gp)
  804 {
  805         struct g_raid_softc *sc;
  806         struct g_raid_md_jmicron_object *mdi;
  807         char name[16];
  808 
  809         mdi = (struct g_raid_md_jmicron_object *)md;
  810         mdi->mdio_config_id = arc4random();
  811         snprintf(name, sizeof(name), "JMicron-%08x", mdi->mdio_config_id);
  812         sc = g_raid_create_node(mp, name, md);
  813         if (sc == NULL)
  814                 return (G_RAID_MD_TASTE_FAIL);
  815         md->mdo_softc = sc;
  816         *gp = sc->sc_geom;
  817         return (G_RAID_MD_TASTE_NEW);
  818 }
  819 
  820 static int
  821 g_raid_md_taste_jmicron(struct g_raid_md_object *md, struct g_class *mp,
  822                               struct g_consumer *cp, struct g_geom **gp)
  823 {
  824         struct g_consumer *rcp;
  825         struct g_provider *pp;
  826         struct g_raid_md_jmicron_object *mdi, *mdi1;
  827         struct g_raid_softc *sc;
  828         struct g_raid_disk *disk;
  829         struct jmicron_raid_conf *meta;
  830         struct g_raid_md_jmicron_perdisk *pd;
  831         struct g_geom *geom;
  832         int disk_pos, result, spare, len;
  833         char name[16];
  834         uint16_t vendor;
  835 
  836         G_RAID_DEBUG(1, "Tasting JMicron on %s", cp->provider->name);
  837         mdi = (struct g_raid_md_jmicron_object *)md;
  838         pp = cp->provider;
  839 
  840         /* Read metadata from device. */
  841         meta = NULL;
  842         g_topology_unlock();
  843         vendor = 0xffff;
  844         len = sizeof(vendor);
  845         if (pp->geom->rank == 1)
  846                 g_io_getattr("GEOM::hba_vendor", cp, &len, &vendor);
  847         meta = jmicron_meta_read(cp);
  848         g_topology_lock();
  849         if (meta == NULL) {
  850                 if (g_raid_aggressive_spare) {
  851                         if (vendor == 0x197b) {
  852                                 G_RAID_DEBUG(1,
  853                                     "No JMicron metadata, forcing spare.");
  854                                 spare = 2;
  855                                 goto search;
  856                         } else {
  857                                 G_RAID_DEBUG(1,
  858                                     "JMicron vendor mismatch 0x%04x != 0x197b",
  859                                     vendor);
  860                         }
  861                 }
  862                 return (G_RAID_MD_TASTE_FAIL);
  863         }
  864 
  865         /* Check this disk position in obtained metadata. */
  866         disk_pos = jmicron_meta_find_disk(meta, meta->disk_id);
  867         if (disk_pos == -1) {
  868                 G_RAID_DEBUG(1, "JMicron disk_id %08x not found",
  869                     meta->disk_id);
  870                 goto fail1;
  871         }
  872 
  873         /* Metadata valid. Print it. */
  874         g_raid_md_jmicron_print(meta);
  875         G_RAID_DEBUG(1, "JMicron disk position %d", disk_pos);
  876         spare = (disk_pos == -2) ? 1 : 0;
  877 
  878 search:
  879         /* Search for matching node. */
  880         sc = NULL;
  881         mdi1 = NULL;
  882         LIST_FOREACH(geom, &mp->geom, geom) {
  883                 sc = geom->softc;
  884                 if (sc == NULL)
  885                         continue;
  886                 if (sc->sc_stopping != 0)
  887                         continue;
  888                 if (sc->sc_md->mdo_class != md->mdo_class)
  889                         continue;
  890                 mdi1 = (struct g_raid_md_jmicron_object *)sc->sc_md;
  891                 if (spare == 2) {
  892                         if (mdi1->mdio_incomplete)
  893                                 break;
  894                 } else {
  895                         if (mdi1->mdio_config_id ==
  896                             jmicron_meta_config_id(meta))
  897                                 break;
  898                 }
  899         }
  900 
  901         /* Found matching node. */
  902         if (geom != NULL) {
  903                 G_RAID_DEBUG(1, "Found matching array %s", sc->sc_name);
  904                 result = G_RAID_MD_TASTE_EXISTING;
  905 
  906         } else if (spare) { /* Not found needy node -- left for later. */
  907                 G_RAID_DEBUG(1, "Spare is not needed at this time");
  908                 goto fail1;
  909 
  910         } else { /* Not found matching node -- create one. */
  911                 result = G_RAID_MD_TASTE_NEW;
  912                 mdi->mdio_config_id = jmicron_meta_config_id(meta);
  913                 snprintf(name, sizeof(name), "JMicron-%08x",
  914                     mdi->mdio_config_id);
  915                 sc = g_raid_create_node(mp, name, md);
  916                 md->mdo_softc = sc;
  917                 geom = sc->sc_geom;
  918                 callout_init(&mdi->mdio_start_co, 1);
  919                 callout_reset(&mdi->mdio_start_co, g_raid_start_timeout * hz,
  920                     g_raid_jmicron_go, sc);
  921                 mdi->mdio_rootmount = root_mount_hold("GRAID-JMicron");
  922                 G_RAID_DEBUG1(1, sc, "root_mount_hold %p", mdi->mdio_rootmount);
  923         }
  924 
  925         /* There is no return after this point, so we close passed consumer. */
  926         g_access(cp, -1, 0, 0);
  927 
  928         rcp = g_new_consumer(geom);
  929         rcp->flags |= G_CF_DIRECT_RECEIVE;
  930         g_attach(rcp, pp);
  931         if (g_access(rcp, 1, 1, 1) != 0)
  932                 ; //goto fail1;
  933 
  934         g_topology_unlock();
  935         sx_xlock(&sc->sc_lock);
  936 
  937         pd = malloc(sizeof(*pd), M_MD_JMICRON, M_WAITOK | M_ZERO);
  938         pd->pd_meta = meta;
  939         if (spare == 2) {
  940                 pd->pd_disk_pos = -3;
  941                 pd->pd_disk_id = arc4random() & JMICRON_DISK_MASK;
  942         } else {
  943                 pd->pd_disk_pos = -1;
  944                 pd->pd_disk_id = meta->disk_id;
  945         }
  946         pd->pd_disk_size = pp->mediasize;
  947         disk = g_raid_create_disk(sc);
  948         disk->d_md_data = (void *)pd;
  949         disk->d_consumer = rcp;
  950         rcp->private = disk;
  951 
  952         g_raid_get_disk_info(disk);
  953 
  954         g_raid_md_jmicron_new_disk(disk);
  955 
  956         sx_xunlock(&sc->sc_lock);
  957         g_topology_lock();
  958         *gp = geom;
  959         return (result);
  960 fail1:
  961         free(meta, M_MD_JMICRON);
  962         return (G_RAID_MD_TASTE_FAIL);
  963 }
  964 
  965 static int
  966 g_raid_md_event_jmicron(struct g_raid_md_object *md,
  967     struct g_raid_disk *disk, u_int event)
  968 {
  969         struct g_raid_softc *sc;
  970         struct g_raid_subdisk *sd;
  971         struct g_raid_md_jmicron_object *mdi;
  972         struct g_raid_md_jmicron_perdisk *pd;
  973 
  974         sc = md->mdo_softc;
  975         mdi = (struct g_raid_md_jmicron_object *)md;
  976         if (disk == NULL) {
  977                 switch (event) {
  978                 case G_RAID_NODE_E_START:
  979                         if (!mdi->mdio_started)
  980                                 g_raid_md_jmicron_start(sc);
  981                         return (0);
  982                 }
  983                 return (-1);
  984         }
  985         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
  986         switch (event) {
  987         case G_RAID_DISK_E_DISCONNECTED:
  988                 /* If disk was assigned, just update statuses. */
  989                 if (pd->pd_disk_pos >= 0) {
  990                         g_raid_change_disk_state(disk, G_RAID_DISK_S_OFFLINE);
  991                         if (disk->d_consumer) {
  992                                 g_raid_kill_consumer(sc, disk->d_consumer);
  993                                 disk->d_consumer = NULL;
  994                         }
  995                         TAILQ_FOREACH(sd, &disk->d_subdisks, sd_next) {
  996                                 g_raid_change_subdisk_state(sd,
  997                                     G_RAID_SUBDISK_S_NONE);
  998                                 g_raid_event_send(sd, G_RAID_SUBDISK_E_DISCONNECTED,
  999                                     G_RAID_EVENT_SUBDISK);
 1000                         }
 1001                 } else {
 1002                         /* Otherwise -- delete. */
 1003                         g_raid_change_disk_state(disk, G_RAID_DISK_S_NONE);
 1004                         g_raid_destroy_disk(disk);
 1005                 }
 1006 
 1007                 /* Write updated metadata to all disks. */
 1008                 g_raid_md_write_jmicron(md, NULL, NULL, NULL);
 1009 
 1010                 /* Check if anything left except placeholders. */
 1011                 if (g_raid_ndisks(sc, -1) ==
 1012                     g_raid_ndisks(sc, G_RAID_DISK_S_OFFLINE))
 1013                         g_raid_destroy_node(sc, 0);
 1014                 else
 1015                         g_raid_md_jmicron_refill(sc);
 1016                 return (0);
 1017         }
 1018         return (-2);
 1019 }
 1020 
 1021 static int
 1022 g_raid_md_ctl_jmicron(struct g_raid_md_object *md,
 1023     struct gctl_req *req)
 1024 {
 1025         struct g_raid_softc *sc;
 1026         struct g_raid_volume *vol;
 1027         struct g_raid_subdisk *sd;
 1028         struct g_raid_disk *disk;
 1029         struct g_raid_md_jmicron_object *mdi;
 1030         struct g_raid_md_jmicron_perdisk *pd;
 1031         struct g_consumer *cp;
 1032         struct g_provider *pp;
 1033         char arg[16];
 1034         const char *verb, *volname, *levelname, *diskname;
 1035         int *nargs, *force;
 1036         off_t size, sectorsize, strip;
 1037         intmax_t *sizearg, *striparg;
 1038         int numdisks, i, len, level, qual, update;
 1039         int error;
 1040 
 1041         sc = md->mdo_softc;
 1042         mdi = (struct g_raid_md_jmicron_object *)md;
 1043         verb = gctl_get_param(req, "verb", NULL);
 1044         nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs));
 1045         error = 0;
 1046         if (strcmp(verb, "label") == 0) {
 1047                 if (*nargs < 4) {
 1048                         gctl_error(req, "Invalid number of arguments.");
 1049                         return (-1);
 1050                 }
 1051                 volname = gctl_get_asciiparam(req, "arg1");
 1052                 if (volname == NULL) {
 1053                         gctl_error(req, "No volume name.");
 1054                         return (-2);
 1055                 }
 1056                 levelname = gctl_get_asciiparam(req, "arg2");
 1057                 if (levelname == NULL) {
 1058                         gctl_error(req, "No RAID level.");
 1059                         return (-3);
 1060                 }
 1061                 if (strcasecmp(levelname, "RAID5") == 0)
 1062                         levelname = "RAID5-LA";
 1063                 if (g_raid_volume_str2level(levelname, &level, &qual)) {
 1064                         gctl_error(req, "Unknown RAID level '%s'.", levelname);
 1065                         return (-4);
 1066                 }
 1067                 numdisks = *nargs - 3;
 1068                 force = gctl_get_paraml(req, "force", sizeof(*force));
 1069                 if (!g_raid_md_jmicron_supported(level, qual, numdisks,
 1070                     force ? *force : 0)) {
 1071                         gctl_error(req, "Unsupported RAID level "
 1072                             "(0x%02x/0x%02x), or number of disks (%d).",
 1073                             level, qual, numdisks);
 1074                         return (-5);
 1075                 }
 1076 
 1077                 /* Search for disks, connect them and probe. */
 1078                 size = 0x7fffffffffffffffllu;
 1079                 sectorsize = 0;
 1080                 for (i = 0; i < numdisks; i++) {
 1081                         snprintf(arg, sizeof(arg), "arg%d", i + 3);
 1082                         diskname = gctl_get_asciiparam(req, arg);
 1083                         if (diskname == NULL) {
 1084                                 gctl_error(req, "No disk name (%s).", arg);
 1085                                 error = -6;
 1086                                 break;
 1087                         }
 1088                         if (strcmp(diskname, "NONE") == 0) {
 1089                                 cp = NULL;
 1090                                 pp = NULL;
 1091                         } else {
 1092                                 g_topology_lock();
 1093                                 cp = g_raid_open_consumer(sc, diskname);
 1094                                 if (cp == NULL) {
 1095                                         gctl_error(req, "Can't open '%s'.",
 1096                                             diskname);
 1097                                         g_topology_unlock();
 1098                                         error = -7;
 1099                                         break;
 1100                                 }
 1101                                 pp = cp->provider;
 1102                         }
 1103                         pd = malloc(sizeof(*pd), M_MD_JMICRON, M_WAITOK | M_ZERO);
 1104                         pd->pd_disk_pos = i;
 1105                         pd->pd_disk_id = arc4random() & JMICRON_DISK_MASK;
 1106                         disk = g_raid_create_disk(sc);
 1107                         disk->d_md_data = (void *)pd;
 1108                         disk->d_consumer = cp;
 1109                         if (cp == NULL)
 1110                                 continue;
 1111                         cp->private = disk;
 1112                         g_topology_unlock();
 1113 
 1114                         g_raid_get_disk_info(disk);
 1115 
 1116                         pd->pd_disk_size = pp->mediasize;
 1117                         if (size > pp->mediasize)
 1118                                 size = pp->mediasize;
 1119                         if (sectorsize < pp->sectorsize)
 1120                                 sectorsize = pp->sectorsize;
 1121                 }
 1122                 if (error != 0)
 1123                         return (error);
 1124 
 1125                 if (sectorsize <= 0) {
 1126                         gctl_error(req, "Can't get sector size.");
 1127                         return (-8);
 1128                 }
 1129 
 1130                 /* Reserve space for metadata. */
 1131                 size -= sectorsize;
 1132 
 1133                 /* Handle size argument. */
 1134                 len = sizeof(*sizearg);
 1135                 sizearg = gctl_get_param(req, "size", &len);
 1136                 if (sizearg != NULL && len == sizeof(*sizearg) &&
 1137                     *sizearg > 0) {
 1138                         if (*sizearg > size) {
 1139                                 gctl_error(req, "Size too big %lld > %lld.",
 1140                                     (long long)*sizearg, (long long)size);
 1141                                 return (-9);
 1142                         }
 1143                         size = *sizearg;
 1144                 }
 1145 
 1146                 /* Handle strip argument. */
 1147                 strip = 131072;
 1148                 len = sizeof(*striparg);
 1149                 striparg = gctl_get_param(req, "strip", &len);
 1150                 if (striparg != NULL && len == sizeof(*striparg) &&
 1151                     *striparg > 0) {
 1152                         if (*striparg < sectorsize) {
 1153                                 gctl_error(req, "Strip size too small.");
 1154                                 return (-10);
 1155                         }
 1156                         if (*striparg % sectorsize != 0) {
 1157                                 gctl_error(req, "Incorrect strip size.");
 1158                                 return (-11);
 1159                         }
 1160                         if (strip > 65535 * sectorsize) {
 1161                                 gctl_error(req, "Strip size too big.");
 1162                                 return (-12);
 1163                         }
 1164                         strip = *striparg;
 1165                 }
 1166 
 1167                 /* Round size down to strip or sector. */
 1168                 if (level == G_RAID_VOLUME_RL_RAID1)
 1169                         size -= (size % sectorsize);
 1170                 else if (level == G_RAID_VOLUME_RL_RAID1E &&
 1171                     (numdisks & 1) != 0)
 1172                         size -= (size % (2 * strip));
 1173                 else
 1174                         size -= (size % strip);
 1175                 if (size <= 0) {
 1176                         gctl_error(req, "Size too small.");
 1177                         return (-13);
 1178                 }
 1179                 if (size > 0xffffffffffffllu * sectorsize) {
 1180                         gctl_error(req, "Size too big.");
 1181                         return (-14);
 1182                 }
 1183 
 1184                 /* We have all we need, create things: volume, ... */
 1185                 mdi->mdio_total_disks = numdisks;
 1186                 mdi->mdio_started = 1;
 1187                 vol = g_raid_create_volume(sc, volname, -1);
 1188                 vol->v_md_data = (void *)(intptr_t)0;
 1189                 vol->v_raid_level = level;
 1190                 vol->v_raid_level_qualifier = qual;
 1191                 vol->v_strip_size = strip;
 1192                 vol->v_disks_count = numdisks;
 1193                 if (level == G_RAID_VOLUME_RL_RAID0 ||
 1194                     level == G_RAID_VOLUME_RL_CONCAT ||
 1195                     level == G_RAID_VOLUME_RL_SINGLE)
 1196                         vol->v_mediasize = size * numdisks;
 1197                 else if (level == G_RAID_VOLUME_RL_RAID1)
 1198                         vol->v_mediasize = size;
 1199                 else if (level == G_RAID_VOLUME_RL_RAID5)
 1200                         vol->v_mediasize = size * (numdisks - 1);
 1201                 else { /* RAID1E */
 1202                         vol->v_mediasize = ((size * numdisks) / strip / 2) *
 1203                             strip;
 1204                 }
 1205                 vol->v_sectorsize = sectorsize;
 1206                 g_raid_start_volume(vol);
 1207 
 1208                 /* , and subdisks. */
 1209                 TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 1210                         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
 1211                         sd = &vol->v_subdisks[pd->pd_disk_pos];
 1212                         sd->sd_disk = disk;
 1213                         sd->sd_offset = 0;
 1214                         sd->sd_size = size;
 1215                         TAILQ_INSERT_TAIL(&disk->d_subdisks, sd, sd_next);
 1216                         if (sd->sd_disk->d_consumer != NULL) {
 1217                                 g_raid_change_disk_state(disk,
 1218                                     G_RAID_DISK_S_ACTIVE);
 1219                                 g_raid_change_subdisk_state(sd,
 1220                                     G_RAID_SUBDISK_S_ACTIVE);
 1221                                 g_raid_event_send(sd, G_RAID_SUBDISK_E_NEW,
 1222                                     G_RAID_EVENT_SUBDISK);
 1223                         } else {
 1224                                 g_raid_change_disk_state(disk, G_RAID_DISK_S_OFFLINE);
 1225                         }
 1226                 }
 1227 
 1228                 /* Write metadata based on created entities. */
 1229                 G_RAID_DEBUG1(0, sc, "Array started.");
 1230                 g_raid_md_write_jmicron(md, NULL, NULL, NULL);
 1231 
 1232                 /* Pickup any STALE/SPARE disks to refill array if needed. */
 1233                 g_raid_md_jmicron_refill(sc);
 1234 
 1235                 g_raid_event_send(vol, G_RAID_VOLUME_E_START,
 1236                     G_RAID_EVENT_VOLUME);
 1237                 return (0);
 1238         }
 1239         if (strcmp(verb, "delete") == 0) {
 1240                 /* Check if some volume is still open. */
 1241                 force = gctl_get_paraml(req, "force", sizeof(*force));
 1242                 if (force != NULL && *force == 0 &&
 1243                     g_raid_nopens(sc) != 0) {
 1244                         gctl_error(req, "Some volume is still open.");
 1245                         return (-4);
 1246                 }
 1247 
 1248                 TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 1249                         if (disk->d_consumer)
 1250                                 jmicron_meta_erase(disk->d_consumer);
 1251                 }
 1252                 g_raid_destroy_node(sc, 0);
 1253                 return (0);
 1254         }
 1255         if (strcmp(verb, "remove") == 0 ||
 1256             strcmp(verb, "fail") == 0) {
 1257                 if (*nargs < 2) {
 1258                         gctl_error(req, "Invalid number of arguments.");
 1259                         return (-1);
 1260                 }
 1261                 for (i = 1; i < *nargs; i++) {
 1262                         snprintf(arg, sizeof(arg), "arg%d", i);
 1263                         diskname = gctl_get_asciiparam(req, arg);
 1264                         if (diskname == NULL) {
 1265                                 gctl_error(req, "No disk name (%s).", arg);
 1266                                 error = -2;
 1267                                 break;
 1268                         }
 1269                         if (strncmp(diskname, _PATH_DEV, 5) == 0)
 1270                                 diskname += 5;
 1271 
 1272                         TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 1273                                 if (disk->d_consumer != NULL && 
 1274                                     disk->d_consumer->provider != NULL &&
 1275                                     strcmp(disk->d_consumer->provider->name,
 1276                                      diskname) == 0)
 1277                                         break;
 1278                         }
 1279                         if (disk == NULL) {
 1280                                 gctl_error(req, "Disk '%s' not found.",
 1281                                     diskname);
 1282                                 error = -3;
 1283                                 break;
 1284                         }
 1285 
 1286                         if (strcmp(verb, "fail") == 0) {
 1287                                 g_raid_md_fail_disk_jmicron(md, NULL, disk);
 1288                                 continue;
 1289                         }
 1290 
 1291                         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
 1292 
 1293                         /* Erase metadata on deleting disk. */
 1294                         jmicron_meta_erase(disk->d_consumer);
 1295 
 1296                         /* If disk was assigned, just update statuses. */
 1297                         if (pd->pd_disk_pos >= 0) {
 1298                                 g_raid_change_disk_state(disk, G_RAID_DISK_S_OFFLINE);
 1299                                 g_raid_kill_consumer(sc, disk->d_consumer);
 1300                                 disk->d_consumer = NULL;
 1301                                 TAILQ_FOREACH(sd, &disk->d_subdisks, sd_next) {
 1302                                         g_raid_change_subdisk_state(sd,
 1303                                             G_RAID_SUBDISK_S_NONE);
 1304                                         g_raid_event_send(sd, G_RAID_SUBDISK_E_DISCONNECTED,
 1305                                             G_RAID_EVENT_SUBDISK);
 1306                                 }
 1307                         } else {
 1308                                 /* Otherwise -- delete. */
 1309                                 g_raid_change_disk_state(disk, G_RAID_DISK_S_NONE);
 1310                                 g_raid_destroy_disk(disk);
 1311                         }
 1312                 }
 1313 
 1314                 /* Write updated metadata to remaining disks. */
 1315                 g_raid_md_write_jmicron(md, NULL, NULL, NULL);
 1316 
 1317                 /* Check if anything left except placeholders. */
 1318                 if (g_raid_ndisks(sc, -1) ==
 1319                     g_raid_ndisks(sc, G_RAID_DISK_S_OFFLINE))
 1320                         g_raid_destroy_node(sc, 0);
 1321                 else
 1322                         g_raid_md_jmicron_refill(sc);
 1323                 return (error);
 1324         }
 1325         if (strcmp(verb, "insert") == 0) {
 1326                 if (*nargs < 2) {
 1327                         gctl_error(req, "Invalid number of arguments.");
 1328                         return (-1);
 1329                 }
 1330                 update = 0;
 1331                 for (i = 1; i < *nargs; i++) {
 1332                         /* Get disk name. */
 1333                         snprintf(arg, sizeof(arg), "arg%d", i);
 1334                         diskname = gctl_get_asciiparam(req, arg);
 1335                         if (diskname == NULL) {
 1336                                 gctl_error(req, "No disk name (%s).", arg);
 1337                                 error = -3;
 1338                                 break;
 1339                         }
 1340 
 1341                         /* Try to find provider with specified name. */
 1342                         g_topology_lock();
 1343                         cp = g_raid_open_consumer(sc, diskname);
 1344                         if (cp == NULL) {
 1345                                 gctl_error(req, "Can't open disk '%s'.",
 1346                                     diskname);
 1347                                 g_topology_unlock();
 1348                                 error = -4;
 1349                                 break;
 1350                         }
 1351                         pp = cp->provider;
 1352 
 1353                         pd = malloc(sizeof(*pd), M_MD_JMICRON, M_WAITOK | M_ZERO);
 1354                         pd->pd_disk_pos = -3;
 1355                         pd->pd_disk_id = arc4random() & JMICRON_DISK_MASK;
 1356                         pd->pd_disk_size = pp->mediasize;
 1357 
 1358                         disk = g_raid_create_disk(sc);
 1359                         disk->d_consumer = cp;
 1360                         disk->d_md_data = (void *)pd;
 1361                         cp->private = disk;
 1362                         g_topology_unlock();
 1363 
 1364                         g_raid_get_disk_info(disk);
 1365 
 1366                         /* Welcome the "new" disk. */
 1367                         update += g_raid_md_jmicron_start_disk(disk);
 1368                         if (disk->d_state != G_RAID_DISK_S_ACTIVE &&
 1369                             disk->d_state != G_RAID_DISK_S_SPARE) {
 1370                                 gctl_error(req, "Disk '%s' doesn't fit.",
 1371                                     diskname);
 1372                                 g_raid_destroy_disk(disk);
 1373                                 error = -8;
 1374                                 break;
 1375                         }
 1376                 }
 1377 
 1378                 /* Write new metadata if we changed something. */
 1379                 if (update)
 1380                         g_raid_md_write_jmicron(md, NULL, NULL, NULL);
 1381                 return (error);
 1382         }
 1383         gctl_error(req, "Command '%s' is not supported.", verb);
 1384         return (-100);
 1385 }
 1386 
 1387 static int
 1388 g_raid_md_write_jmicron(struct g_raid_md_object *md, struct g_raid_volume *tvol,
 1389     struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
 1390 {
 1391         struct g_raid_softc *sc;
 1392         struct g_raid_volume *vol;
 1393         struct g_raid_subdisk *sd;
 1394         struct g_raid_disk *disk;
 1395         struct g_raid_md_jmicron_object *mdi;
 1396         struct g_raid_md_jmicron_perdisk *pd;
 1397         struct jmicron_raid_conf *meta;
 1398         int i, spares;
 1399 
 1400         sc = md->mdo_softc;
 1401         mdi = (struct g_raid_md_jmicron_object *)md;
 1402 
 1403         if (sc->sc_stopping == G_RAID_DESTROY_HARD)
 1404                 return (0);
 1405 
 1406         /* There is only one volume. */
 1407         vol = TAILQ_FIRST(&sc->sc_volumes);
 1408 
 1409         /* Fill global fields. */
 1410         meta = malloc(sizeof(*meta), M_MD_JMICRON, M_WAITOK | M_ZERO);
 1411         strncpy(meta->signature, JMICRON_MAGIC, 2);
 1412         meta->version = JMICRON_VERSION;
 1413         jmicron_meta_put_name(meta, vol->v_name);
 1414         if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID0)
 1415                 meta->type = JMICRON_T_RAID0;
 1416         else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1)
 1417                 meta->type = JMICRON_T_RAID1;
 1418         else if (vol->v_raid_level == G_RAID_VOLUME_RL_RAID1E)
 1419                 meta->type = JMICRON_T_RAID01;
 1420         else if (vol->v_raid_level == G_RAID_VOLUME_RL_CONCAT ||
 1421             vol->v_raid_level == G_RAID_VOLUME_RL_SINGLE)
 1422                 meta->type = JMICRON_T_CONCAT;
 1423         else
 1424                 meta->type = JMICRON_T_RAID5;
 1425         meta->stripe_shift = fls(vol->v_strip_size / 2048);
 1426         meta->flags = JMICRON_F_READY | JMICRON_F_BOOTABLE;
 1427         for (i = 0; i < vol->v_disks_count; i++) {
 1428                 sd = &vol->v_subdisks[i];
 1429                 if (sd->sd_disk == NULL || sd->sd_disk->d_md_data == NULL)
 1430                         meta->disks[i] = 0xffffffff;
 1431                 else {
 1432                         pd = (struct g_raid_md_jmicron_perdisk *)
 1433                             sd->sd_disk->d_md_data;
 1434                         meta->disks[i] = pd->pd_disk_id;
 1435                 }
 1436                 if (sd->sd_state < G_RAID_SUBDISK_S_STALE)
 1437                         meta->flags |= JMICRON_F_BADSEC;
 1438                 if (vol->v_dirty)
 1439                         meta->flags |= JMICRON_F_UNSYNC;
 1440         }
 1441 
 1442         /* Put spares to their slots. */
 1443         spares = 0;
 1444         TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 1445                 pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
 1446                 if (disk->d_state != G_RAID_DISK_S_SPARE)
 1447                         continue;
 1448                 meta->spare[spares] = pd->pd_disk_id;
 1449                 if (++spares >= 2)
 1450                         break;
 1451         }
 1452 
 1453         /* We are done. Print meta data and store them to disks. */
 1454         if (mdi->mdio_meta != NULL)
 1455                 free(mdi->mdio_meta, M_MD_JMICRON);
 1456         mdi->mdio_meta = meta;
 1457         TAILQ_FOREACH(disk, &sc->sc_disks, d_next) {
 1458                 pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
 1459                 if (disk->d_state != G_RAID_DISK_S_ACTIVE &&
 1460                     disk->d_state != G_RAID_DISK_S_SPARE)
 1461                         continue;
 1462                 if (pd->pd_meta != NULL) {
 1463                         free(pd->pd_meta, M_MD_JMICRON);
 1464                         pd->pd_meta = NULL;
 1465                 }
 1466                 pd->pd_meta = jmicron_meta_copy(meta);
 1467                 pd->pd_meta->disk_id = pd->pd_disk_id;
 1468                 if ((sd = TAILQ_FIRST(&disk->d_subdisks)) != NULL) {
 1469                         pd->pd_meta->offset =
 1470                             (sd->sd_offset / 512) / 16;
 1471                         pd->pd_meta->disk_sectors_high =
 1472                             (sd->sd_size / 512) >> 16;
 1473                         pd->pd_meta->disk_sectors_low =
 1474                             (sd->sd_size / 512) & 0xffff;
 1475                         if (sd->sd_state < G_RAID_SUBDISK_S_STALE)
 1476                                 pd->pd_meta->flags &= ~JMICRON_F_BADSEC;
 1477                         else if (sd->sd_state < G_RAID_SUBDISK_S_ACTIVE)
 1478                                 pd->pd_meta->flags |= JMICRON_F_UNSYNC;
 1479                 }
 1480                 G_RAID_DEBUG(1, "Writing JMicron metadata to %s",
 1481                     g_raid_get_diskname(disk));
 1482                 g_raid_md_jmicron_print(pd->pd_meta);
 1483                 jmicron_meta_write(disk->d_consumer, pd->pd_meta);
 1484         }
 1485         return (0);
 1486 }
 1487 
 1488 static int
 1489 g_raid_md_fail_disk_jmicron(struct g_raid_md_object *md,
 1490     struct g_raid_subdisk *tsd, struct g_raid_disk *tdisk)
 1491 {
 1492         struct g_raid_softc *sc;
 1493         struct g_raid_md_jmicron_perdisk *pd;
 1494         struct g_raid_subdisk *sd;
 1495 
 1496         sc = md->mdo_softc;
 1497         pd = (struct g_raid_md_jmicron_perdisk *)tdisk->d_md_data;
 1498 
 1499         /* We can't fail disk that is not a part of array now. */
 1500         if (pd->pd_disk_pos < 0)
 1501                 return (-1);
 1502 
 1503         if (tdisk->d_consumer)
 1504                 jmicron_meta_erase(tdisk->d_consumer);
 1505 
 1506         /* Change states. */
 1507         g_raid_change_disk_state(tdisk, G_RAID_DISK_S_FAILED);
 1508         TAILQ_FOREACH(sd, &tdisk->d_subdisks, sd_next) {
 1509                 g_raid_change_subdisk_state(sd,
 1510                     G_RAID_SUBDISK_S_FAILED);
 1511                 g_raid_event_send(sd, G_RAID_SUBDISK_E_FAILED,
 1512                     G_RAID_EVENT_SUBDISK);
 1513         }
 1514 
 1515         /* Write updated metadata to remaining disks. */
 1516         g_raid_md_write_jmicron(md, NULL, NULL, tdisk);
 1517 
 1518         /* Check if anything left except placeholders. */
 1519         if (g_raid_ndisks(sc, -1) ==
 1520             g_raid_ndisks(sc, G_RAID_DISK_S_OFFLINE))
 1521                 g_raid_destroy_node(sc, 0);
 1522         else
 1523                 g_raid_md_jmicron_refill(sc);
 1524         return (0);
 1525 }
 1526 
 1527 static int
 1528 g_raid_md_free_disk_jmicron(struct g_raid_md_object *md,
 1529     struct g_raid_disk *disk)
 1530 {
 1531         struct g_raid_md_jmicron_perdisk *pd;
 1532 
 1533         pd = (struct g_raid_md_jmicron_perdisk *)disk->d_md_data;
 1534         if (pd->pd_meta != NULL) {
 1535                 free(pd->pd_meta, M_MD_JMICRON);
 1536                 pd->pd_meta = NULL;
 1537         }
 1538         free(pd, M_MD_JMICRON);
 1539         disk->d_md_data = NULL;
 1540         return (0);
 1541 }
 1542 
 1543 static int
 1544 g_raid_md_free_jmicron(struct g_raid_md_object *md)
 1545 {
 1546         struct g_raid_md_jmicron_object *mdi;
 1547 
 1548         mdi = (struct g_raid_md_jmicron_object *)md;
 1549         if (!mdi->mdio_started) {
 1550                 mdi->mdio_started = 0;
 1551                 callout_stop(&mdi->mdio_start_co);
 1552                 G_RAID_DEBUG1(1, md->mdo_softc,
 1553                     "root_mount_rel %p", mdi->mdio_rootmount);
 1554                 root_mount_rel(mdi->mdio_rootmount);
 1555                 mdi->mdio_rootmount = NULL;
 1556         }
 1557         if (mdi->mdio_meta != NULL) {
 1558                 free(mdi->mdio_meta, M_MD_JMICRON);
 1559                 mdi->mdio_meta = NULL;
 1560         }
 1561         return (0);
 1562 }
 1563 
 1564 G_RAID_MD_DECLARE(jmicron, "JMicron");

Cache object: 726cd500374a75039ceb7be34e6413ae


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.