1 /* $NetBSD: subr_disklabel.c,v 1.3 2019/04/07 02:58:02 rin 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: subr_disklabel.c,v 1.3 2019/04/07 02:58:02 rin Exp $");
36
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/disklabel.h>
40
41 #if !defined(__HAVE_SETDISKLABEL) || defined(_RUMPKERNEL)
42
43 #ifdef DEBUG
44 #define DPRINTF(a, ...) printf(a, ##__VA_ARGS__)
45 #else
46 #define DPRINTF(a, ...) __nothing
47 #endif
48
49 /*
50 * Check new disk label for sensibility
51 * before setting it.
52 */
53 int
54 setdisklabel(struct disklabel *olp, struct disklabel *nlp, u_long openmask,
55 struct cpu_disklabel *osdep)
56 {
57 int i;
58 struct partition *opp, *npp;
59
60 /* sanity clause */
61 if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0
62 || (nlp->d_secsize % DEV_BSIZE) != 0) {
63 DPRINTF("%s: secpercyl/secsize %u/%u\n", __func__,
64 nlp->d_secpercyl, nlp->d_secsize);
65 return EINVAL;
66 }
67
68 /* special case to allow disklabel to be invalidated */
69 if (nlp->d_magic == 0xffffffff) {
70 *olp = *nlp;
71 return 0;
72 }
73
74 if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
75 nlp->d_npartitions > MAXPARTITIONS || dkcksum(nlp) != 0) {
76 DPRINTF("%s: bad magic %#x/%#x != %#x, partitions %u != %u"
77 ", bad sum=%#x\n", __func__,
78 nlp->d_magic, nlp->d_magic2, DISKMAGIC,
79 nlp->d_npartitions, MAXPARTITIONS, dkcksum(nlp));
80 return EINVAL;
81 }
82
83 while (openmask != 0) {
84 i = ffs(openmask) - 1;
85 openmask &= ~(1 << i);
86 if (i >= nlp->d_npartitions) {
87 DPRINTF("%s: partition not found\n", __func__);
88 return EBUSY;
89 }
90 opp = &olp->d_partitions[i];
91 npp = &nlp->d_partitions[i];
92 /*
93 * Copy internally-set partition information
94 * if new label doesn't include it. XXX
95 */
96 if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
97 *npp = *opp;
98 continue;
99 }
100 if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
101 {
102 DPRINTF("%s: mismatched offset/size", __func__);
103 return EBUSY;
104 }
105 }
106 nlp->d_checksum = 0;
107 nlp->d_checksum = dkcksum(nlp);
108 *olp = *nlp;
109 return 0;
110 }
111 #endif
Cache object: 29b9d13ce4613f63ff8debf1bb8fa062
|