root/dev/softraidvar.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


    1 /* $OpenBSD: softraidvar.h,v 1.32 2007/06/06 23:06:02 deraadt Exp $ */
    2 /*
    3  * Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
    4  *
    5  * Permission to use, copy, modify, and distribute this software for any
    6  * purpose with or without fee is hereby granted, provided that the above
    7  * copyright notice and this permission notice appear in all copies.
    8  *
    9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   16  */
   17 
   18 #include <dev/biovar.h>
   19 
   20 #include <sys/buf.h>
   21 #include <sys/queue.h>
   22 #include <sys/rwlock.h>
   23 
   24 #include <scsi/scsi_all.h>
   25 #include <scsi/scsi_disk.h>
   26 #include <scsi/scsiconf.h>
   27 
   28 #define DEVNAME(_s)     ((_s)->sc_dev.dv_xname)
   29 
   30 /* #define SR_DEBUG */
   31 #ifdef SR_DEBUG
   32 extern u_int32_t                sr_debug;
   33 #define DPRINTF(x...)           do { if (sr_debug) printf(x); } while(0)
   34 #define DNPRINTF(n,x...)        do { if (sr_debug & n) printf(x); } while(0)
   35 #define SR_D_CMD                0x0001
   36 #define SR_D_INTR               0x0002
   37 #define SR_D_MISC               0x0004
   38 #define SR_D_IOCTL              0x0008
   39 #define SR_D_CCB                0x0010
   40 #define SR_D_WU                 0x0020
   41 #define SR_D_META               0x0040
   42 #define SR_D_DIS                0x0080
   43 #define SR_D_STATE              0x0100
   44 #else
   45 #define DPRINTF(x...)
   46 #define DNPRINTF(n,x...)
   47 #endif
   48 
   49 #define SR_MAXFER               MAXPHYS
   50 #define SR_MAX_LD               1
   51 #define SR_MAX_CMDS             16
   52 #define SR_MAX_STATES           7
   53 
   54 /* forward define to prevent dependency goo */
   55 struct sr_softc;
   56 
   57 #define SR_UUID_MAX             4
   58 struct sr_uuid {
   59         u_int32_t               sui_id[SR_UUID_MAX];
   60 } __packed;
   61 
   62 struct sr_ccb {
   63         struct buf              ccb_buf;        /* MUST BE FIRST!! */
   64 
   65         struct sr_workunit      *ccb_wu;
   66         struct sr_discipline    *ccb_dis;
   67 
   68         int                     ccb_target;
   69         int                     ccb_state;
   70 #define SR_CCB_FREE             0
   71 #define SR_CCB_INPROGRESS       1
   72 #define SR_CCB_OK               2
   73 #define SR_CCB_FAILED           3
   74 
   75         TAILQ_ENTRY(sr_ccb)     ccb_link;
   76 } __packed;
   77 
   78 TAILQ_HEAD(sr_ccb_list, sr_ccb);
   79 
   80 struct sr_workunit {
   81         struct scsi_xfer        *swu_xs;
   82         struct sr_discipline    *swu_dis;
   83 
   84         int                     swu_state;
   85 #define SR_WU_FREE              0
   86 #define SR_WU_INPROGRESS        1
   87 #define SR_WU_OK                2
   88 #define SR_WU_FAILED            3
   89 #define SR_WU_PARTIALLYFAILED   4
   90 #define SR_WU_DEFERRED          5
   91 #define SR_WU_PENDING           6
   92 #define SR_WU_RESTART           7
   93 #define SR_WU_REQUEUE           8
   94 
   95         int                     swu_fake;       /* faked wu */
   96         /* workunit io range */
   97         daddr64_t               swu_blk_start;
   98         daddr64_t               swu_blk_end;
   99 
  100         /* in flight totals */
  101         u_int32_t               swu_ios_complete;
  102         u_int32_t               swu_ios_failed;
  103         u_int32_t               swu_ios_succeeded;
  104 
  105         /* number of ios that makes up the whole work unit */
  106         u_int32_t               swu_io_count;
  107 
  108         /* colliding wu */
  109         struct sr_workunit      *swu_collider;
  110 
  111         /* all ios that make up this workunit */
  112         struct sr_ccb_list      swu_ccb;
  113 
  114         TAILQ_ENTRY(sr_workunit) swu_link;
  115 };
  116 
  117 TAILQ_HEAD(sr_wu_list, sr_workunit);
  118 
  119 /* RAID 1 */
  120 #define SR_RAID1_NOWU           16
  121 struct sr_raid1 {
  122         u_int32_t               sr1_counter;
  123 };
  124 
  125 /* RAID C */
  126 #define SR_RAIDC_NOWU           16
  127 struct sr_raidc {
  128         u_int64_t               src_sid;
  129         char                    src_key[64];
  130 };
  131 
  132 #define SR_META_SIZE            32      /* save space at chunk beginning */
  133 #define SR_META_OFFSET          16      /* skip 8192 bytes at chunk beginning */
  134 #define SR_META_VERSION         1       /* bump when sr_metadata changes */
  135 struct sr_metadata {
  136         /* do not change order of ssd_magic, ssd_version & ssd_checksum */
  137         u_int64_t               ssd_magic;      /* magic id */
  138 #define SR_MAGIC                0x4d4152436372616dLLU
  139         u_int8_t                ssd_version;    /* meta data version */
  140         u_int8_t                ssd_pad1[3];
  141         u_int32_t               ssd_flags;      /* flags */
  142 
  143         /* meta-data */
  144         u_int32_t               ssd_checksum;   /* xor of the structure */
  145         u_int32_t               ssd_size;       /* sizeof(sr_metadata) */
  146         u_int32_t               ssd_ondisk;     /* on disk version counter */
  147         u_int32_t               ssd_pad2;
  148         struct sr_uuid          ssd_uuid;       /* unique identifier */
  149 
  150         /* virtual disk data */
  151         u_int32_t               ssd_vd_ver;     /* vd structure version */
  152         u_int32_t               ssd_vd_size;    /* vd structure size */
  153         u_int32_t               ssd_vd_volid;   /* volume id */
  154         u_int32_t               ssd_vd_chk;     /* vd structure xor */
  155 
  156         /* chunk data */
  157         u_int32_t               ssd_chunk_ver;  /* chunk structure version */
  158         u_int32_t               ssd_chunk_no;   /* number of chunks */
  159         u_int32_t               ssd_chunk_size; /* chunk structure size */
  160         u_int32_t               ssd_chunk_id;   /* chunk identifier */
  161         u_int32_t               ssd_chunk_chk;  /* chunk structure xor */
  162         u_int32_t               ssd_pad3;
  163 
  164         /* optional metadata */
  165         u_int32_t               ssd_opt_ver;    /* optinal meta version */
  166         u_int32_t               ssd_opt_no;     /* nr of optional md elements */
  167         u_int32_t               ssd_opt_size;   /* sizeof optional metadata */
  168         u_int32_t               ssd_opt_chk;    /* optional metadata xor */
  169 } __packed;
  170 
  171 struct sr_metadata_list {
  172         struct sr_metadata      *sml_metadata;
  173         dev_t                   sml_mm;
  174         int                     sml_used;
  175 
  176         SLIST_ENTRY(sr_metadata_list) sml_link;
  177 };
  178 
  179 SLIST_HEAD(sr_metadata_list_head, sr_metadata_list);
  180 
  181 #define SR_OPT_VERSION          1       /* bump when sr_opt_meta changes */
  182 struct sr_opt_meta {
  183         u_int32_t               som_type;
  184         u_int32_t               som_pad;
  185 #define SR_OPT_INVALID          0x00
  186 #define SR_OPT_CRYPTO           0x01
  187         union {
  188                 struct sr_raidc smm_crypto;
  189         }                       som_meta;
  190 };
  191 
  192 #define SR_CHUNK_VERSION        1       /* bump when sr_chunk_meta changes */
  193 struct sr_chunk_meta {
  194         u_int32_t               scm_volid;      /* vd we belong to */
  195         u_int32_t               scm_chunk_id;   /* chunk id */
  196         u_int32_t               scm_status;     /* use bio bioc_disk status */
  197         u_int32_t               scm_pad1;
  198         char                    scm_devname[32];/* /dev/XXXXX */
  199         int64_t                 scm_size;       /* size of partition */
  200         int64_t                 scm_coerced_size; /* coerced size of part */
  201         struct sr_uuid          scm_uuid;       /* unique identifier */
  202 } __packed;
  203 
  204 struct sr_chunk {
  205         struct sr_chunk_meta    src_meta;       /* chunk meta data */
  206 
  207         /* runtime data */
  208         dev_t                   src_dev_mm;     /* major/minor */
  209 
  210         /* helper members before metadata makes it onto the chunk  */
  211         int                     src_meta_ondisk;/* set when meta is on disk */
  212         char                    src_devname[32];
  213         int64_t                 src_size;
  214 
  215         SLIST_ENTRY(sr_chunk)   src_link;
  216 };
  217 
  218 SLIST_HEAD(sr_chunk_head, sr_chunk);
  219 
  220 #define SR_VOL_VERSION  1       /* bump when sr_vol_meta changes */
  221 struct sr_vol_meta {
  222         u_int32_t               svm_volid;      /* volume id */
  223         u_int32_t               svm_status;     /* use bioc_vol status */
  224         u_int32_t               svm_flags;      /* flags */
  225 #define SR_VOL_DIRTY            0x01
  226         u_int32_t               svm_level;      /* raid level */
  227         int64_t                 svm_size;       /* virtual disk size */
  228         char                    svm_devname[32];/* /dev/XXXXX */
  229         char                    svm_vendor[8];  /* scsi vendor */
  230         char                    svm_product[16];/* scsi product */
  231         char                    svm_revision[4];/* scsi revision */
  232         u_int32_t               svm_no_chunk;   /* number of chunks */
  233         struct sr_uuid          svm_uuid;       /* volume unique identifier */
  234 } __packed;
  235 
  236 struct sr_volume {
  237         struct sr_vol_meta      sv_meta;        /* meta data */
  238 
  239         /* runtime data */
  240         struct sr_chunk_head    sv_chunk_list;  /* linked list of all chunks */
  241         struct sr_chunk         **sv_chunks;    /* array to same chunks */
  242 
  243         /* sensors */
  244         struct ksensor          sv_sensor;
  245         struct ksensordev       sv_sensordev;
  246         int                     sv_sensor_valid;
  247 };
  248 
  249 struct sr_discipline {
  250         struct sr_softc         *sd_sc;         /* link back to sr softc */
  251         u_int8_t                sd_type;        /* type of discipline */
  252 #define SR_MD_RAID0             0
  253 #define SR_MD_RAID1             1
  254 #define SR_MD_RAID5             2
  255 #define SR_MD_CACHE             3
  256 #define SR_MD_RAIDC             4
  257         char                    sd_name[10];    /* human readable dis name */
  258         u_int8_t                sd_scsibus;     /* scsibus discipline uses */
  259         struct scsi_link        sd_link;        /* link to midlayer */
  260 
  261         union {
  262             struct sr_raid1     mdd_raid1;
  263             struct sr_raidc     mdd_raidc;
  264         }                       sd_dis_specific;/* dis specific members */
  265 #define mds                     sd_dis_specific
  266 
  267         /* discipline metadata */
  268         struct sr_metadata      *sd_meta;       /* in memory copy of metadata */
  269         u_int32_t               sd_meta_flags;
  270 
  271         int                     sd_sync;
  272         int                     sd_must_flush;
  273 
  274         struct device           *sd_scsibus_dev;
  275         void                    (*sd_shutdownhook)(void *);
  276 
  277         /* discipline volume */
  278         struct sr_volume        sd_vol;         /* volume associated */
  279 
  280         /* discipline resources */
  281         struct sr_ccb           *sd_ccb;
  282         struct sr_ccb_list      sd_ccb_freeq;
  283         u_int32_t               sd_max_ccb_per_wu;
  284 
  285         struct sr_workunit      *sd_wu;         /* all workunits */
  286         u_int32_t               sd_max_wu;
  287 
  288         struct sr_wu_list       sd_wu_freeq;    /* free wu queue */
  289         struct sr_wu_list       sd_wu_pendq;    /* pending wu queue */
  290         struct sr_wu_list       sd_wu_defq;     /* deferred wu queue */
  291 
  292         /* discipline stats */
  293         int                     sd_wu_pending;
  294         u_int64_t               sd_wu_collisions;
  295 
  296         /* discipline functions */
  297         int                     (*sd_alloc_resources)(struct sr_discipline *);
  298         int                     (*sd_assemble_volume)(void *);
  299         int                     (*sd_bringup_volume)(void *);
  300         int                     (*sd_shutdown_volume)(void *);
  301         int                     (*sd_free_resources)(struct sr_discipline *);
  302         int                     (*sd_quiesce_io)(struct sr_discipline *);
  303         void                    (*sd_set_chunk_state)(struct sr_discipline *,
  304                                     int, int);
  305         void                    (*sd_set_vol_state)(struct sr_discipline *);
  306 
  307         /* SCSI emulation */
  308         struct scsi_sense_data  sd_scsi_sense;
  309         int                     (*sd_scsi_rw)(struct sr_workunit *);
  310         int                     (*sd_scsi_sync)(struct sr_workunit *);
  311         int                     (*sd_scsi_tur)(struct sr_workunit *);
  312         int                     (*sd_scsi_start_stop)(struct sr_workunit *);
  313         int                     (*sd_scsi_inquiry)(struct sr_workunit *);
  314         int                     (*sd_scsi_read_cap)(struct sr_workunit *);
  315         int                     (*sd_scsi_req_sense)(struct sr_workunit *);
  316 };
  317 
  318 struct sr_softc {
  319         struct device           sc_dev;
  320 
  321         int                     (*sc_ioctl)(struct device *, u_long, caddr_t);
  322 
  323         struct rwlock           sc_lock;
  324 
  325         int                     sc_sensors_running;
  326         /*
  327          * during scsibus attach this is the discipline that is in use
  328          * this variable is protected by sc_lock and splhigh
  329          */
  330         struct sr_discipline    *sc_attach_dis;
  331 
  332         /*
  333          * XXX expensive, alternative would be nice but has to be cheap
  334          * since the scsibus lookup happens on each IO
  335          */
  336 #define SR_MAXSCSIBUS           256
  337         struct sr_discipline    *sc_dis[SR_MAXSCSIBUS]; /* scsibus is u_int8_t */
  338 };

/* [<][>][^][v][top][bottom][index][help] */