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/part/g_part_vtoc8.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  * Copyright (c) 2008 Marcel Moolenaar
    3  * All rights reserved.
    4  *
    5  * Redistribution and use in source and binary forms, with or without
    6  * modification, are permitted provided that the following conditions
    7  * are met:
    8  *
    9  * 1. Redistributions of source code must retain the above copyright
   10  *    notice, this list of conditions and the following disclaimer.
   11  * 2. Redistributions in binary form must reproduce the above copyright
   12  *    notice, this list of conditions and the following disclaimer in the
   13  *    documentation and/or other materials provided with the distribution.
   14  *
   15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
   16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
   17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
   18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
   19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
   20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
   21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
   22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
   24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   25  */
   26 
   27 #include <sys/cdefs.h>
   28 __FBSDID("$FreeBSD: releng/8.3/sys/geom/part/g_part_vtoc8.c 226935 2011-10-30 12:23:04Z marius $");
   29 
   30 #include <sys/param.h>
   31 #include <sys/bio.h>
   32 #include <sys/endian.h>
   33 #include <sys/kernel.h>
   34 #include <sys/kobj.h>
   35 #include <sys/limits.h>
   36 #include <sys/lock.h>
   37 #include <sys/malloc.h>
   38 #include <sys/mutex.h>
   39 #include <sys/queue.h>
   40 #include <sys/sbuf.h>
   41 #include <sys/systm.h>
   42 #include <sys/vtoc.h>
   43 #include <geom/geom.h>
   44 #include <geom/part/g_part.h>
   45 
   46 #include "g_part_if.h"
   47 
   48 struct g_part_vtoc8_table {
   49         struct g_part_table     base;
   50         struct vtoc8            vtoc;
   51         uint32_t                secpercyl;
   52 };
   53 
   54 static int g_part_vtoc8_add(struct g_part_table *, struct g_part_entry *,
   55     struct g_part_parms *);
   56 static int g_part_vtoc8_create(struct g_part_table *, struct g_part_parms *);
   57 static int g_part_vtoc8_destroy(struct g_part_table *, struct g_part_parms *);
   58 static void g_part_vtoc8_dumpconf(struct g_part_table *,
   59     struct g_part_entry *, struct sbuf *, const char *);
   60 static int g_part_vtoc8_dumpto(struct g_part_table *, struct g_part_entry *);
   61 static int g_part_vtoc8_modify(struct g_part_table *, struct g_part_entry *,
   62     struct g_part_parms *);
   63 static const char *g_part_vtoc8_name(struct g_part_table *,
   64     struct g_part_entry *, char *, size_t);
   65 static int g_part_vtoc8_probe(struct g_part_table *, struct g_consumer *);
   66 static int g_part_vtoc8_read(struct g_part_table *, struct g_consumer *);
   67 static const char *g_part_vtoc8_type(struct g_part_table *,
   68     struct g_part_entry *, char *, size_t);
   69 static int g_part_vtoc8_write(struct g_part_table *, struct g_consumer *);
   70 static int g_part_vtoc8_resize(struct g_part_table *, struct g_part_entry *,
   71     struct g_part_parms *);
   72 
   73 static kobj_method_t g_part_vtoc8_methods[] = {
   74         KOBJMETHOD(g_part_add,          g_part_vtoc8_add),
   75         KOBJMETHOD(g_part_create,       g_part_vtoc8_create),
   76         KOBJMETHOD(g_part_destroy,      g_part_vtoc8_destroy),
   77         KOBJMETHOD(g_part_dumpconf,     g_part_vtoc8_dumpconf),
   78         KOBJMETHOD(g_part_dumpto,       g_part_vtoc8_dumpto),
   79         KOBJMETHOD(g_part_modify,       g_part_vtoc8_modify),
   80         KOBJMETHOD(g_part_resize,       g_part_vtoc8_resize),
   81         KOBJMETHOD(g_part_name,         g_part_vtoc8_name),
   82         KOBJMETHOD(g_part_probe,        g_part_vtoc8_probe),
   83         KOBJMETHOD(g_part_read,         g_part_vtoc8_read),
   84         KOBJMETHOD(g_part_type,         g_part_vtoc8_type),
   85         KOBJMETHOD(g_part_write,        g_part_vtoc8_write),
   86         { 0, 0 }
   87 };
   88 
   89 static struct g_part_scheme g_part_vtoc8_scheme = {
   90         "VTOC8",
   91         g_part_vtoc8_methods,
   92         sizeof(struct g_part_vtoc8_table),
   93         .gps_entrysz = sizeof(struct g_part_entry),
   94         .gps_minent = VTOC8_NPARTS,
   95         .gps_maxent = VTOC8_NPARTS,
   96 };
   97 G_PART_SCHEME_DECLARE(g_part_vtoc8);
   98 
   99 static int
  100 vtoc8_parse_type(const char *type, uint16_t *tag)
  101 {
  102         const char *alias;
  103         char *endp;
  104         long lt;
  105 
  106         if (type[0] == '!') {
  107                 lt = strtol(type + 1, &endp, 0);
  108                 if (type[1] == '\0' || *endp != '\0' || lt <= 0 ||
  109                     lt >= 65536)
  110                         return (EINVAL);
  111                 *tag = (uint16_t)lt;
  112                 return (0);
  113         }
  114         alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP);
  115         if (!strcasecmp(type, alias)) {
  116                 *tag = VTOC_TAG_FREEBSD_SWAP;
  117                 return (0);
  118         }
  119         alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS);
  120         if (!strcasecmp(type, alias)) {
  121                 *tag = VTOC_TAG_FREEBSD_UFS;
  122                 return (0);
  123         }
  124         alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM);
  125         if (!strcasecmp(type, alias)) {
  126                 *tag = VTOC_TAG_FREEBSD_VINUM;
  127                 return (0);
  128         }
  129         alias = g_part_alias_name(G_PART_ALIAS_FREEBSD_ZFS);
  130         if (!strcasecmp(type, alias)) {
  131                 *tag = VTOC_TAG_FREEBSD_ZFS;
  132                 return (0);
  133         }
  134         return (EINVAL);
  135 }
  136 
  137 static int
  138 g_part_vtoc8_add(struct g_part_table *basetable, struct g_part_entry *entry,
  139     struct g_part_parms *gpp)
  140 {
  141         struct g_part_vtoc8_table *table;
  142         int error, index;
  143         uint64_t start, size;
  144         uint16_t tag;
  145 
  146         if (gpp->gpp_parms & G_PART_PARM_LABEL)
  147                 return (EINVAL);
  148 
  149         error = vtoc8_parse_type(gpp->gpp_type, &tag);
  150         if (error)
  151                 return (error);
  152 
  153         table = (struct g_part_vtoc8_table *)basetable;
  154         index = entry->gpe_index - 1;
  155 
  156         start = gpp->gpp_start;
  157         size = gpp->gpp_size;
  158         if (start % table->secpercyl) {
  159                 size = size - table->secpercyl + (start % table->secpercyl);
  160                 start = start - (start % table->secpercyl) + table->secpercyl;
  161         }
  162         if (size % table->secpercyl)
  163                 size = size - (size % table->secpercyl);
  164         if (size < table->secpercyl)
  165                 return (EINVAL);
  166 
  167         KASSERT(entry->gpe_start <= start, (__func__));
  168         KASSERT(entry->gpe_end >= start + size - 1, (__func__));
  169         entry->gpe_start = start;
  170         entry->gpe_end = start + size - 1;
  171 
  172         be16enc(&table->vtoc.part[index].tag, tag);
  173         be16enc(&table->vtoc.part[index].flag, 0);
  174         be32enc(&table->vtoc.timestamp[index], 0);
  175         be32enc(&table->vtoc.map[index].cyl, start / table->secpercyl);
  176         be32enc(&table->vtoc.map[index].nblks, size);
  177         return (0);
  178 }
  179 
  180 static int
  181 g_part_vtoc8_create(struct g_part_table *basetable, struct g_part_parms *gpp)
  182 {
  183         struct g_provider *pp;
  184         struct g_part_entry *entry;
  185         struct g_part_vtoc8_table *table;
  186         uint64_t msize;
  187         uint32_t acyls, ncyls, pcyls;
  188 
  189         pp = gpp->gpp_provider;
  190 
  191         if (pp->sectorsize < sizeof(struct vtoc8))
  192                 return (ENOSPC);
  193         if (pp->sectorsize > sizeof(struct vtoc8))
  194                 return (ENXIO);
  195 
  196         table = (struct g_part_vtoc8_table *)basetable;
  197 
  198         msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
  199         table->secpercyl = basetable->gpt_sectors * basetable->gpt_heads;
  200         pcyls = msize / table->secpercyl;
  201         acyls = 2;
  202         ncyls = pcyls - acyls;
  203         msize = ncyls * table->secpercyl;
  204 
  205         sprintf(table->vtoc.ascii, "FreeBSD%lldM cyl %u alt %u hd %u sec %u",
  206             (long long)(msize / 2048), ncyls, acyls, basetable->gpt_heads,
  207             basetable->gpt_sectors);
  208         be32enc(&table->vtoc.version, VTOC_VERSION);
  209         be16enc(&table->vtoc.nparts, VTOC8_NPARTS);
  210         be32enc(&table->vtoc.sanity, VTOC_SANITY);
  211         be16enc(&table->vtoc.rpm, 3600);
  212         be16enc(&table->vtoc.physcyls, pcyls);
  213         be16enc(&table->vtoc.ncyls, ncyls);
  214         be16enc(&table->vtoc.altcyls, acyls);
  215         be16enc(&table->vtoc.nheads, basetable->gpt_heads);
  216         be16enc(&table->vtoc.nsecs, basetable->gpt_sectors);
  217         be16enc(&table->vtoc.magic, VTOC_MAGIC);
  218 
  219         basetable->gpt_first = 0;
  220         basetable->gpt_last = msize - 1;
  221         basetable->gpt_isleaf = 1;
  222 
  223         entry = g_part_new_entry(basetable, VTOC_RAW_PART + 1,
  224             basetable->gpt_first, basetable->gpt_last);
  225         entry->gpe_internal = 1;
  226         be16enc(&table->vtoc.part[VTOC_RAW_PART].tag, VTOC_TAG_BACKUP);
  227         be32enc(&table->vtoc.map[VTOC_RAW_PART].nblks, msize);
  228         return (0);
  229 }
  230 
  231 static int
  232 g_part_vtoc8_destroy(struct g_part_table *basetable, struct g_part_parms *gpp)
  233 {
  234 
  235         /* Wipe the first sector to clear the partitioning. */
  236         basetable->gpt_smhead |= 1;
  237         return (0);
  238 }
  239 
  240 static void
  241 g_part_vtoc8_dumpconf(struct g_part_table *basetable,
  242     struct g_part_entry *entry, struct sbuf *sb, const char *indent)
  243 {
  244         struct g_part_vtoc8_table *table;
  245 
  246         table = (struct g_part_vtoc8_table *)basetable;
  247         if (indent == NULL) {
  248                 /* conftxt: libdisk compatibility */
  249                 sbuf_printf(sb, " xs SUN sc %u hd %u alt %u",
  250                     be16dec(&table->vtoc.nsecs), be16dec(&table->vtoc.nheads),
  251                     be16dec(&table->vtoc.altcyls));
  252         } else if (entry != NULL) {
  253                 /* confxml: partition entry information */
  254                 sbuf_printf(sb, "%s<rawtype>%u</rawtype>\n", indent,
  255                     be16dec(&table->vtoc.part[entry->gpe_index - 1].tag));
  256         } else {
  257                 /* confxml: scheme information */
  258         }
  259 }
  260 
  261 static int
  262 g_part_vtoc8_dumpto(struct g_part_table *basetable,
  263     struct g_part_entry *entry)
  264 {
  265         struct g_part_vtoc8_table *table;
  266         uint16_t tag;
  267 
  268         /*
  269          * Allow dumping to a swap partition or a partition that
  270          * has no type.
  271          */
  272         table = (struct g_part_vtoc8_table *)basetable;
  273         tag = be16dec(&table->vtoc.part[entry->gpe_index - 1].tag);
  274         return ((tag == 0 || tag == VTOC_TAG_FREEBSD_SWAP ||
  275             tag == VTOC_TAG_SWAP) ? 1 : 0);
  276 }
  277 
  278 static int
  279 g_part_vtoc8_modify(struct g_part_table *basetable,
  280     struct g_part_entry *entry, struct g_part_parms *gpp)
  281 {
  282         struct g_part_vtoc8_table *table;
  283         int error;
  284         uint16_t tag;
  285 
  286         if (gpp->gpp_parms & G_PART_PARM_LABEL)
  287                 return (EINVAL);
  288 
  289         table = (struct g_part_vtoc8_table *)basetable;
  290         if (gpp->gpp_parms & G_PART_PARM_TYPE) {
  291                 error = vtoc8_parse_type(gpp->gpp_type, &tag);
  292                 if (error)
  293                         return(error);
  294 
  295                 be16enc(&table->vtoc.part[entry->gpe_index - 1].tag, tag);
  296         }
  297         return (0);
  298 }
  299 
  300 static int
  301 g_part_vtoc8_resize(struct g_part_table *basetable,
  302     struct g_part_entry *entry, struct g_part_parms *gpp)
  303 {
  304         struct g_part_vtoc8_table *table;
  305         uint64_t size;
  306 
  307         table = (struct g_part_vtoc8_table *)basetable;
  308         size = gpp->gpp_size;
  309         if (size % table->secpercyl)
  310                 size = size - (size % table->secpercyl);
  311         if (size < table->secpercyl)
  312                 return (EINVAL);
  313 
  314         entry->gpe_end = entry->gpe_start + size - 1;
  315         be32enc(&table->vtoc.map[entry->gpe_index - 1].nblks, size);
  316 
  317         return (0);
  318 }
  319 
  320 static const char *
  321 g_part_vtoc8_name(struct g_part_table *table, struct g_part_entry *baseentry,
  322     char *buf, size_t bufsz)
  323 {
  324 
  325         snprintf(buf, bufsz, "%c", 'a' + baseentry->gpe_index - 1);
  326         return (buf);
  327 }
  328 
  329 static int
  330 g_part_vtoc8_probe(struct g_part_table *table, struct g_consumer *cp)
  331 {
  332         struct g_provider *pp;
  333         u_char *buf;
  334         int error, ofs, res;
  335         uint16_t cksum, magic;
  336 
  337         pp = cp->provider;
  338 
  339         /* Sanity-check the provider. */
  340         if (pp->sectorsize != sizeof(struct vtoc8))
  341                 return (ENOSPC);
  342 
  343         /* Check that there's a disklabel. */
  344         buf = g_read_data(cp, 0, pp->sectorsize, &error);
  345         if (buf == NULL)
  346                 return (error);
  347 
  348         res = ENXIO;    /* Assume mismatch */
  349 
  350         /* Check the magic */
  351         magic = be16dec(buf + offsetof(struct vtoc8, magic));
  352         if (magic != VTOC_MAGIC)
  353                 goto out;
  354 
  355         /* Check the sum */
  356         cksum = 0;
  357         for (ofs = 0; ofs < sizeof(struct vtoc8); ofs += 2)
  358                 cksum ^= be16dec(buf + ofs);
  359         if (cksum != 0)
  360                 goto out;
  361 
  362         res = G_PART_PROBE_PRI_NORM;
  363 
  364  out:
  365         g_free(buf);
  366         return (res);
  367 }
  368 
  369 static int
  370 g_part_vtoc8_read(struct g_part_table *basetable, struct g_consumer *cp)
  371 {
  372         struct g_provider *pp;
  373         struct g_part_vtoc8_table *table;
  374         struct g_part_entry *entry;
  375         u_char *buf;
  376         off_t chs, msize;
  377         uint64_t offset, size;
  378         u_int cyls, heads, sectors;
  379         int error, index, withtags;
  380         uint16_t tag;
  381 
  382         pp = cp->provider;
  383         buf = g_read_data(cp, 0, pp->sectorsize, &error);
  384         if (buf == NULL)
  385                 return (error);
  386 
  387         table = (struct g_part_vtoc8_table *)basetable;
  388         bcopy(buf, &table->vtoc, sizeof(table->vtoc));
  389         g_free(buf);
  390 
  391         msize = MIN(pp->mediasize / pp->sectorsize, UINT32_MAX);
  392         sectors = be16dec(&table->vtoc.nsecs);
  393         if (sectors < 1)
  394                 goto invalid_label;
  395         if (sectors != basetable->gpt_sectors && !basetable->gpt_fixgeom) {
  396                 g_part_geometry_heads(msize, sectors, &chs, &heads);
  397                 if (chs != 0) {
  398                         basetable->gpt_sectors = sectors;
  399                         basetable->gpt_heads = heads;
  400                 }
  401         }
  402 
  403         heads = be16dec(&table->vtoc.nheads);
  404         if (heads < 1)
  405                 goto invalid_label;
  406         if (heads != basetable->gpt_heads && !basetable->gpt_fixgeom)
  407                 basetable->gpt_heads = heads;
  408         /*
  409          * Except for ATA disks > 32GB, Solaris uses the native geometry
  410          * as reported by the target for the labels while da(4) typically
  411          * uses a synthetic one so we don't complain too loudly if these
  412          * geometries don't match.
  413          */
  414         if (bootverbose && (sectors != basetable->gpt_sectors ||
  415             heads != basetable->gpt_heads))
  416                 printf("GEOM: %s: geometry does not match VTOC8 label "
  417                     "(label: %uh,%us GEOM: %uh,%us).\n", pp->name, heads,
  418                     sectors, basetable->gpt_heads, basetable->gpt_sectors);
  419 
  420         table->secpercyl = heads * sectors;
  421         cyls = be16dec(&table->vtoc.ncyls);
  422         chs = cyls * table->secpercyl;
  423         if (chs < 1 || chs > msize)
  424                 goto invalid_label;
  425 
  426         basetable->gpt_first = 0;
  427         basetable->gpt_last = chs - 1;
  428         basetable->gpt_isleaf = 1;
  429 
  430         withtags = (be32dec(&table->vtoc.sanity) == VTOC_SANITY) ? 1 : 0;
  431         if (!withtags) {
  432                 printf("GEOM: %s: adding VTOC8 information.\n", pp->name);
  433                 be32enc(&table->vtoc.version, VTOC_VERSION);
  434                 bzero(&table->vtoc.volume, VTOC_VOLUME_LEN);
  435                 be16enc(&table->vtoc.nparts, VTOC8_NPARTS);
  436                 bzero(&table->vtoc.part, sizeof(table->vtoc.part));
  437                 be32enc(&table->vtoc.sanity, VTOC_SANITY);
  438         }
  439 
  440         basetable->gpt_entries = be16dec(&table->vtoc.nparts);
  441         if (basetable->gpt_entries < g_part_vtoc8_scheme.gps_minent ||
  442             basetable->gpt_entries > g_part_vtoc8_scheme.gps_maxent)
  443                 goto invalid_label;
  444 
  445         for (index = basetable->gpt_entries - 1; index >= 0; index--) {
  446                 offset = be32dec(&table->vtoc.map[index].cyl) *
  447                     table->secpercyl;
  448                 size = be32dec(&table->vtoc.map[index].nblks);
  449                 if (size == 0)
  450                         continue;
  451                 if (withtags)
  452                         tag = be16dec(&table->vtoc.part[index].tag);
  453                 else
  454                         tag = (index == VTOC_RAW_PART)
  455                             ? VTOC_TAG_BACKUP
  456                             : VTOC_TAG_UNASSIGNED;
  457 
  458                 if (index == VTOC_RAW_PART && tag != VTOC_TAG_BACKUP)
  459                         continue;
  460                 if (index != VTOC_RAW_PART && tag == VTOC_TAG_BACKUP)
  461                         continue;
  462                 entry = g_part_new_entry(basetable, index + 1, offset,
  463                     offset + size - 1);
  464                 if (tag == VTOC_TAG_BACKUP)
  465                         entry->gpe_internal = 1;
  466 
  467                 if (!withtags)
  468                         be16enc(&table->vtoc.part[index].tag, tag);
  469         }
  470 
  471         return (0);
  472 
  473  invalid_label:
  474         printf("GEOM: %s: invalid VTOC8 label.\n", pp->name);
  475         return (EINVAL);
  476 }
  477 
  478 static const char *
  479 g_part_vtoc8_type(struct g_part_table *basetable, struct g_part_entry *entry,
  480     char *buf, size_t bufsz)
  481 {
  482         struct g_part_vtoc8_table *table;
  483         uint16_t tag;
  484 
  485         table = (struct g_part_vtoc8_table *)basetable;
  486         tag = be16dec(&table->vtoc.part[entry->gpe_index - 1].tag);
  487         if (tag == VTOC_TAG_FREEBSD_SWAP)
  488                 return (g_part_alias_name(G_PART_ALIAS_FREEBSD_SWAP));
  489         if (tag == VTOC_TAG_FREEBSD_UFS)
  490                 return (g_part_alias_name(G_PART_ALIAS_FREEBSD_UFS));
  491         if (tag == VTOC_TAG_FREEBSD_VINUM)
  492                 return (g_part_alias_name(G_PART_ALIAS_FREEBSD_VINUM));
  493         if (tag == VTOC_TAG_FREEBSD_ZFS)
  494                 return (g_part_alias_name(G_PART_ALIAS_FREEBSD_ZFS));
  495         snprintf(buf, bufsz, "!%d", tag);
  496         return (buf);
  497 }
  498 
  499 static int
  500 g_part_vtoc8_write(struct g_part_table *basetable, struct g_consumer *cp)
  501 {
  502         struct g_provider *pp;
  503         struct g_part_entry *entry;
  504         struct g_part_vtoc8_table *table;
  505         uint16_t sum;
  506         u_char *p;
  507         int error, index, match, offset;
  508 
  509         pp = cp->provider;
  510         table = (struct g_part_vtoc8_table *)basetable;
  511         entry = LIST_FIRST(&basetable->gpt_entry);
  512         for (index = 0; index < basetable->gpt_entries; index++) {
  513                 match = (entry != NULL && index == entry->gpe_index - 1)
  514                     ? 1 : 0;
  515                 if (match) {
  516                         if (entry->gpe_deleted) {
  517                                 be16enc(&table->vtoc.part[index].tag, 0);
  518                                 be16enc(&table->vtoc.part[index].flag, 0);
  519                                 be32enc(&table->vtoc.map[index].cyl, 0);
  520                                 be32enc(&table->vtoc.map[index].nblks, 0);
  521                         }
  522                         entry = LIST_NEXT(entry, gpe_entry);
  523                 }
  524         }
  525 
  526         /* Calculate checksum. */
  527         sum = 0;
  528         p = (void *)&table->vtoc;
  529         for (offset = 0; offset < sizeof(table->vtoc) - 2; offset += 2)
  530                 sum ^= be16dec(p + offset);
  531         be16enc(&table->vtoc.cksum, sum);
  532 
  533         error = g_write_data(cp, 0, p, pp->sectorsize);
  534         return (error);
  535 }

Cache object: 5f7069c56a316bdccbe4eaead4382ddf


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