subr_disk_4bsd.c revision 1.1 1 1.1 thorpej /* $NetBSD: subr_disk_4bsd.c,v 1.1 2026/04/04 00:23:09 thorpej Exp $ */
2 1.1 thorpej
3 1.1 thorpej /*
4 1.1 thorpej * Copyright (c) 1982, 1986, 1988, 1993
5 1.1 thorpej * The Regents of the University of California. All rights reserved.
6 1.1 thorpej * (c) UNIX System Laboratories, Inc.
7 1.1 thorpej * All or some portions of this file are derived from material licensed
8 1.1 thorpej * to the University of California by American Telephone and Telegraph
9 1.1 thorpej * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 1.1 thorpej * the permission of UNIX System Laboratories, Inc.
11 1.1 thorpej *
12 1.1 thorpej * Redistribution and use in source and binary forms, with or without
13 1.1 thorpej * modification, are permitted provided that the following conditions
14 1.1 thorpej * are met:
15 1.1 thorpej * 1. Redistributions of source code must retain the above copyright
16 1.1 thorpej * notice, this list of conditions and the following disclaimer.
17 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright
18 1.1 thorpej * notice, this list of conditions and the following disclaimer in the
19 1.1 thorpej * documentation and/or other materials provided with the distribution.
20 1.1 thorpej * 3. Neither the name of the University nor the names of its contributors
21 1.1 thorpej * may be used to endorse or promote products derived from this software
22 1.1 thorpej * without specific prior written permission.
23 1.1 thorpej *
24 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 1.1 thorpej * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 1.1 thorpej * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 1.1 thorpej * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 1.1 thorpej * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 1.1 thorpej * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 1.1 thorpej * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.1 thorpej * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.1 thorpej * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.1 thorpej * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.1 thorpej * SUCH DAMAGE.
35 1.1 thorpej *
36 1.1 thorpej * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
37 1.1 thorpej */
38 1.1 thorpej
39 1.1 thorpej #include <sys/cdefs.h>
40 1.1 thorpej __KERNEL_RCSID(0, "$NetBSD: subr_disk_4bsd.c,v 1.1 2026/04/04 00:23:09 thorpej Exp $");
41 1.1 thorpej
42 1.1 thorpej #include <sys/param.h>
43 1.1 thorpej #include <sys/systm.h>
44 1.1 thorpej #include <sys/buf.h>
45 1.1 thorpej #include <sys/disk.h>
46 1.1 thorpej #include <sys/disklabel.h>
47 1.1 thorpej
48 1.1 thorpej /*
49 1.1 thorpej * Implementation of readdisklabel() and writedisklabel() for the simple
50 1.1 thorpej * "basic scheme from 4BSD".
51 1.1 thorpej *
52 1.1 thorpej * Lifted verbatim from the hp300 copy.
53 1.1 thorpej */
54 1.1 thorpej
55 1.1 thorpej /*
56 1.1 thorpej * Attempt to read a disk label from a device using the indicated strategy
57 1.1 thorpej * routine. The label must be partly set up before this: secpercyl and
58 1.1 thorpej * anything required in the strategy routine (e.g., sector size) must be
59 1.1 thorpej * filled in before calling us. Returns null on success and an error
60 1.1 thorpej * string on failure.
61 1.1 thorpej */
62 1.1 thorpej const char *
63 1.1 thorpej readdisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
64 1.1 thorpej struct cpu_disklabel *osdep)
65 1.1 thorpej {
66 1.1 thorpej struct buf *bp;
67 1.1 thorpej struct disklabel *dlp;
68 1.1 thorpej const char *msg = NULL;
69 1.1 thorpej int i;
70 1.1 thorpej
71 1.1 thorpej if (lp->d_secsize == 0)
72 1.1 thorpej lp->d_secsize = DEV_BSIZE;
73 1.1 thorpej if (lp->d_secperunit == 0)
74 1.1 thorpej lp->d_secperunit = 0x1fffffff;
75 1.1 thorpej if (lp->d_npartitions < RAW_PART + 1)
76 1.1 thorpej lp->d_npartitions = RAW_PART + 1;
77 1.1 thorpej for (i = 0; i < RAW_PART; i++) {
78 1.1 thorpej lp->d_partitions[i].p_size = 0;
79 1.1 thorpej lp->d_partitions[i].p_offset = 0;
80 1.1 thorpej }
81 1.1 thorpej if (lp->d_partitions[RAW_PART].p_size == 0)
82 1.1 thorpej lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
83 1.1 thorpej lp->d_partitions[RAW_PART].p_offset = 0;
84 1.1 thorpej
85 1.1 thorpej lp->d_partitions[0].p_size = lp->d_partitions[RAW_PART].p_size;
86 1.1 thorpej lp->d_partitions[0].p_fstype = FS_BSDFFS;
87 1.1 thorpej
88 1.1 thorpej bp = geteblk((int)lp->d_secsize);
89 1.1 thorpej bp->b_dev = dev;
90 1.1 thorpej bp->b_blkno = LABELSECTOR;
91 1.1 thorpej bp->b_bcount = lp->d_secsize;
92 1.1 thorpej bp->b_flags |= B_READ;
93 1.1 thorpej bp->b_cylinder = LABELSECTOR / lp->d_secpercyl;
94 1.1 thorpej (*strat)(bp);
95 1.1 thorpej if (biowait(bp))
96 1.1 thorpej msg = "I/O error";
97 1.1 thorpej else for (dlp = (struct disklabel *)bp->b_data;
98 1.1 thorpej dlp <= (struct disklabel *)((char *)bp->b_data +
99 1.1 thorpej DEV_BSIZE - sizeof(*dlp));
100 1.1 thorpej dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
101 1.1 thorpej if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
102 1.1 thorpej if (msg == NULL)
103 1.1 thorpej msg = "no disk label";
104 1.1 thorpej } else if (dlp->d_npartitions > MAXPARTITIONS ||
105 1.1 thorpej dkcksum(dlp) != 0)
106 1.1 thorpej msg = "disk label corrupted";
107 1.1 thorpej else {
108 1.1 thorpej *lp = *dlp;
109 1.1 thorpej msg = NULL;
110 1.1 thorpej break;
111 1.1 thorpej }
112 1.1 thorpej }
113 1.1 thorpej brelse(bp, 0);
114 1.1 thorpej return msg;
115 1.1 thorpej }
116 1.1 thorpej
117 1.1 thorpej /*
118 1.1 thorpej * Write disk label back to device after modification.
119 1.1 thorpej */
120 1.1 thorpej int
121 1.1 thorpej writedisklabel(dev_t dev, void (*strat)(struct buf *), struct disklabel *lp,
122 1.1 thorpej struct cpu_disklabel *osdep)
123 1.1 thorpej {
124 1.1 thorpej struct buf *bp;
125 1.1 thorpej struct disklabel *dlp;
126 1.1 thorpej int labelpart;
127 1.1 thorpej int error = 0;
128 1.1 thorpej
129 1.1 thorpej labelpart = DISKPART(dev);
130 1.1 thorpej if (lp->d_partitions[labelpart].p_offset != 0) {
131 1.1 thorpej if (lp->d_partitions[0].p_offset != 0)
132 1.1 thorpej return EXDEV; /* not quite right */
133 1.1 thorpej labelpart = 0;
134 1.1 thorpej }
135 1.1 thorpej bp = geteblk((int)lp->d_secsize);
136 1.1 thorpej bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart);
137 1.1 thorpej bp->b_blkno = LABELSECTOR;
138 1.1 thorpej bp->b_bcount = lp->d_secsize;
139 1.1 thorpej bp->b_flags |= B_READ;
140 1.1 thorpej (*strat)(bp);
141 1.1 thorpej if ((error = biowait(bp)) != 0)
142 1.1 thorpej goto done;
143 1.1 thorpej for (dlp = (struct disklabel *)bp->b_data;
144 1.1 thorpej dlp <= (struct disklabel *)
145 1.1 thorpej ((char *)bp->b_data + lp->d_secsize - sizeof(*dlp));
146 1.1 thorpej dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
147 1.1 thorpej if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
148 1.1 thorpej dkcksum(dlp) == 0) {
149 1.1 thorpej *dlp = *lp;
150 1.1 thorpej bp->b_oflags &= ~(BO_DONE);
151 1.1 thorpej bp->b_flags &= ~(B_READ);
152 1.1 thorpej bp->b_flags |= B_WRITE;
153 1.1 thorpej (*strat)(bp);
154 1.1 thorpej error = biowait(bp);
155 1.1 thorpej goto done;
156 1.1 thorpej }
157 1.1 thorpej }
158 1.1 thorpej error = ESRCH;
159 1.1 thorpej done:
160 1.1 thorpej brelse(bp, 0);
161 1.1 thorpej return error;
162 1.1 thorpej }
163