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/dev/softraid_raid0.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 /* $OpenBSD: softraid_raid0.c,v 1.53 2020/03/25 21:29:04 tobhe Exp $ */
    2 /*
    3  * Copyright (c) 2008 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 "bio.h"
   19 
   20 #include <sys/param.h>
   21 #include <sys/systm.h>
   22 #include <sys/buf.h>
   23 #include <sys/device.h>
   24 #include <sys/ioctl.h>
   25 #include <sys/malloc.h>
   26 #include <sys/kernel.h>
   27 #include <sys/disk.h>
   28 #include <sys/rwlock.h>
   29 #include <sys/queue.h>
   30 #include <sys/fcntl.h>
   31 #include <sys/mount.h>
   32 #include <sys/sensors.h>
   33 #include <sys/stat.h>
   34 #include <sys/conf.h>
   35 #include <sys/uio.h>
   36 
   37 #include <scsi/scsi_all.h>
   38 #include <scsi/scsiconf.h>
   39 #include <scsi/scsi_disk.h>
   40 
   41 #include <dev/softraidvar.h>
   42 
   43 /* RAID 0 functions. */
   44 int     sr_raid0_create(struct sr_discipline *, struct bioc_createraid *,
   45             int, int64_t);
   46 int     sr_raid0_assemble(struct sr_discipline *, struct bioc_createraid *,
   47             int, void *);
   48 int     sr_raid0_init(struct sr_discipline *);
   49 int     sr_raid0_rw(struct sr_workunit *);
   50 
   51 /* Discipline initialisation. */
   52 void
   53 sr_raid0_discipline_init(struct sr_discipline *sd)
   54 {
   55 
   56         /* Fill out discipline members. */
   57         sd->sd_type = SR_MD_RAID0;
   58         strlcpy(sd->sd_name, "RAID 0", sizeof(sd->sd_name));
   59         sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE;
   60         sd->sd_max_wu = SR_RAID0_NOWU;
   61 
   62         /* Setup discipline specific function pointers. */
   63         sd->sd_assemble = sr_raid0_assemble;
   64         sd->sd_create = sr_raid0_create;
   65         sd->sd_scsi_rw = sr_raid0_rw;
   66 }
   67 
   68 int
   69 sr_raid0_create(struct sr_discipline *sd, struct bioc_createraid *bc,
   70     int no_chunk, int64_t coerced_size)
   71 {
   72         if (no_chunk < 2) {
   73                 sr_error(sd->sd_sc, "%s requires two or more chunks",
   74                     sd->sd_name);
   75                 return EINVAL;
   76         }
   77 
   78         /*
   79          * XXX add variable strip size later even though MAXPHYS is really
   80          * the clever value, users like to tinker with that type of stuff.
   81          */
   82         sd->sd_meta->ssdi.ssd_strip_size = MAXPHYS;
   83         sd->sd_meta->ssdi.ssd_size = (coerced_size &
   84             ~(((u_int64_t)sd->sd_meta->ssdi.ssd_strip_size >>
   85             DEV_BSHIFT) - 1)) * no_chunk;
   86 
   87         return sr_raid0_init(sd);
   88 }
   89 
   90 int
   91 sr_raid0_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
   92     int no_chunks, void *data)
   93 {
   94         return sr_raid0_init(sd);
   95 }
   96 
   97 int
   98 sr_raid0_init(struct sr_discipline *sd)
   99 {
  100         /* Initialise runtime values. */
  101         sd->mds.mdd_raid0.sr0_strip_bits =
  102             sr_validate_stripsize(sd->sd_meta->ssdi.ssd_strip_size);
  103         if (sd->mds.mdd_raid0.sr0_strip_bits == -1) {
  104                 sr_error(sd->sd_sc, "%s: invalid strip size", sd->sd_name);
  105                 return EINVAL;
  106         }
  107         sd->sd_max_ccb_per_wu =
  108             (MAXPHYS / sd->sd_meta->ssdi.ssd_strip_size + 1) *
  109             SR_RAID0_NOWU * sd->sd_meta->ssdi.ssd_chunk_no;
  110 
  111         return 0;
  112 }
  113 
  114 int
  115 sr_raid0_rw(struct sr_workunit *wu)
  116 {
  117         struct sr_discipline    *sd = wu->swu_dis;
  118         struct scsi_xfer        *xs = wu->swu_xs;
  119         struct sr_ccb           *ccb;
  120         struct sr_chunk         *scp;
  121         daddr_t                 blkno;
  122         int64_t                 chunkoffs, lbaoffs, offset, stripoffs;
  123         int64_t                 strip_bits, strip_no, strip_size;
  124         int64_t                 chunk, no_chunk;
  125         int64_t                 length, leftover;
  126         u_int8_t                *data;
  127 
  128         /* blkno and scsi error will be handled by sr_validate_io */
  129         if (sr_validate_io(wu, &blkno, "sr_raid0_rw"))
  130                 goto bad;
  131 
  132         strip_size = sd->sd_meta->ssdi.ssd_strip_size;
  133         strip_bits = sd->mds.mdd_raid0.sr0_strip_bits;
  134         no_chunk = sd->sd_meta->ssdi.ssd_chunk_no;
  135 
  136         DNPRINTF(SR_D_DIS, "%s: %s: front end io: blkno %lld size %d\n",
  137             DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname,
  138             (long long)blkno, xs->datalen);
  139 
  140         /* all offs are in bytes */
  141         lbaoffs = blkno << DEV_BSHIFT;
  142         strip_no = lbaoffs >> strip_bits;
  143         chunk = strip_no % no_chunk;
  144         stripoffs = lbaoffs & (strip_size - 1);
  145         chunkoffs = (strip_no / no_chunk) << strip_bits;
  146         offset = chunkoffs + stripoffs;
  147         length = MIN(xs->datalen, strip_size - stripoffs);
  148         leftover = xs->datalen;
  149         data = xs->data;
  150         for (;;) {
  151                 /* make sure chunk is online */
  152                 scp = sd->sd_vol.sv_chunks[chunk];
  153                 if (scp->src_meta.scm_status != BIOC_SDONLINE)
  154                         goto bad;
  155 
  156                 DNPRINTF(SR_D_DIS, "%s: %s %s io lbaoffs %lld "
  157                     "strip_no %lld chunk %lld stripoffs %lld "
  158                     "chunkoffs %lld offset %lld length %lld "
  159                     "leftover %lld data %p\n",
  160                     DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_name,
  161                     lbaoffs, strip_no, chunk, stripoffs, chunkoffs, offset,
  162                     length, leftover, data);
  163 
  164                 blkno = offset >> DEV_BSHIFT;
  165                 ccb = sr_ccb_rw(sd, chunk, blkno, length, data, xs->flags, 0);
  166                 if (!ccb) {
  167                         /* should never happen but handle more gracefully */
  168                         printf("%s: %s: too many ccbs queued\n",
  169                             DEVNAME(sd->sd_sc),
  170                             sd->sd_meta->ssd_devname);
  171                         goto bad;
  172                 }
  173                 sr_wu_enqueue_ccb(wu, ccb);
  174 
  175                 leftover -= length;
  176                 if (leftover == 0)
  177                         break;
  178 
  179                 data += length;
  180                 if (++chunk > no_chunk - 1) {
  181                         chunk = 0;
  182                         offset += length;
  183                 } else if (wu->swu_io_count == 1)
  184                         offset -= stripoffs;
  185                 length = MIN(leftover,strip_size);
  186         }
  187 
  188         sr_schedule_wu(wu);
  189 
  190         return (0);
  191 
  192 bad:
  193         /* wu is unwound by sr_wu_put */
  194         return (1);
  195 }

Cache object: c5f3c6e3068649a8cd54bf18f7c80081


[ 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.