xref: /dflybsd-src/sys/kern/subr_disklabel32.c (revision 805c8e8e4093ceca2e27510ad3a66d4de8060a55)
1ba0cc1abSMatthew Dillon /*
2ba0cc1abSMatthew Dillon  * Copyright (c) 2003-2007 The DragonFly Project.  All rights reserved.
3ba0cc1abSMatthew Dillon  *
4ba0cc1abSMatthew Dillon  * This code is derived from software contributed to The DragonFly Project
5ba0cc1abSMatthew Dillon  * by Matthew Dillon <dillon@backplane.com>
6ba0cc1abSMatthew Dillon  *
7ba0cc1abSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
8ba0cc1abSMatthew Dillon  * modification, are permitted provided that the following conditions
9ba0cc1abSMatthew Dillon  * are met:
10ba0cc1abSMatthew Dillon  *
11ba0cc1abSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
12ba0cc1abSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
13ba0cc1abSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
14ba0cc1abSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in
15ba0cc1abSMatthew Dillon  *    the documentation and/or other materials provided with the
16ba0cc1abSMatthew Dillon  *    distribution.
17ba0cc1abSMatthew Dillon  * 3. Neither the name of The DragonFly Project nor the names of its
18ba0cc1abSMatthew Dillon  *    contributors may be used to endorse or promote products derived
19ba0cc1abSMatthew Dillon  *    from this software without specific, prior written permission.
20ba0cc1abSMatthew Dillon  *
21ba0cc1abSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22ba0cc1abSMatthew Dillon  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23ba0cc1abSMatthew Dillon  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24ba0cc1abSMatthew Dillon  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
25ba0cc1abSMatthew Dillon  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26ba0cc1abSMatthew Dillon  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27ba0cc1abSMatthew Dillon  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28ba0cc1abSMatthew Dillon  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29ba0cc1abSMatthew Dillon  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30ba0cc1abSMatthew Dillon  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31ba0cc1abSMatthew Dillon  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32ba0cc1abSMatthew Dillon  * SUCH DAMAGE.
33ba0cc1abSMatthew Dillon  *
34ba0cc1abSMatthew Dillon  * ----------------------------------------------------------------------------
35ba0cc1abSMatthew Dillon  * "THE BEER-WARE LICENSE" (Revision 42):
36ba0cc1abSMatthew Dillon  * <phk@FreeBSD.ORG> wrote this file.  As long as you retain this notice you
37ba0cc1abSMatthew Dillon  * can do whatever you want with this stuff. If we meet some day, and you think
38ba0cc1abSMatthew Dillon  * this stuff is worth it, you can buy me a beer in return.   Poul-Henning Kamp
39ba0cc1abSMatthew Dillon  * ----------------------------------------------------------------------------
40ba0cc1abSMatthew Dillon  *
41ba0cc1abSMatthew Dillon  * Copyright (c) 1982, 1986, 1988, 1993
42ba0cc1abSMatthew Dillon  *	The Regents of the University of California.  All rights reserved.
43ba0cc1abSMatthew Dillon  * (c) UNIX System Laboratories, Inc.
44ba0cc1abSMatthew Dillon  * All or some portions of this file are derived from material licensed
45ba0cc1abSMatthew Dillon  * to the University of California by American Telephone and Telegraph
46ba0cc1abSMatthew Dillon  * Co. or Unix System Laboratories, Inc. and are reproduced herein with
47ba0cc1abSMatthew Dillon  * the permission of UNIX System Laboratories, Inc.
48ba0cc1abSMatthew Dillon  *
49ba0cc1abSMatthew Dillon  * Copyright (c) 1994 Bruce D. Evans.
50ba0cc1abSMatthew Dillon  * All rights reserved.
51ba0cc1abSMatthew Dillon  *
52ba0cc1abSMatthew Dillon  * Copyright (c) 1990 The Regents of the University of California.
53ba0cc1abSMatthew Dillon  * All rights reserved.
54ba0cc1abSMatthew Dillon  *
55ba0cc1abSMatthew Dillon  * This code is derived from software contributed to Berkeley by
56ba0cc1abSMatthew Dillon  * William Jolitz.
57ba0cc1abSMatthew Dillon  *
58ba0cc1abSMatthew Dillon  * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
59ba0cc1abSMatthew Dillon  * All rights reserved.
60ba0cc1abSMatthew Dillon  *
61ba0cc1abSMatthew Dillon  * Redistribution and use in source and binary forms, with or without
62ba0cc1abSMatthew Dillon  * modification, are permitted provided that the following conditions
63ba0cc1abSMatthew Dillon  * are met:
64ba0cc1abSMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
65ba0cc1abSMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
66ba0cc1abSMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
67ba0cc1abSMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
68ba0cc1abSMatthew Dillon  *    documentation and/or other materials provided with the distribution.
69dc71b7abSJustin C. Sherrill  * 3. Neither the name of the University nor the names of its contributors
70ba0cc1abSMatthew Dillon  *    may be used to endorse or promote products derived from this software
71ba0cc1abSMatthew Dillon  *    without specific prior written permission.
72ba0cc1abSMatthew Dillon  *
73ba0cc1abSMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
74ba0cc1abSMatthew Dillon  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
75ba0cc1abSMatthew Dillon  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
76ba0cc1abSMatthew Dillon  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
77ba0cc1abSMatthew Dillon  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
78ba0cc1abSMatthew Dillon  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
79ba0cc1abSMatthew Dillon  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
80ba0cc1abSMatthew Dillon  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
81ba0cc1abSMatthew Dillon  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
82ba0cc1abSMatthew Dillon  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
83ba0cc1abSMatthew Dillon  * SUCH DAMAGE.
84ba0cc1abSMatthew Dillon  *
85ba0cc1abSMatthew Dillon  *	@(#)ufs_disksubr.c	8.5 (Berkeley) 1/21/94
86ba0cc1abSMatthew Dillon  * $FreeBSD: src/sys/kern/subr_disk.c,v 1.20.2.6 2001/10/05 07:14:57 peter Exp $
87ba0cc1abSMatthew Dillon  * $FreeBSD: src/sys/ufs/ufs/ufs_disksubr.c,v 1.44.2.3 2001/03/05 05:42:19 obrien Exp $
88ba0cc1abSMatthew Dillon  */
89ba0cc1abSMatthew Dillon 
90ba0cc1abSMatthew Dillon #include <sys/param.h>
91ba0cc1abSMatthew Dillon #include <sys/systm.h>
92ba0cc1abSMatthew Dillon #include <sys/kernel.h>
93*805c8e8eSzrj #include <sys/malloc.h>
94ba0cc1abSMatthew Dillon #include <sys/proc.h>
95ba0cc1abSMatthew Dillon #include <sys/sysctl.h>
96ba0cc1abSMatthew Dillon #include <sys/buf.h>
97ba0cc1abSMatthew Dillon #include <sys/conf.h>
98ba0cc1abSMatthew Dillon #include <sys/disklabel.h>
992b961883SMatthew Dillon #include <sys/disklabel32.h>
100ba0cc1abSMatthew Dillon #include <sys/diskslice.h>
101ba0cc1abSMatthew Dillon #include <sys/disk.h>
102ba0cc1abSMatthew Dillon #include <sys/dtype.h>		/* DTYPE_* constants */
103ba0cc1abSMatthew Dillon #include <machine/md_var.h>
104ba0cc1abSMatthew Dillon #include <sys/ctype.h>
105ba0cc1abSMatthew Dillon #include <sys/syslog.h>
106ba0cc1abSMatthew Dillon #include <sys/device.h>
107ba0cc1abSMatthew Dillon #include <sys/msgport.h>
108ba0cc1abSMatthew Dillon #include <sys/msgport2.h>
109ba0cc1abSMatthew Dillon #include <sys/buf2.h>
110ba0cc1abSMatthew Dillon 
111ba0cc1abSMatthew Dillon #include <vfs/ufs/dinode.h>	/* XXX used only for fs.h */
112ba0cc1abSMatthew Dillon #include <vfs/ufs/fs.h>		/* XXX used only to get BBSIZE/SBSIZE */
113ba0cc1abSMatthew Dillon 
1142b961883SMatthew Dillon static void partition_info(const char *sname, int part, struct partition32 *pp);
115ba0cc1abSMatthew Dillon static void slice_info(const char *sname, struct diskslice *sp);
1162b961883SMatthew Dillon static const char *l32_fixlabel(const char *sname, struct diskslice *sp,
1172b961883SMatthew Dillon 				disklabel_t lpx, int writeflag);
118ba0cc1abSMatthew Dillon 
119ba0cc1abSMatthew Dillon /*
120ba0cc1abSMatthew Dillon  * Retrieve the partition start and extent, in blocks.  Return 0 on success,
121ba0cc1abSMatthew Dillon  * EINVAL on error.
122ba0cc1abSMatthew Dillon  */
1232b961883SMatthew Dillon static int
l32_getpartbounds(struct diskslices * ssp,disklabel_t lp,u_int32_t part,u_int64_t * start,u_int64_t * blocks)1240ffe40b3SMatthew Dillon l32_getpartbounds(struct diskslices *ssp, disklabel_t lp, u_int32_t part,
125ba0cc1abSMatthew Dillon 		  u_int64_t *start, u_int64_t *blocks)
126ba0cc1abSMatthew Dillon {
1272b961883SMatthew Dillon 	struct partition32 *pp;
128ba0cc1abSMatthew Dillon 
1292b961883SMatthew Dillon 	if (part >= lp.lab32->d_npartitions)
130ba0cc1abSMatthew Dillon 		return (EINVAL);
1312b961883SMatthew Dillon 	pp = &lp.lab32->d_partitions[part];
132ba0cc1abSMatthew Dillon 	*start = pp->p_offset;
1330ffe40b3SMatthew Dillon 	*blocks = pp->p_size;
134ba0cc1abSMatthew Dillon 	return(0);
135ba0cc1abSMatthew Dillon }
136ba0cc1abSMatthew Dillon 
13718cb7addSMatthew Dillon static void
l32_loadpartinfo(disklabel_t lp,u_int32_t part,struct partinfo * dpart)13818cb7addSMatthew Dillon l32_loadpartinfo(disklabel_t lp, u_int32_t part, struct partinfo *dpart)
139ba0cc1abSMatthew Dillon {
1402b961883SMatthew Dillon 	struct partition32 *pp;
14118cb7addSMatthew Dillon 	const size_t uuid_size = sizeof(struct uuid);
142ba0cc1abSMatthew Dillon 
14318cb7addSMatthew Dillon 	bzero(&dpart->fstype_uuid, uuid_size);
14418cb7addSMatthew Dillon 	bzero(&dpart->storage_uuid, uuid_size);
14518cb7addSMatthew Dillon 	if (part < lp.lab32->d_npartitions) {
1462b961883SMatthew Dillon 		pp = &lp.lab32->d_partitions[part];
14718cb7addSMatthew Dillon 		dpart->fstype = pp->p_fstype;
14818cb7addSMatthew Dillon 	} else {
14918cb7addSMatthew Dillon 		dpart->fstype = 0;
15018cb7addSMatthew Dillon 	}
151ba0cc1abSMatthew Dillon }
152ba0cc1abSMatthew Dillon 
1532b961883SMatthew Dillon static u_int32_t
l32_getnumparts(disklabel_t lp)1542b961883SMatthew Dillon l32_getnumparts(disklabel_t lp)
155ba0cc1abSMatthew Dillon {
1562b961883SMatthew Dillon 	return(lp.lab32->d_npartitions);
157ba0cc1abSMatthew Dillon }
158ba0cc1abSMatthew Dillon 
15946acecf8SMatthew Dillon static int
l32_getpackname(disklabel_t lp,char * buf,size_t bytes)16046acecf8SMatthew Dillon l32_getpackname(disklabel_t lp, char *buf, size_t bytes)
16146acecf8SMatthew Dillon {
16246acecf8SMatthew Dillon 	size_t slen;
16346acecf8SMatthew Dillon 
16446acecf8SMatthew Dillon 	if (lp.lab32->d_packname[0] == 0) {
16546acecf8SMatthew Dillon 		buf[0] = 0;
16646acecf8SMatthew Dillon 		return -1;
16746acecf8SMatthew Dillon 	}
16846acecf8SMatthew Dillon 	slen = strnlen(lp.lab32->d_packname, sizeof(lp.lab32->d_packname));
16946acecf8SMatthew Dillon 	if (slen >= bytes)
17046acecf8SMatthew Dillon 		slen = bytes - 1;
17146acecf8SMatthew Dillon 	bcopy(lp.lab32->d_packname, buf, slen);
17246acecf8SMatthew Dillon 	buf[slen] = 0;
17346acecf8SMatthew Dillon 
17446acecf8SMatthew Dillon 	return 0;
17546acecf8SMatthew Dillon }
17646acecf8SMatthew Dillon 
1772fa1a664SAlex Hornung static void
l32_freedisklabel(disklabel_t * lpp)1782fa1a664SAlex Hornung l32_freedisklabel(disklabel_t *lpp)
1792fa1a664SAlex Hornung {
1802fa1a664SAlex Hornung 	kfree((*lpp).lab32, M_DEVBUF);
1812fa1a664SAlex Hornung 	(*lpp).lab32 = NULL;
1822fa1a664SAlex Hornung }
1832fa1a664SAlex Hornung 
184ba0cc1abSMatthew Dillon /*
1850ffe40b3SMatthew Dillon  * Attempt to read a disk label from a device.
1860ffe40b3SMatthew Dillon  *
1870ffe40b3SMatthew Dillon  * Returns NULL on sucess, and an error string on failure
188ba0cc1abSMatthew Dillon  */
1892b961883SMatthew Dillon static const char *
l32_readdisklabel(cdev_t dev,struct diskslice * sp,disklabel_t * lpp,struct disk_info * info)1902b961883SMatthew Dillon l32_readdisklabel(cdev_t dev, struct diskslice *sp, disklabel_t *lpp,
1912b961883SMatthew Dillon 		struct disk_info *info)
192ba0cc1abSMatthew Dillon {
1932b961883SMatthew Dillon 	disklabel_t lpx;
194ba0cc1abSMatthew Dillon 	struct buf *bp;
1952b961883SMatthew Dillon 	struct disklabel32 *dlp;
1962b961883SMatthew Dillon 	const char *msg = NULL;
1972b961883SMatthew Dillon 	int secsize = info->d_media_blksize;
198ba0cc1abSMatthew Dillon 
199bf20632cSMatthew Dillon 	bp = getpbuf_mem(NULL);
200bf20632cSMatthew Dillon 	KKASSERT(secsize <= bp->b_bufsize);
2012b961883SMatthew Dillon 	bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * secsize;
202ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_done = biodone_sync;
203ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_flags |= BIO_SYNC;
2042b961883SMatthew Dillon 	bp->b_bcount = secsize;
205ba0cc1abSMatthew Dillon 	bp->b_flags &= ~B_INVAL;
206ba0cc1abSMatthew Dillon 	bp->b_cmd = BUF_CMD_READ;
207a06d536bSMatthew Dillon 	bp->b_flags |= B_FAILONDIS;
208ba0cc1abSMatthew Dillon 	dev_dstrategy(dev, &bp->b_bio1);
209ae8e83e6SMatthew Dillon 	if (biowait(&bp->b_bio1, "labrd"))
210ba0cc1abSMatthew Dillon 		msg = "I/O error";
2112b961883SMatthew Dillon 	else for (dlp = (struct disklabel32 *)bp->b_data;
2122b961883SMatthew Dillon 	    dlp <= (struct disklabel32 *)((char *)bp->b_data +
2132b961883SMatthew Dillon 	    secsize - sizeof(*dlp));
2142b961883SMatthew Dillon 	    dlp = (struct disklabel32 *)((char *)dlp + sizeof(long))) {
2152b961883SMatthew Dillon 		if (dlp->d_magic != DISKMAGIC32 ||
2162b961883SMatthew Dillon 		    dlp->d_magic2 != DISKMAGIC32) {
2170ffe40b3SMatthew Dillon 			/*
2180ffe40b3SMatthew Dillon 			 * NOTE! dsreadandsetlabel() does a strcmp() on
2190ffe40b3SMatthew Dillon 			 * this string.
2200ffe40b3SMatthew Dillon 			 */
221ba0cc1abSMatthew Dillon 			if (msg == NULL)
222ba0cc1abSMatthew Dillon 				msg = "no disk label";
2230ffe40b3SMatthew Dillon 		} else if (dlp->d_npartitions > MAXPARTITIONS32 ||
2242b961883SMatthew Dillon 			   dkcksum32(dlp) != 0) {
225ba0cc1abSMatthew Dillon 			msg = "disk label corrupted";
2262b961883SMatthew Dillon 		} else {
2272b961883SMatthew Dillon 			lpx.lab32 = dlp;
2282b961883SMatthew Dillon 			msg = l32_fixlabel(NULL, sp, lpx, FALSE);
2292b961883SMatthew Dillon 			if (msg == NULL) {
2302b961883SMatthew Dillon 				(*lpp).lab32 = kmalloc(sizeof(*dlp),
2312b961883SMatthew Dillon 						       M_DEVBUF, M_WAITOK|M_ZERO);
2322b961883SMatthew Dillon 				*(*lpp).lab32 = *dlp;
2332b961883SMatthew Dillon 			}
234ba0cc1abSMatthew Dillon 			break;
235ba0cc1abSMatthew Dillon 		}
236ba0cc1abSMatthew Dillon 	}
237ba0cc1abSMatthew Dillon 	bp->b_flags |= B_INVAL | B_AGE;
238bf20632cSMatthew Dillon 	relpbuf(bp, NULL);
239bf20632cSMatthew Dillon 
240ba0cc1abSMatthew Dillon 	return (msg);
241ba0cc1abSMatthew Dillon }
242ba0cc1abSMatthew Dillon 
243ba0cc1abSMatthew Dillon /*
244ba0cc1abSMatthew Dillon  * Check new disk label for sensibility before setting it.
245ba0cc1abSMatthew Dillon  */
2462b961883SMatthew Dillon static int
l32_setdisklabel(disklabel_t olpx,disklabel_t nlpx,struct diskslices * ssp,struct diskslice * sp,u_int32_t * openmask)2470ffe40b3SMatthew Dillon l32_setdisklabel(disklabel_t olpx, disklabel_t nlpx, struct diskslices *ssp,
248ba0cc1abSMatthew Dillon 		 struct diskslice *sp, u_int32_t *openmask)
249ba0cc1abSMatthew Dillon {
2502b961883SMatthew Dillon 	struct disklabel32 *olp, *nlp;
2512b961883SMatthew Dillon 	struct partition32 *opp, *npp;
252ba0cc1abSMatthew Dillon 	int part;
253ba0cc1abSMatthew Dillon 	int i;
254ba0cc1abSMatthew Dillon 
2552b961883SMatthew Dillon 	olp = olpx.lab32;
2562b961883SMatthew Dillon 	nlp = nlpx.lab32;
2572b961883SMatthew Dillon 
258ba0cc1abSMatthew Dillon 	/*
259ba0cc1abSMatthew Dillon 	 * Check it is actually a disklabel we are looking at.
260ba0cc1abSMatthew Dillon 	 */
2612b961883SMatthew Dillon 	if (nlp->d_magic != DISKMAGIC32 || nlp->d_magic2 != DISKMAGIC32 ||
2622b961883SMatthew Dillon 	    dkcksum32(nlp) != 0)
263ba0cc1abSMatthew Dillon 		return (EINVAL);
264ba0cc1abSMatthew Dillon 
265ba0cc1abSMatthew Dillon 	/*
266ba0cc1abSMatthew Dillon 	 * For each partition that we think is open, check the new disklabel
267ba0cc1abSMatthew Dillon 	 * for compatibility.  Ignore special partitions (>= 128).
268ba0cc1abSMatthew Dillon 	 */
269ba0cc1abSMatthew Dillon 	i = 0;
270ba0cc1abSMatthew Dillon 	while (i < 128) {
271ba0cc1abSMatthew Dillon 		if (openmask[i >> 5] == 0) {
272ba0cc1abSMatthew Dillon 			i += 32;
273ba0cc1abSMatthew Dillon 			continue;
274ba0cc1abSMatthew Dillon 		}
275ba0cc1abSMatthew Dillon 		if ((openmask[i >> 5] & (1 << (i & 31))) == 0) {
276ba0cc1abSMatthew Dillon 			++i;
277ba0cc1abSMatthew Dillon 			continue;
278ba0cc1abSMatthew Dillon 		}
279ba0cc1abSMatthew Dillon 		if (nlp->d_npartitions <= i)
280ba0cc1abSMatthew Dillon 			return (EBUSY);
281ba0cc1abSMatthew Dillon 		opp = &olp->d_partitions[i];
282ba0cc1abSMatthew Dillon 		npp = &nlp->d_partitions[i];
283ba0cc1abSMatthew Dillon 		if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
284ba0cc1abSMatthew Dillon 			return (EBUSY);
285ba0cc1abSMatthew Dillon 		/*
286ba0cc1abSMatthew Dillon 		 * Copy internally-set partition information
287ba0cc1abSMatthew Dillon 		 * if new label doesn't include it.		XXX
288ba0cc1abSMatthew Dillon 		 * (If we are using it then we had better stay the same type)
289ba0cc1abSMatthew Dillon 		 * This is possibly dubious, as someone else noted (XXX)
290ba0cc1abSMatthew Dillon 		 */
291ba0cc1abSMatthew Dillon 		if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
292ba0cc1abSMatthew Dillon 			npp->p_fstype = opp->p_fstype;
293ba0cc1abSMatthew Dillon 			npp->p_fsize = opp->p_fsize;
294ba0cc1abSMatthew Dillon 			npp->p_frag = opp->p_frag;
295ba0cc1abSMatthew Dillon 			npp->p_cpg = opp->p_cpg;
296ba0cc1abSMatthew Dillon 		}
297ba0cc1abSMatthew Dillon 		++i;
298ba0cc1abSMatthew Dillon 	}
299ba0cc1abSMatthew Dillon  	nlp->d_checksum = 0;
3002b961883SMatthew Dillon  	nlp->d_checksum = dkcksum32(nlp);
301ba0cc1abSMatthew Dillon 	*olp = *nlp;
302ba0cc1abSMatthew Dillon 
303ba0cc1abSMatthew Dillon 	if (olp->d_partitions[RAW_PART].p_offset)
304ba0cc1abSMatthew Dillon 		return (EXDEV);
305ba0cc1abSMatthew Dillon 	if (olp->d_secperunit > sp->ds_size)
306ba0cc1abSMatthew Dillon 		return (ENOSPC);
307ba0cc1abSMatthew Dillon 	for (part = 0; part < olp->d_npartitions; ++part) {
308ba0cc1abSMatthew Dillon 		if (olp->d_partitions[part].p_size > sp->ds_size)
309ba0cc1abSMatthew Dillon 			return(ENOSPC);
310ba0cc1abSMatthew Dillon 	}
311ba0cc1abSMatthew Dillon 	return (0);
312ba0cc1abSMatthew Dillon }
313ba0cc1abSMatthew Dillon 
314ba0cc1abSMatthew Dillon /*
315ba0cc1abSMatthew Dillon  * Write disk label back to device after modification.
316ba0cc1abSMatthew Dillon  */
3172b961883SMatthew Dillon static int
l32_writedisklabel(cdev_t dev,struct diskslices * ssp,struct diskslice * sp,disklabel_t lpx)3180ffe40b3SMatthew Dillon l32_writedisklabel(cdev_t dev, struct diskslices *ssp, struct diskslice *sp,
3190ffe40b3SMatthew Dillon 		   disklabel_t lpx)
320ba0cc1abSMatthew Dillon {
3212b961883SMatthew Dillon 	struct disklabel32 *lp;
3222b961883SMatthew Dillon 	struct disklabel32 *dlp;
323ba0cc1abSMatthew Dillon 	struct buf *bp;
3242b961883SMatthew Dillon 	const char *msg;
325ba0cc1abSMatthew Dillon 	int error = 0;
326ba0cc1abSMatthew Dillon 
3272b961883SMatthew Dillon 	lp = lpx.lab32;
3282b961883SMatthew Dillon 
329ba0cc1abSMatthew Dillon 	if (lp->d_partitions[RAW_PART].p_offset != 0)
330ba0cc1abSMatthew Dillon 		return (EXDEV);			/* not quite right */
331cd29885aSMatthew Dillon 
332bf20632cSMatthew Dillon 	bp = getpbuf_mem(NULL);
333bf20632cSMatthew Dillon 	KKASSERT((int)lp->d_secsize <= bp->b_bufsize);
3342b961883SMatthew Dillon 	bp->b_bio1.bio_offset = (off_t)LABELSECTOR32 * lp->d_secsize;
335ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_done = biodone_sync;
336ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_flags |= BIO_SYNC;
337ba0cc1abSMatthew Dillon 	bp->b_bcount = lp->d_secsize;
338a06d536bSMatthew Dillon 	bp->b_flags |= B_FAILONDIS;
339cd29885aSMatthew Dillon 
340ba0cc1abSMatthew Dillon #if 1
341ba0cc1abSMatthew Dillon 	/*
342ba0cc1abSMatthew Dillon 	 * We read the label first to see if it's there,
343ba0cc1abSMatthew Dillon 	 * in which case we will put ours at the same offset into the block..
344ba0cc1abSMatthew Dillon 	 * (I think this is stupid [Julian])
345ba0cc1abSMatthew Dillon 	 * Note that you can't write a label out over a corrupted label!
346ba0cc1abSMatthew Dillon 	 * (also stupid.. how do you write the first one? by raw writes?)
347ba0cc1abSMatthew Dillon 	 */
348ba0cc1abSMatthew Dillon 	bp->b_flags &= ~B_INVAL;
349ba0cc1abSMatthew Dillon 	bp->b_cmd = BUF_CMD_READ;
350aec8eea4SMatthew Dillon 	KKASSERT(dkpart(dev) == WHOLE_SLICE_PART);
351aec8eea4SMatthew Dillon 	dev_dstrategy(dev, &bp->b_bio1);
352ae8e83e6SMatthew Dillon 	error = biowait(&bp->b_bio1, "labrd");
353ba0cc1abSMatthew Dillon 	if (error)
354ba0cc1abSMatthew Dillon 		goto done;
3552b961883SMatthew Dillon 	for (dlp = (struct disklabel32 *)bp->b_data;
3562b961883SMatthew Dillon 	    dlp <= (struct disklabel32 *)
357ba0cc1abSMatthew Dillon 	      ((char *)bp->b_data + lp->d_secsize - sizeof(*dlp));
3582b961883SMatthew Dillon 	    dlp = (struct disklabel32 *)((char *)dlp + sizeof(long))) {
3592b961883SMatthew Dillon 		if (dlp->d_magic == DISKMAGIC32 &&
3602b961883SMatthew Dillon 		    dlp->d_magic2 == DISKMAGIC32 && dkcksum32(dlp) == 0) {
361ba0cc1abSMatthew Dillon 			*dlp = *lp;
3622b961883SMatthew Dillon 			lpx.lab32 = dlp;
3632b961883SMatthew Dillon 			msg = l32_fixlabel(NULL, sp, lpx, TRUE);
3642b961883SMatthew Dillon 			if (msg) {
3652b961883SMatthew Dillon 				error = EINVAL;
3662b961883SMatthew Dillon 			} else {
367ba0cc1abSMatthew Dillon 				bp->b_cmd = BUF_CMD_WRITE;
368ae8e83e6SMatthew Dillon 				bp->b_bio1.bio_done = biodone_sync;
369ae8e83e6SMatthew Dillon 				bp->b_bio1.bio_flags |= BIO_SYNC;
370aec8eea4SMatthew Dillon 				KKASSERT(dkpart(dev) == WHOLE_SLICE_PART);
371aec8eea4SMatthew Dillon 				dev_dstrategy(dev, &bp->b_bio1);
372ae8e83e6SMatthew Dillon 				error = biowait(&bp->b_bio1, "labwr");
3732b961883SMatthew Dillon 			}
374ba0cc1abSMatthew Dillon 			goto done;
375ba0cc1abSMatthew Dillon 		}
376ba0cc1abSMatthew Dillon 	}
377ba0cc1abSMatthew Dillon 	error = ESRCH;
378ba0cc1abSMatthew Dillon done:
379ba0cc1abSMatthew Dillon #else
380ba0cc1abSMatthew Dillon 	bzero(bp->b_data, lp->d_secsize);
3812b961883SMatthew Dillon 	dlp = (struct disklabel32 *)bp->b_data;
382ba0cc1abSMatthew Dillon 	*dlp = *lp;
383ba0cc1abSMatthew Dillon 	bp->b_flags &= ~B_INVAL;
384ba0cc1abSMatthew Dillon 	bp->b_cmd = BUF_CMD_WRITE;
385ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_done = biodone_sync;
386ae8e83e6SMatthew Dillon 	bp->b_bio1.bio_flags |= BIO_SYNC;
387ba0cc1abSMatthew Dillon 	BUF_STRATEGY(bp, 1);
388ae8e83e6SMatthew Dillon 	error = biowait(&bp->b_bio1, "labwr");
389ba0cc1abSMatthew Dillon #endif
390ba0cc1abSMatthew Dillon 	bp->b_flags |= B_INVAL | B_AGE;
391bf20632cSMatthew Dillon 	relpbuf(bp, NULL);
392bf20632cSMatthew Dillon 
393ba0cc1abSMatthew Dillon 	return (error);
394ba0cc1abSMatthew Dillon }
395ba0cc1abSMatthew Dillon 
396ba0cc1abSMatthew Dillon /*
397ba0cc1abSMatthew Dillon  * Create a disklabel based on a disk_info structure, initializing
398ba0cc1abSMatthew Dillon  * the appropriate fields and creating a raw partition that covers the
399ba0cc1abSMatthew Dillon  * whole disk.
400ba0cc1abSMatthew Dillon  *
401ba0cc1abSMatthew Dillon  * If a diskslice is passed, the label is truncated to the slice
402ba0cc1abSMatthew Dillon  */
4032b961883SMatthew Dillon static disklabel_t
l32_clone_label(struct disk_info * info,struct diskslice * sp)4042b961883SMatthew Dillon l32_clone_label(struct disk_info *info, struct diskslice *sp)
405ba0cc1abSMatthew Dillon {
4062b961883SMatthew Dillon 	struct disklabel32 *lp;
4072b961883SMatthew Dillon 	disklabel_t res;
408ba0cc1abSMatthew Dillon 
4092b961883SMatthew Dillon 	lp = kmalloc(sizeof *lp, M_DEVBUF, M_WAITOK | M_ZERO);
4102b961883SMatthew Dillon 	lp->d_nsectors = info->d_secpertrack;
4112b961883SMatthew Dillon 	lp->d_ntracks = info->d_nheads;
4122b961883SMatthew Dillon 	lp->d_secpercyl = info->d_secpercyl;
4132b961883SMatthew Dillon 	lp->d_secsize = info->d_media_blksize;
414ba0cc1abSMatthew Dillon 
415ba0cc1abSMatthew Dillon 	if (sp)
4162b961883SMatthew Dillon 		lp->d_secperunit = (u_int)sp->ds_size;
417ba0cc1abSMatthew Dillon 	else
4182b961883SMatthew Dillon 		lp->d_secperunit = (u_int)info->d_media_blocks;
419ba0cc1abSMatthew Dillon 
4202b961883SMatthew Dillon 	if (lp->d_typename[0] == '\0')
4212b961883SMatthew Dillon 		strncpy(lp->d_typename, "amnesiac", sizeof(lp->d_typename));
4222b961883SMatthew Dillon 	if (lp->d_packname[0] == '\0')
4232b961883SMatthew Dillon 		strncpy(lp->d_packname, "fictitious", sizeof(lp->d_packname));
4242b961883SMatthew Dillon 	if (lp->d_nsectors == 0)
4252b961883SMatthew Dillon 		lp->d_nsectors = 32;
4262b961883SMatthew Dillon 	if (lp->d_ntracks == 0)
4272b961883SMatthew Dillon 		lp->d_ntracks = 64;
4282b961883SMatthew Dillon 	lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
4292b961883SMatthew Dillon 	lp->d_ncylinders = lp->d_secperunit / lp->d_secpercyl;
4302b961883SMatthew Dillon 	if (lp->d_rpm == 0)
4312b961883SMatthew Dillon 		lp->d_rpm = 3600;
4322b961883SMatthew Dillon 	if (lp->d_interleave == 0)
4332b961883SMatthew Dillon 		lp->d_interleave = 1;
4342b961883SMatthew Dillon 	if (lp->d_npartitions < RAW_PART + 1)
4350ffe40b3SMatthew Dillon 		lp->d_npartitions = MAXPARTITIONS32;
4362b961883SMatthew Dillon 	if (lp->d_bbsize == 0)
4372b961883SMatthew Dillon 		lp->d_bbsize = BBSIZE;
4382b961883SMatthew Dillon 	if (lp->d_sbsize == 0)
4392b961883SMatthew Dillon 		lp->d_sbsize = SBSIZE;
440ba0cc1abSMatthew Dillon 
441ba0cc1abSMatthew Dillon 	/*
442ba0cc1abSMatthew Dillon 	 * Used by various devices to create a compatibility slice which
443ba0cc1abSMatthew Dillon 	 * allows us to mount root from devices which do not have a
444ba0cc1abSMatthew Dillon 	 * disklabel.  Particularly: CDs.
445ba0cc1abSMatthew Dillon 	 */
4462b961883SMatthew Dillon 	lp->d_partitions[RAW_PART].p_size = lp->d_secperunit;
447ba0cc1abSMatthew Dillon 	if (info->d_dsflags & DSO_COMPATPARTA) {
4482b961883SMatthew Dillon 		lp->d_partitions[0].p_size = lp->d_secperunit;
4492b961883SMatthew Dillon 		lp->d_partitions[0].p_fstype = FS_OTHER;
450ba0cc1abSMatthew Dillon 	}
4512b961883SMatthew Dillon 	lp->d_magic = DISKMAGIC32;
4522b961883SMatthew Dillon 	lp->d_magic2 = DISKMAGIC32;
4532b961883SMatthew Dillon 	lp->d_checksum = dkcksum32(lp);
4542b961883SMatthew Dillon 	res.lab32 = lp;
4552b961883SMatthew Dillon 	return (res);
456ba0cc1abSMatthew Dillon }
457ba0cc1abSMatthew Dillon 
4582b961883SMatthew Dillon static void
l32_makevirginlabel(disklabel_t lpx,struct diskslices * ssp,struct diskslice * sp,struct disk_info * info)4592b961883SMatthew Dillon l32_makevirginlabel(disklabel_t lpx, struct diskslices *ssp,
460ba0cc1abSMatthew Dillon 		    struct diskslice *sp, struct disk_info *info)
461ba0cc1abSMatthew Dillon {
4622b961883SMatthew Dillon 	struct disklabel32 *lp = lpx.lab32;
4632b961883SMatthew Dillon 	struct partition32 *pp;
4640ffe40b3SMatthew Dillon 	disklabel_t template;
465ba0cc1abSMatthew Dillon 
4660ffe40b3SMatthew Dillon 	template = l32_clone_label(info, NULL);
4670ffe40b3SMatthew Dillon 	bcopy(template.opaque, lp, sizeof(struct disklabel32));
4680ffe40b3SMatthew Dillon 
4692b961883SMatthew Dillon 	lp->d_magic = DISKMAGIC32;
4702b961883SMatthew Dillon 	lp->d_magic2 = DISKMAGIC32;
471ba0cc1abSMatthew Dillon 
4720ffe40b3SMatthew Dillon 	lp->d_npartitions = MAXPARTITIONS32;
473ba0cc1abSMatthew Dillon 	if (lp->d_interleave == 0)
474ba0cc1abSMatthew Dillon 		lp->d_interleave = 1;
475ba0cc1abSMatthew Dillon 	if (lp->d_rpm == 0)
476ba0cc1abSMatthew Dillon 		lp->d_rpm = 3600;
477ba0cc1abSMatthew Dillon 	if (lp->d_nsectors == 0)	/* sectors per track */
478ba0cc1abSMatthew Dillon 		lp->d_nsectors = 32;
479ba0cc1abSMatthew Dillon 	if (lp->d_ntracks == 0)		/* heads */
480ba0cc1abSMatthew Dillon 		lp->d_ntracks = 64;
481ba0cc1abSMatthew Dillon 	lp->d_ncylinders = 0;
482ba0cc1abSMatthew Dillon 	lp->d_bbsize = BBSIZE;
483ba0cc1abSMatthew Dillon 	lp->d_sbsize = SBSIZE;
484ba0cc1abSMatthew Dillon 
485ba0cc1abSMatthew Dillon 	/*
486ba0cc1abSMatthew Dillon 	 * If the slice or GPT partition is really small we could
487ba0cc1abSMatthew Dillon 	 * wind up with an absurd calculation for ncylinders.
488ba0cc1abSMatthew Dillon 	 */
489ba0cc1abSMatthew Dillon 	while (lp->d_ncylinders < 4) {
490ba0cc1abSMatthew Dillon 		if (lp->d_ntracks > 1)
491ba0cc1abSMatthew Dillon 			lp->d_ntracks >>= 1;
492ba0cc1abSMatthew Dillon 		else if (lp->d_nsectors > 1)
493ba0cc1abSMatthew Dillon 			lp->d_nsectors >>= 1;
494ba0cc1abSMatthew Dillon 		else
495ba0cc1abSMatthew Dillon 			break;
496ba0cc1abSMatthew Dillon 		lp->d_secpercyl = lp->d_nsectors * lp->d_ntracks;
497ba0cc1abSMatthew Dillon 		lp->d_ncylinders = sp->ds_size / lp->d_secpercyl;
498ba0cc1abSMatthew Dillon 	}
499ba0cc1abSMatthew Dillon 
500ba0cc1abSMatthew Dillon 	/*
501ba0cc1abSMatthew Dillon 	 * Set or Modify the partition sizes to accomodate the slice,
502ba0cc1abSMatthew Dillon 	 * since we started with a copy of the virgin label stored
503ba0cc1abSMatthew Dillon 	 * in the whole-disk-slice and we are probably not a
504ba0cc1abSMatthew Dillon 	 * whole-disk slice.
505ba0cc1abSMatthew Dillon 	 */
506ba0cc1abSMatthew Dillon 	lp->d_secperunit = sp->ds_size;
507ba0cc1abSMatthew Dillon 	pp = &lp->d_partitions[RAW_PART];
508ba0cc1abSMatthew Dillon 	pp->p_offset = 0;
509ba0cc1abSMatthew Dillon 	pp->p_size = lp->d_secperunit;
510ba0cc1abSMatthew Dillon 	if (info->d_dsflags & DSO_COMPATPARTA) {
511ba0cc1abSMatthew Dillon 		pp = &lp->d_partitions[0];
512ba0cc1abSMatthew Dillon 		pp->p_offset = 0;
513ba0cc1abSMatthew Dillon 		pp->p_size = lp->d_secperunit;
514ba0cc1abSMatthew Dillon 		pp->p_fstype = FS_OTHER;
515ba0cc1abSMatthew Dillon 	}
516ba0cc1abSMatthew Dillon 	lp->d_checksum = 0;
5172b961883SMatthew Dillon 	lp->d_checksum = dkcksum32(lp);
5180ffe40b3SMatthew Dillon 
5190ffe40b3SMatthew Dillon 	kfree(template.opaque, M_DEVBUF);
520ba0cc1abSMatthew Dillon }
521ba0cc1abSMatthew Dillon 
5222b961883SMatthew Dillon static const char *
l32_fixlabel(const char * sname,struct diskslice * sp,disklabel_t lpx,int writeflag)5232b961883SMatthew Dillon l32_fixlabel(const char *sname, struct diskslice *sp,
5242b961883SMatthew Dillon 	     disklabel_t lpx, int writeflag)
525ba0cc1abSMatthew Dillon {
5262b961883SMatthew Dillon 	struct disklabel32 *lp;
5272b961883SMatthew Dillon 	struct partition32 *pp;
528ba0cc1abSMatthew Dillon 	u_int64_t start;
529ba0cc1abSMatthew Dillon 	u_int64_t end;
530ba0cc1abSMatthew Dillon 	u_int64_t offset;
531ba0cc1abSMatthew Dillon 	int part;
532ba0cc1abSMatthew Dillon 	int warned;
533ba0cc1abSMatthew Dillon 
5342b961883SMatthew Dillon 	lp = lpx.lab32;
5352b961883SMatthew Dillon 
536ba0cc1abSMatthew Dillon 	/* These errors "can't happen" so don't bother reporting details. */
5372b961883SMatthew Dillon 	if (lp->d_magic != DISKMAGIC32 || lp->d_magic2 != DISKMAGIC32)
538ba0cc1abSMatthew Dillon 		return ("fixlabel: invalid magic");
5392b961883SMatthew Dillon 	if (dkcksum32(lp) != 0)
540ba0cc1abSMatthew Dillon 		return ("fixlabel: invalid checksum");
541ba0cc1abSMatthew Dillon 
542ba0cc1abSMatthew Dillon 	pp = &lp->d_partitions[RAW_PART];
543ba0cc1abSMatthew Dillon 
544ba0cc1abSMatthew Dillon 	/*
545ba0cc1abSMatthew Dillon 	 * What a mess.  For ages old backwards compatibility the disklabel
546ba0cc1abSMatthew Dillon 	 * on-disk stores absolute offsets instead of slice-relative offsets.
547ba0cc1abSMatthew Dillon 	 * So fix it up when reading, writing, or snooping.
548ba0cc1abSMatthew Dillon 	 *
549ba0cc1abSMatthew Dillon 	 * The in-core label is always slice-relative.
550ba0cc1abSMatthew Dillon 	 */
551ba0cc1abSMatthew Dillon 	if (writeflag) {
552ba0cc1abSMatthew Dillon 		start = 0;
553ba0cc1abSMatthew Dillon 		offset = sp->ds_offset;
554ba0cc1abSMatthew Dillon 	} else {
555ba0cc1abSMatthew Dillon 		start = sp->ds_offset;
556ba0cc1abSMatthew Dillon 		offset = -sp->ds_offset;
557ba0cc1abSMatthew Dillon 	}
558ba0cc1abSMatthew Dillon 	if (pp->p_offset != start) {
559ba0cc1abSMatthew Dillon 		if (sname != NULL) {
560ba0cc1abSMatthew Dillon 			kprintf(
561ba0cc1abSMatthew Dillon "%s: rejecting BSD label: raw partition offset != slice offset\n",
562ba0cc1abSMatthew Dillon 			       sname);
563ba0cc1abSMatthew Dillon 			slice_info(sname, sp);
564ba0cc1abSMatthew Dillon 			partition_info(sname, RAW_PART, pp);
565ba0cc1abSMatthew Dillon 		}
566ba0cc1abSMatthew Dillon 		return ("fixlabel: raw partition offset != slice offset");
567ba0cc1abSMatthew Dillon 	}
568ba0cc1abSMatthew Dillon 	if (pp->p_size != sp->ds_size) {
569ba0cc1abSMatthew Dillon 		if (sname != NULL) {
570ba0cc1abSMatthew Dillon 			kprintf("%s: raw partition size != slice size\n", sname);
571ba0cc1abSMatthew Dillon 			slice_info(sname, sp);
572ba0cc1abSMatthew Dillon 			partition_info(sname, RAW_PART, pp);
573ba0cc1abSMatthew Dillon 		}
574ba0cc1abSMatthew Dillon 		if (pp->p_size > sp->ds_size) {
575ba0cc1abSMatthew Dillon 			if (sname == NULL)
576ba0cc1abSMatthew Dillon 				return ("fixlabel: raw partition size > slice size");
577ba0cc1abSMatthew Dillon 			kprintf("%s: truncating raw partition\n", sname);
578ba0cc1abSMatthew Dillon 			pp->p_size = sp->ds_size;
579ba0cc1abSMatthew Dillon 		}
580ba0cc1abSMatthew Dillon 	}
581ba0cc1abSMatthew Dillon 	end = start + sp->ds_size;
582ba0cc1abSMatthew Dillon 	if (start > end)
583ba0cc1abSMatthew Dillon 		return ("fixlabel: slice wraps");
584ba0cc1abSMatthew Dillon 	if (lp->d_secpercyl <= 0)
585ba0cc1abSMatthew Dillon 		return ("fixlabel: d_secpercyl <= 0");
586ba0cc1abSMatthew Dillon 	pp -= RAW_PART;
587ba0cc1abSMatthew Dillon 	warned = FALSE;
588ba0cc1abSMatthew Dillon 	for (part = 0; part < lp->d_npartitions; part++, pp++) {
589ba0cc1abSMatthew Dillon 		if (pp->p_offset != 0 || pp->p_size != 0) {
590ba0cc1abSMatthew Dillon 			if (pp->p_offset < start
591ba0cc1abSMatthew Dillon 			    || pp->p_offset + pp->p_size > end
592ba0cc1abSMatthew Dillon 			    || pp->p_offset + pp->p_size < pp->p_offset) {
593ba0cc1abSMatthew Dillon 				if (sname != NULL) {
594ba0cc1abSMatthew Dillon 					kprintf(
595ba0cc1abSMatthew Dillon "%s: rejecting partition in BSD label: it isn't entirely within the slice\n",
596ba0cc1abSMatthew Dillon 					       sname);
597ba0cc1abSMatthew Dillon 					if (!warned) {
598ba0cc1abSMatthew Dillon 						slice_info(sname, sp);
599ba0cc1abSMatthew Dillon 						warned = TRUE;
600ba0cc1abSMatthew Dillon 					}
601ba0cc1abSMatthew Dillon 					partition_info(sname, part, pp);
602ba0cc1abSMatthew Dillon 				}
603ba0cc1abSMatthew Dillon 				/* XXX else silently discard junk. */
604ba0cc1abSMatthew Dillon 				bzero(pp, sizeof *pp);
605ba0cc1abSMatthew Dillon 			} else {
606ba0cc1abSMatthew Dillon 				pp->p_offset += offset;
607ba0cc1abSMatthew Dillon 			}
608ba0cc1abSMatthew Dillon 		}
609ba0cc1abSMatthew Dillon 	}
610ba0cc1abSMatthew Dillon 	lp->d_ncylinders = sp->ds_size / lp->d_secpercyl;
611ba0cc1abSMatthew Dillon 	lp->d_secperunit = sp->ds_size;
612ba0cc1abSMatthew Dillon  	lp->d_checksum = 0;
6132b961883SMatthew Dillon  	lp->d_checksum = dkcksum32(lp);
614ba0cc1abSMatthew Dillon 	return (NULL);
615ba0cc1abSMatthew Dillon }
616ba0cc1abSMatthew Dillon 
6170ffe40b3SMatthew Dillon /*
6180ffe40b3SMatthew Dillon  * Set the number of blocks at the beginning of the slice which have
6190ffe40b3SMatthew Dillon  * been reserved for label operations.  This area will be write-protected
6200ffe40b3SMatthew Dillon  * when accessed via the slice.
6210ffe40b3SMatthew Dillon  */
6222b961883SMatthew Dillon static void
l32_adjust_label_reserved(struct diskslices * ssp,int slice,struct diskslice * sp)6232b961883SMatthew Dillon l32_adjust_label_reserved(struct diskslices *ssp, int slice,
6242b961883SMatthew Dillon 			  struct diskslice *sp)
625ba0cc1abSMatthew Dillon {
6260ffe40b3SMatthew Dillon 	/*struct disklabel32 *lp = sp->ds_label.lab32;*/
627ba0cc1abSMatthew Dillon 	sp->ds_reserved = SBSIZE / ssp->dss_secsize;
628ba0cc1abSMatthew Dillon }
629ba0cc1abSMatthew Dillon 
630ba0cc1abSMatthew Dillon static void
partition_info(const char * sname,int part,struct partition32 * pp)6312b961883SMatthew Dillon partition_info(const char *sname, int part, struct partition32 *pp)
632ba0cc1abSMatthew Dillon {
633ba0cc1abSMatthew Dillon 	kprintf("%s%c: start %lu, end %lu, size %lu\n", sname, 'a' + part,
634ba0cc1abSMatthew Dillon 		(u_long)pp->p_offset, (u_long)(pp->p_offset + pp->p_size - 1),
635ba0cc1abSMatthew Dillon 		(u_long)pp->p_size);
636ba0cc1abSMatthew Dillon }
637ba0cc1abSMatthew Dillon 
638ba0cc1abSMatthew Dillon static void
slice_info(const char * sname,struct diskslice * sp)639ba0cc1abSMatthew Dillon slice_info(const char *sname, struct diskslice *sp)
640ba0cc1abSMatthew Dillon {
641ba0cc1abSMatthew Dillon 	kprintf("%s: start %llu, end %llu, size %llu\n", sname,
642973c11b9SMatthew Dillon 	       (long long)sp->ds_offset,
643973c11b9SMatthew Dillon 	       (long long)sp->ds_offset + sp->ds_size - 1,
644973c11b9SMatthew Dillon 	       (long long)sp->ds_size);
645ba0cc1abSMatthew Dillon }
646ba0cc1abSMatthew Dillon 
6472b961883SMatthew Dillon struct disklabel_ops disklabel32_ops = {
6482b961883SMatthew Dillon 	.labelsize = sizeof(struct disklabel32),
6492b961883SMatthew Dillon 	.op_readdisklabel = l32_readdisklabel,
6502b961883SMatthew Dillon 	.op_setdisklabel = l32_setdisklabel,
6512b961883SMatthew Dillon 	.op_writedisklabel = l32_writedisklabel,
6522b961883SMatthew Dillon 	.op_clone_label = l32_clone_label,
6532b961883SMatthew Dillon 	.op_adjust_label_reserved = l32_adjust_label_reserved,
6542b961883SMatthew Dillon 	.op_getpartbounds = l32_getpartbounds,
65518cb7addSMatthew Dillon 	.op_loadpartinfo = l32_loadpartinfo,
6562b961883SMatthew Dillon 	.op_getnumparts = l32_getnumparts,
6572fa1a664SAlex Hornung 	.op_makevirginlabel = l32_makevirginlabel,
65846acecf8SMatthew Dillon 	.op_getpackname = l32_getpackname,
6592fa1a664SAlex Hornung 	.op_freedisklabel = l32_freedisklabel
6602b961883SMatthew Dillon };
6612b961883SMatthew Dillon 
662