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_concat.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_concat.c,v 1.27 2020/04/25 14:37:43 krw Exp $ */
    2 /*
    3  * Copyright (c) 2008 Marco Peereboom <marco@peereboom.us>
    4  * Copyright (c) 2011 Joel Sing <jsing@openbsd.org>
    5  *
    6  * Permission to use, copy, modify, and distribute this software for any
    7  * purpose with or without fee is hereby granted, provided that the above
    8  * copyright notice and this permission notice appear in all copies.
    9  *
   10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
   12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
   13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
   14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
   15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
   16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   17  */
   18 
   19 #include "bio.h"
   20 
   21 #include <sys/param.h>
   22 #include <sys/systm.h>
   23 #include <sys/device.h>
   24 #include <sys/buf.h>
   25 #include <sys/queue.h>
   26 #include <sys/sensors.h>
   27 
   28 #include <scsi/scsi_all.h>
   29 #include <scsi/scsiconf.h>
   30 #include <scsi/scsi_disk.h>
   31 
   32 #include <dev/softraidvar.h>
   33 
   34 /* CONCAT functions. */
   35 int     sr_concat_create(struct sr_discipline *, struct bioc_createraid *,
   36             int, int64_t);
   37 int     sr_concat_assemble(struct sr_discipline *, struct bioc_createraid *,
   38             int, void *);
   39 int     sr_concat_init(struct sr_discipline *);
   40 int     sr_concat_rw(struct sr_workunit *);
   41 
   42 /* Discipline initialisation. */
   43 void
   44 sr_concat_discipline_init(struct sr_discipline *sd)
   45 {
   46         /* Fill out discipline members. */
   47         sd->sd_type = SR_MD_CONCAT;
   48         strlcpy(sd->sd_name, "CONCAT", sizeof(sd->sd_name));
   49         sd->sd_capabilities = SR_CAP_SYSTEM_DISK | SR_CAP_AUTO_ASSEMBLE |
   50             SR_CAP_NON_COERCED;
   51         sd->sd_max_wu = SR_CONCAT_NOWU;
   52 
   53         /* Setup discipline specific function pointers. */
   54         sd->sd_assemble = sr_concat_assemble;
   55         sd->sd_create = sr_concat_create;
   56         sd->sd_scsi_rw = sr_concat_rw;
   57 }
   58 
   59 int
   60 sr_concat_create(struct sr_discipline *sd, struct bioc_createraid *bc,
   61     int no_chunk, int64_t coerced_size)
   62 {
   63         int i;
   64 
   65         if (no_chunk < 1) {
   66                 sr_error(sd->sd_sc, "%s requires one or more chunks",
   67                     sd->sd_name);
   68                 return EINVAL;
   69         }
   70 
   71         sd->sd_meta->ssdi.ssd_size = 0;
   72         for (i = 0; i < no_chunk; i++) {
   73                 sd->sd_meta->ssdi.ssd_size +=
   74                     sd->sd_vol.sv_chunks[i]->src_size;
   75         }
   76 
   77         return sr_concat_init(sd);
   78 }
   79 
   80 int
   81 sr_concat_assemble(struct sr_discipline *sd, struct bioc_createraid *bc,
   82     int no_chunk, void *data)
   83 {
   84         return sr_concat_init(sd);
   85 }
   86 
   87 int
   88 sr_concat_init(struct sr_discipline *sd)
   89 {
   90         sd->sd_max_ccb_per_wu = SR_CONCAT_NOWU * sd->sd_meta->ssdi.ssd_chunk_no;
   91 
   92         return 0;
   93 }
   94 
   95 int
   96 sr_concat_rw(struct sr_workunit *wu)
   97 {
   98         struct sr_discipline    *sd = wu->swu_dis;
   99         struct scsi_xfer        *xs = wu->swu_xs;
  100         struct sr_ccb           *ccb;
  101         struct sr_chunk         *scp;
  102         daddr_t                 blkno;
  103         int64_t                 lbaoffs, offset;
  104         int64_t                 no_chunk, chunkend, chunk, chunksize;
  105         int64_t                 length, leftover;
  106         u_int8_t                *data;
  107 
  108         /* blkno and scsi error will be handled by sr_validate_io */
  109         if (sr_validate_io(wu, &blkno, "sr_concat_rw"))
  110                 goto bad;
  111 
  112         no_chunk = sd->sd_meta->ssdi.ssd_chunk_no;
  113 
  114         DNPRINTF(SR_D_DIS, "%s: %s: front end io: blkno %lld size %d\n",
  115             DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname,
  116             (long long)blkno, xs->datalen);
  117 
  118         /* All offsets are in bytes. */
  119         lbaoffs = blkno << DEV_BSHIFT;
  120         leftover = xs->datalen;
  121         data = xs->data;
  122         for (;;) {
  123 
  124                 chunkend = 0;
  125                 offset = lbaoffs;
  126                 for (chunk = 0; chunk < no_chunk; chunk++) {
  127                         chunksize = sd->sd_vol.sv_chunks[chunk]->src_size <<
  128                             DEV_BSHIFT;
  129                         chunkend += chunksize;
  130                         if (lbaoffs < chunkend)
  131                                 break;
  132                         offset -= chunksize;
  133                 }
  134                 if (lbaoffs > chunkend)
  135                         goto bad;
  136 
  137                 length = MIN(MIN(leftover, chunkend - lbaoffs), MAXPHYS);
  138 
  139                 /* make sure chunk is online */
  140                 scp = sd->sd_vol.sv_chunks[chunk];
  141                 if (scp->src_meta.scm_status != BIOC_SDONLINE)
  142                         goto bad;
  143 
  144                 DNPRINTF(SR_D_DIS, "%s: %s %s io lbaoffs %lld "
  145                     "chunk %lld chunkend %lld offset %lld length %lld "
  146                     "leftover %lld data %p\n",
  147                     DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_name,
  148                     lbaoffs, chunk, chunkend, offset, length, leftover, data);
  149 
  150                 blkno = offset >> DEV_BSHIFT;
  151                 ccb = sr_ccb_rw(sd, chunk, blkno, length, data, xs->flags, 0);
  152                 if (!ccb) {
  153                         /* should never happen but handle more gracefully */
  154                         printf("%s: %s: too many ccbs queued\n",
  155                             DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname);
  156                         goto bad;
  157                 }
  158                 sr_wu_enqueue_ccb(wu, ccb);
  159 
  160                 leftover -= length;
  161                 if (leftover == 0)
  162                         break;
  163                 data += length;
  164                 lbaoffs += length;
  165         }
  166 
  167         sr_schedule_wu(wu);
  168 
  169         return (0);
  170 
  171 bad:
  172         /* wu is unwound by sr_wu_put */
  173         return (1);
  174 }

Cache object: bcda365e0ad96e691228d11d8a134c66


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