xref: /netbsd/sys/arch/mac68k/mac68k/disksubr.c (revision c4a72b64)
1 /*	$NetBSD: disksubr.c,v 1.42 2002/06/29 19:44:52 scottr 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. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by the University of
18  *	California, Berkeley and its contributors.
19  * 4. Neither the name of the University nor the names of its contributors
20  *    may be used to endorse or promote products derived from this software
21  *    without specific prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33  * SUCH DAMAGE.
34  *
35  *	@(#)ufs_disksubr.c	7.16 (Berkeley) 5/4/91
36  */
37 /*-
38  * Copyright (C) 1993	Allen K. Briggs, Chris P. Caputo,
39  *			Michael L. Finch, Bradley A. Grantham, and
40  *			Lawrence A. Kesteloot
41  * All rights reserved.
42  *
43  * Redistribution and use in source and binary forms, with or without
44  * modification, are permitted provided that the following conditions
45  * are met:
46  * 1. Redistributions of source code must retain the above copyright
47  *    notice, this list of conditions and the following disclaimer.
48  * 2. Redistributions in binary form must reproduce the above copyright
49  *    notice, this list of conditions and the following disclaimer in the
50  *    documentation and/or other materials provided with the distribution.
51  * 3. All advertising materials mentioning features or use of this software
52  *    must display the following acknowledgement:
53  *	This product includes software developed by the Alice Group.
54  * 4. The names of the Alice Group or any of its members may not be used
55  *    to endorse or promote products derived from this software without
56  *    specific prior written permission.
57  *
58  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
59  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
60  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
61  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
62  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
63  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
64  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
65  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
66  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
67  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
68  *
69  */
70 
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/buf.h>
74 #include <sys/disk.h>
75 #include <sys/disklabel.h>
76 #include <sys/disklabel_mbr.h>
77 #include <sys/syslog.h>
78 
79 #include <machine/bswap.h>
80 
81 #define NUM_PARTS 32
82 
83 #define ROOT_PART 1
84 #define UFS_PART 2
85 #define SWAP_PART 3
86 #define HFS_PART 4
87 #define SCRATCH_PART 5
88 
89 int fat_types[] = {
90 	MBR_PTYPE_FAT12, MBR_PTYPE_FAT16S,
91 	MBR_PTYPE_FAT16B, MBR_PTYPE_FAT32,
92 	MBR_PTYPE_FAT32L, MBR_PTYPE_FAT16L,
93 	-1
94 };
95 
96 static int getFreeLabelEntry __P((struct disklabel *));
97 static int whichType __P((struct part_map_entry *));
98 static void setpartition __P((struct part_map_entry *,
99 		struct partition *, int));
100 static int getNamedType __P((struct part_map_entry *, int,
101 		struct disklabel *, int, int, int *));
102 static char *read_mac_label __P((char *, struct disklabel *, int *));
103 static char *read_mbr_label __P((char *, struct disklabel *, int *));
104 static char *read_bsd_label __P((char *, struct disklabel *, int *));
105 
106 
107 /*
108  * Find an entry in the disk label that is unused and return it
109  * or -1 if no entry
110  */
111 static int
112 getFreeLabelEntry(lp)
113 	struct disklabel *lp;
114 {
115 	int i;
116 
117 	for (i = 0; i < MAXPARTITIONS; i++) {
118 		if ((i != RAW_PART)
119 		    && (lp->d_partitions[i].p_fstype == FS_UNUSED))
120 			return i;
121 	}
122 	return -1;
123 }
124 
125 /*
126  * figure out what the type of the given part is and return it
127  */
128 static int
129 whichType(part)
130 	struct part_map_entry *part;
131 {
132 	struct blockzeroblock *bzb;
133 	char typestr[32], *s;
134 	int type;
135 
136 	if (part->pmSig != PART_ENTRY_MAGIC || part->pmPartType[0] == '\0')
137 		return 0;
138 
139 	strncpy(typestr, (char *)part->pmPartType, sizeof(typestr));
140 	typestr[sizeof(typestr) - 1] = '\0';
141 	for (s = typestr; *s; s++)
142 		if ((*s >= 'a') && (*s <= 'z'))
143 			*s = (*s - 'a' + 'A');
144 
145 	if (strcmp(PART_TYPE_DRIVER, typestr) == 0 ||
146 	    strcmp(PART_TYPE_DRIVER43, typestr) == 0 ||
147 	    strcmp(PART_TYPE_DRIVERATA, typestr) == 0 ||
148 	    strcmp(PART_TYPE_FWB_COMPONENT, typestr) == 0 ||
149 	    strcmp(PART_TYPE_PARTMAP, typestr) == 0)
150 		type = 0;
151 	else if (strcmp(PART_TYPE_UNIX, typestr) == 0) {
152 		/* unix part, swap, root, usr */
153 		bzb = (struct blockzeroblock *)(&part->pmBootArgs);
154 		if (bzb->bzbMagic != BZB_MAGIC)
155 			type = 0;
156 		else if (bzb->bzbFlags & BZB_ROOTFS)
157 			type = ROOT_PART;
158 		else if (bzb->bzbFlags & BZB_USRFS)
159 			type = UFS_PART;
160 		else if (bzb->bzbType == BZB_TYPESWAP)
161 			type = SWAP_PART;
162 		else
163 			type = SCRATCH_PART;
164 	} else if (strcmp(PART_TYPE_MAC, typestr) == 0)
165 		type = HFS_PART;
166 	else
167 		type = SCRATCH_PART;	/* no known type */
168 
169 	return type;
170 }
171 
172 static void
173 setpartition(part, pp, fstype)
174 	struct part_map_entry *part;
175 	struct partition *pp;
176 	int fstype;
177 {
178 	pp->p_size = part->pmPartBlkCnt;
179 	pp->p_offset = part->pmPyPartStart;
180 	pp->p_fstype = fstype;
181 
182 	part->pmPartType[0] = '\0';
183 }
184 
185 static int
186 getNamedType(part, num_parts, lp, type, alt, maxslot)
187 	struct part_map_entry *part;
188 	int num_parts;
189 	struct disklabel *lp;
190 	int type, alt;
191 	int *maxslot;
192 {
193 	struct blockzeroblock *bzb;
194 	int i;
195 
196 	for (i = 0; i < num_parts; i++) {
197 		if (whichType(part + i) != type)
198 			continue;
199 
200 		if (type == ROOT_PART) {
201 			bzb = (struct blockzeroblock *)
202 			    (&(part + i)->pmBootArgs);
203 			if (alt >= 0 && alt != bzb->bzbCluster)
204 				continue;
205 			setpartition(part + i, &lp->d_partitions[0], FS_BSDFFS);
206 		} else if (type == UFS_PART) {
207 			bzb = (struct blockzeroblock *)
208 			    (&(part + i)->pmBootArgs);
209 			if (alt >= 0 && alt != bzb->bzbCluster)
210 				continue;
211 			setpartition(part + i, &lp->d_partitions[6], FS_BSDFFS);
212 			if (*maxslot < 6)
213 				*maxslot = 6;
214 		} else if (type == SWAP_PART) {
215 			setpartition(part + i, &lp->d_partitions[1], FS_SWAP);
216 			if (*maxslot < 1)
217 				*maxslot = 1;
218 		} else
219 			printf("disksubr.c: can't do type %d\n", type);
220 
221 		return 0;
222 	}
223 
224 	return -1;
225 }
226 
227 /*
228  * MF --
229  * here's what i'm gonna do:
230  * read in the entire diskpartition table, it may be bigger or smaller
231  * than NUM_PARTS but read that many entries.  Each entry has a magic
232  * number so we'll know if an entry is crap.
233  * next fill in the disklabel with info like this
234  * next fill in the root, usr, and swap parts.
235  * then look for anything else and fit it in.
236  *	A: root
237  *	B: Swap
238  *	C: Whole disk
239  *	G: Usr
240  *
241  *
242  * I'm not entirely sure what netbsd386 wants in c & d
243  * 386bsd wants other stuff, so i'll leave them alone
244  *
245  * AKB -- I added to Mike's original algorithm by searching for a bzbCluster
246  *	of zero for root, first.  This allows A/UX to live on cluster 1 and
247  *	NetBSD to live on cluster 0--regardless of the actual order on the
248  *	disk.  This whole algorithm should probably be changed in the future.
249  */
250 
251 /*
252  * This uses sector zero.  If this contains what looks like a valid
253  * Macintosh boot sector, we attempt to fill in the disklabel structure
254  * with the partition data from block #1 on.
255  */
256 static char *
257 read_mac_label(dlbuf, lp, match)
258 	char *dlbuf;
259 	struct disklabel *lp;
260 	int *match;
261 {
262 	u_int16_t *sbSigp;
263 	struct part_map_entry *part;
264 	struct partition *pp;
265 	char *msg;
266 	int i, slot, maxslot;
267 
268 	maxslot = 0;
269 	*match = 0;
270 	msg = NULL;
271 
272 	sbSigp = (u_int16_t *)dlbuf;
273 	if (*sbSigp != DRIVER_MAP_MAGIC)
274 		return msg;
275 
276 	/* Found Macintosh partition magic number; set up disklabel */
277 	*match = (-1);
278 
279 	/* the Macintosh partition table starts at sector #1 */
280 	part = (struct part_map_entry *)(dlbuf + DEV_BSIZE);
281 
282 	/* Fill in standard partitions */
283 	lp->d_npartitions = RAW_PART + 1;
284 	if (getNamedType(part, NUM_PARTS, lp, ROOT_PART, 0, &maxslot))
285 		getNamedType(part, NUM_PARTS, lp, ROOT_PART, -1, &maxslot);
286 	if (getNamedType(part, NUM_PARTS, lp, UFS_PART, 0, &maxslot))
287 		getNamedType(part, NUM_PARTS, lp, UFS_PART, -1, &maxslot);
288 	getNamedType(part, NUM_PARTS, lp, SWAP_PART, -1, &maxslot);
289 
290 	/* Now get as many of the rest of the partitions as we can */
291 	for (i = 0; i < NUM_PARTS; i++) {
292 		slot = getFreeLabelEntry(lp);
293 		if (slot < 0)
294 			break;
295 
296 		pp = &lp->d_partitions[slot];
297 
298 		switch (whichType(part + i)) {
299 		case ROOT_PART:
300 		/*
301 		 * another root part will turn into a plain old
302 		 * UFS_PART partition, live with it.
303 		 */
304 		case UFS_PART:
305 			setpartition(part + i, pp, FS_BSDFFS);
306 			break;
307 		case SWAP_PART:
308 			setpartition(part + i, pp, FS_SWAP);
309 			break;
310 		case HFS_PART:
311 			setpartition(part + i, pp, FS_HFS);
312 			break;
313 		case SCRATCH_PART:
314 			setpartition(part + i, pp, FS_OTHER);
315 			break;
316 		default:
317 			slot = 0;
318 			break;
319 		}
320 		if (slot > maxslot)
321 			maxslot = slot;
322 	}
323 	lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
324 	return msg;
325 }
326 
327 /*
328  * Scan the disk buffer for a DOS style master boot record.
329  * Return if no match; otherwise, set up an in-core disklabel .
330  *
331  * XXX stuff like this really should be MI
332  *
333  * Since FFS is endian sensitive, we pay no effort in attempting to
334  * dig up *BSD/i386 disk labels that may be present on the disk.
335  * Hence anything but DOS partitions is treated as unknown FS type, but
336  * this should suffice to mount_msdos Zip and other removable media.
337  */
338 static char *
339 read_mbr_label(dlbuf, lp, match)
340 	char *dlbuf;
341 	struct disklabel *lp;
342 	int *match;
343 {
344 	struct mbr_partition *dp;
345 	struct partition *pp;
346 	char *msg;
347 	size_t mbr_lbl_off;
348 	int i, *ip, slot, maxslot;
349 
350 	maxslot = 0;
351 	*match = 0;
352 	msg = NULL;
353 
354 	if (MBR_MAGIC != bswap16(*(u_int16_t *)(dlbuf + MBR_MAGICOFF)))
355 		return msg;
356 
357 	/* Found MBR magic number; set up disklabel */
358 	*match = (-1);
359 	mbr_lbl_off = MBR_BBSECTOR * lp->d_secsize + MBR_PARTOFF;
360 
361 	dp = (struct mbr_partition *)(dlbuf + mbr_lbl_off);
362 	for (i = 0; i < NMBRPART; i++, dp++) {
363 		if (dp->mbrp_typ == 0)
364 			continue;
365 
366 		slot = getFreeLabelEntry(lp);
367 		maxslot = (slot > maxslot) ? maxslot : slot;
368 
369 		pp = &lp->d_partitions[slot];
370 		pp->p_fstype = FS_OTHER;
371 		pp->p_offset = bswap32(dp->mbrp_start);
372 		pp->p_size = bswap32(dp->mbrp_size);
373 
374 		for (ip = fat_types; *ip != -1; ip++) {
375 			if (dp->mbrp_typ == *ip) {
376 				pp->p_fstype = FS_MSDOS;
377 				break;
378 			}
379 		}
380 	}
381 	lp->d_npartitions = ((maxslot >= RAW_PART) ? maxslot : RAW_PART) + 1;
382 	return msg;
383 }
384 
385 /*
386  * Scan the disk buffer in four byte steps for a native BSD disklabel
387  * (different ports have variable-sized bootcode before the label)
388  */
389 static char *
390 read_bsd_label(dlbuf, lp, match)
391 	char *dlbuf;
392 	struct disklabel *lp;
393 	int *match;
394 {
395 	struct disklabel *dlp;
396 	char *msg;
397 	struct disklabel *blk_start, *blk_end;
398 
399 	*match = 0;
400 	msg = NULL;
401 
402 	blk_start = (struct disklabel *)dlbuf;
403 	blk_end = (struct disklabel *)(dlbuf + (NUM_PARTS << DEV_BSHIFT) -
404 	    sizeof(struct disklabel));
405 
406 	for (dlp = blk_start; dlp <= blk_end;
407 	     dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
408 		if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC) {
409 			/* Sanity check */
410 			if (dlp->d_npartitions <= MAXPARTITIONS &&
411 			    dkcksum(dlp) == 0) {
412 				*lp = *dlp;
413 				*match = (-1);
414 			} else
415 				msg = "Disk label corrupted";
416 			break;
417 		}
418 	}
419 	return msg;
420 }
421 
422 /*
423  * Attempt to read a disk label from a device using the indicated strategy
424  * routine.  The label must be partly set up before this: secpercyl and
425  * anything required in the strategy routine (e.g., sector size) must be
426  * filled in before calling us.  Returns null on success and an error
427  * string on failure.
428  */
429 char *
430 readdisklabel(dev, strat, lp, osdep)
431 	dev_t dev;
432 	void (*strat)(struct buf *);
433 	struct disklabel *lp;
434 	struct cpu_disklabel *osdep;
435 {
436 	struct buf *bp;
437 	char *msg;
438 	int size;
439 
440 	if (lp->d_secperunit == 0)
441 		lp->d_secperunit = 0x1fffffff;
442 
443 	if (lp->d_secpercyl == 0)
444 		return msg = "Zero secpercyl";
445 
446 	msg = NULL;
447 
448 	/*
449 	 * Read in the first #(NUM_PARTS + 1) blocks of the disk.
450 	 * The native Macintosh partition table starts at
451 	 * sector #1, but we want #0 too for the BSD label.
452 	 */
453 
454 	size = roundup((NUM_PARTS + 1) << DEV_BSHIFT, lp->d_secsize);
455 	bp = geteblk(size);
456 
457 	bp->b_dev = dev;
458 	bp->b_blkno = 0;
459 	bp->b_resid = 0;
460 	bp->b_bcount = size;
461 	bp->b_flags |= B_READ;
462 	bp->b_cylinder = 1 / lp->d_secpercyl;
463 	(*strat)(bp);
464 
465 	if (biowait(bp)) {
466 		msg = "I/O error reading block zero";
467 	} else {
468 		int match;
469 
470 		/* Add any offsets in the table handlers */
471 		msg = read_mac_label(bp->b_data, lp, &match);
472 		if (!match && msg == NULL)
473 			msg = read_mbr_label(bp->b_data, lp, &match);
474 		if (!match && msg == NULL)
475 			msg = read_bsd_label(bp->b_data, lp, &match);
476 		if (!match && msg == NULL)
477 			msg = "no disk label";
478 	}
479 
480 	brelse(bp);
481 	return (msg);
482 }
483 
484 /*
485  * Check new disk label for sensibility before setting it.
486  */
487 int
488 setdisklabel(olp, nlp, openmask, osdep)
489 	struct disklabel *olp, *nlp;
490 	u_long openmask;
491 	struct cpu_disklabel *osdep;
492 {
493 #if 0
494 	int i;
495 	struct partition *opp, *npp;
496 
497 	/* sanity clause */
498 	if (nlp->d_secpercyl == 0 || nlp->d_secsize == 0 ||
499 	    (nlp->d_secsize % DEV_BSIZE) != 0)
500 		return(EINVAL);
501 
502 	/* special case to allow disklabel to be invalidated */
503 	if (nlp->d_magic == 0xffffffff) {
504 		*olp = *nlp;
505 		return (0);
506 	}
507 
508 	if (nlp->d_magic != DISKMAGIC || nlp->d_magic2 != DISKMAGIC ||
509 	    dkcksum(nlp) != 0)
510 		return (EINVAL);
511 
512 	/*
513 	 * XXX We are missing any sort of check if other partition types,
514 	 * e.g. Macintosh or (PC) BIOS, will be overwritten.
515 	 */
516 
517 	while ((i = ffs(openmask)) != 0) {
518 		i--;
519 		openmask &= ~(1 << i);
520 		if (nlp->d_npartitions <= i)
521 			return (EBUSY);
522 		opp = &olp->d_partitions[i];
523 		npp = &nlp->d_partitions[i];
524 		if (npp->p_offset != opp->p_offset || npp->p_size < opp->p_size)
525 			return (EBUSY);
526 		/*
527 		 * Copy internally-set partition information
528 		 * if new label doesn't include it.		XXX
529 		 */
530 		if (npp->p_fstype == FS_UNUSED && opp->p_fstype != FS_UNUSED) {
531 			npp->p_fstype = opp->p_fstype;
532 			npp->p_fsize = opp->p_fsize;
533 			npp->p_frag = opp->p_frag;
534 			npp->p_cpg = opp->p_cpg;
535 		}
536 	}
537 	nlp->d_checksum = 0;
538 	nlp->d_checksum = dkcksum(nlp);
539 	*olp = *nlp;
540 #endif
541 	return (0);
542 }
543 
544 /*
545  * Write disk label back to device after modification.
546  *
547  *  MF - 8-14-93 This function is never called.  It is here just in case
548  *  we want to write dos disklabels some day. Really!
549  */
550 int
551 writedisklabel(dev, strat, lp, osdep)
552 	dev_t dev;
553 	void (*strat)(struct buf *);
554 	struct disklabel *lp;
555 	struct cpu_disklabel *osdep;
556 {
557 #if 0
558 	struct buf *bp;
559 	struct disklabel *dlp;
560 	int labelpart;
561 	int error = 0;
562 
563 	labelpart = DISKPART(dev);
564 	if (lp->d_partitions[labelpart].p_offset != 0) {
565 		if (lp->d_partitions[0].p_offset != 0)
566 			return (EXDEV);	/* not quite right */
567 		labelpart = 0;
568 	}
569 	bp = geteblk((int)lp->d_secsize);
570 	bp->b_dev = MAKEDISKDEV(major(dev), DISKUNIT(dev), labelpart);
571 	bp->b_blkno = LABELSECTOR;
572 	bp->b_bcount = lp->d_secsize;
573 	bp->b_flags |= B_READ;
574 	(*strat)(bp);
575 	if (error = biowait(bp))
576 		goto done;
577 	for (dlp = (struct disklabel *)bp->b_data;
578 	    dlp <= (struct disklabel *)
579 	    (bp->b_data + lp->d_secsize - sizeof(*dlp));
580 	    dlp = (struct disklabel *)((char *)dlp + sizeof(long))) {
581 		if (dlp->d_magic == DISKMAGIC && dlp->d_magic2 == DISKMAGIC &&
582 		    dkcksum(dlp) == 0) {
583 			*dlp = *lp;
584 			bp->b_flags &= ~(B_READ|B_DONE);
585 			bp->b_flags |= B_WRITE;
586 			(*strat)(bp);
587 			error = biowait(bp);
588 			goto done;
589 		}
590 	}
591 	error = ESRCH;
592 done:
593 	brelse(bp);
594 	return (error);
595 #else
596 	int i;
597 
598 	/*
599 	 * Clear and re-analyze the ondisk Apple Disk Partition Map,
600 	 * then recompute the faked incore disk label. This is necessary
601 	 * for sysinst, which may have modified the disk layout. We don't
602 	 * (yet?) support writing real BSD disk labels, so this hack
603 	 * instead causes the DIOCWDINFO ioctl invoked by sysinst to
604 	 * update the in-core disk label when it is "written" to disk.
605 	 * This code was originally developed by Bob Nestor on 9/13/99.
606 	 */
607 	lp->d_npartitions = 0;
608 	for (i = 0; i < MAXPARTITIONS; i++) {
609 		lp->d_partitions[i].p_fstype = FS_UNUSED;
610 		lp->d_partitions[i].p_offset = 0;
611 		if (i != RAW_PART)
612 			lp->d_partitions[i].p_size = 0;
613 	}
614 	return (readdisklabel(dev, strat, lp, osdep) ? EINVAL : 0);
615 #endif
616 }
617 
618 /*
619  * Determine the size of the transfer, and make sure it is
620  * within the boundaries of the partition. Adjust transfer
621  * if needed, and signal errors or early completion.
622  */
623 int
624 bounds_check_with_label(bp, lp, wlabel)
625 	struct buf *bp;
626 	struct disklabel *lp;
627 	int wlabel;
628 {
629 	struct partition *p = lp->d_partitions + DISKPART(bp->b_dev);
630 #if 0
631 	int labelsector = lp->d_partitions[2].p_offset + LABELSECTOR;
632 #endif
633 	int sz;
634 
635 	sz = howmany(bp->b_bcount, lp->d_secsize);
636 
637 	if (bp->b_blkno + sz > p->p_size) {
638 		sz = p->p_size - bp->b_blkno;
639 		if (sz == 0) {
640 			/* If exactly at end of disk, return EOF. */
641 			bp->b_resid = bp->b_bcount;
642 			goto done;
643 		}
644 		if (sz < 0) {
645 			/* If past end of disk, return EINVAL. */
646 			bp->b_error = EINVAL;
647 			goto bad;
648 		}
649 		/* Otherwise, truncate request. */
650 		bp->b_bcount = sz << DEV_BSHIFT;
651 	}
652 
653 #if 0
654 	/* Overwriting disk label? */
655 	if (bp->b_blkno + p->p_offset <= labelsector &&
656 #if LABELSECTOR != 0
657 	    bp->b_blkno + p->p_offset + sz > labelsector &&
658 #endif
659 	    (bp->b_flags & B_READ) == 0 && !wlabel) {
660 		bp->b_error = EROFS;
661 		goto bad;
662 	}
663 #endif
664 
665 	/* calculate cylinder for disksort to order transfers with */
666 	bp->b_cylinder = (bp->b_blkno + p->p_offset) /
667 	    (lp->d_secsize / DEV_BSIZE) / lp->d_secpercyl;
668 	return (1);
669 
670 bad:
671 	bp->b_flags |= B_ERROR;
672 done:
673 	return (0);
674 }
675