1 /* $NetBSD: disklabel_swap.c,v 1.1 2021/05/17 08:50:36 mrg Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of the University nor the names of its contributors 16 * may be used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 * SUCH DAMAGE. 30 * 31 * @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 32 */ 33 34 #include <sys/cdefs.h> 35 __KERNEL_RCSID(0, "$NetBSD: disklabel_swap.c,v 1.1 2021/05/17 08:50:36 mrg Exp $"); 36 37 #ifdef _KERNEL_OPT 38 #include "opt_disklabel.h" 39 #endif /* _KERNEL_OPT */ 40 41 #if defined(DISKLABEL_EI) || defined(LIBSA_DISKLABEL_EI) 42 43 #include <sys/param.h> 44 #include <sys/systm.h> 45 #include <sys/disklabel.h> 46 #include <sys/conf.h> 47 #include <lib/libkern/libkern.h> 48 49 /* 50 * from sh3/disksubr.c and kern/subr_disk_mbr.c with modifications: 51 * - update d_checksum properly 52 * - replace memcpy(9) by memmove(9) as a precaution 53 * - avoid memmove(9) for libkern version, check if the labels 54 * are the same and skip copying in-place. 55 */ 56 void 57 disklabel_swap(struct disklabel *nlp, struct disklabel *olp) 58 { 59 int i; 60 uint16_t npartitions; 61 62 #define SWAP16(x) nlp->x = bswap16(olp->x) 63 #define SWAP32(x) nlp->x = bswap32(olp->x) 64 65 SWAP32(d_magic); 66 SWAP16(d_type); 67 SWAP16(d_subtype); 68 if (nlp != olp) { 69 /* Do not need to swap char strings. */ 70 memcpy(nlp->d_typename, olp->d_typename, 71 sizeof(nlp->d_typename)); 72 73 /* 74 * XXX What should we do for d_un (an union of char and 75 * pointers)? 76 */ 77 memcpy(nlp->d_packname, olp->d_packname, 78 sizeof(nlp->d_packname)); 79 } 80 81 SWAP32(d_secsize); 82 SWAP32(d_nsectors); 83 SWAP32(d_ntracks); 84 SWAP32(d_ncylinders); 85 SWAP32(d_secpercyl); 86 SWAP32(d_secperunit); 87 88 SWAP16(d_sparespertrack); 89 SWAP16(d_sparespercyl); 90 91 SWAP32(d_acylinders); 92 93 SWAP16(d_rpm); 94 SWAP16(d_interleave); 95 SWAP16(d_trackskew); 96 SWAP16(d_cylskew); 97 SWAP32(d_headswitch); 98 SWAP32(d_trkseek); 99 SWAP32(d_flags); 100 for (i = 0; i < NDDATA; i++) 101 SWAP32(d_drivedata[i]); 102 for (i = 0; i < NSPARE; i++) 103 SWAP32(d_spare[i]); 104 SWAP32(d_magic2); 105 /* d_checksum is updated later. */ 106 107 SWAP16(d_npartitions); 108 SWAP32(d_bbsize); 109 SWAP32(d_sbsize); 110 for (i = 0; i < MAXPARTITIONS; i++) { 111 SWAP32(d_partitions[i].p_size); 112 SWAP32(d_partitions[i].p_offset); 113 SWAP32(d_partitions[i].p_fsize); 114 /* p_fstype and p_frag is uint8_t, so no need to swap. */ 115 nlp->d_partitions[i].p_fstype = olp->d_partitions[i].p_fstype; 116 nlp->d_partitions[i].p_frag = olp->d_partitions[i].p_frag; 117 SWAP16(d_partitions[i].p_cpg); 118 } 119 120 #undef SWAP16 121 #undef SWAP32 122 123 /* Update checksum in the target endian. */ 124 nlp->d_checksum = 0; 125 npartitions = nlp->d_magic == DISKMAGIC ? 126 nlp->d_npartitions : olp->d_npartitions; 127 /* 128 * npartitions can be larger than MAXPARTITIONS when the label was not 129 * validated by setdisklabel. If so, the label is intentionally(?) 130 * corrupted and checksum should be meaningless. 131 */ 132 if (npartitions <= MAXPARTITIONS) 133 nlp->d_checksum = dkcksum_sized(nlp, npartitions); 134 } 135 #endif /* DISKLABEL_EI || LIBSA_DISKLABEL_EI */ 136