1: /*-
2: * Public domain, May 1995
3: *
4: * @(#)label.c 1.2 (2.11BSD GTE) 1996/03/07
5: *
6: * Date: 1995/08/01
7: * Move the check for a partition number being out of bounds to the
8: * readlabel routine. This is necessary in order to permit unlabeled disks
9: * (or disks whose label is corrupt) to be open'd. This check can't be done
10: * in the open routine because a corrupt or missing label could have garbage
11: * for the number of partitions.
12: */
13:
14: #include "../h/param.h"
15: #include "saio.h"
16:
17: /*
18: * Called from the general device label routine in conf.c. A label with
19: * a fake geometry suitable for reading the label sector is created and
20: * the driver's strategy routine is called. If the label is corrupted
21: * or absent an error is possibly printed.
22: *
23: * NOTES: We reuse the iob structure's buffer (i_buf).
24: * All disks must have at least LABELSECTOR+1 sectors in a track.
25: * (this is not expected to be a problem since LABELSECTOR is 1).
26: */
27:
28: readlabel(io, strat)
29: register struct iob *io;
30: int (*strat)();
31: {
32: register struct disklabel *lp = &io->i_label;
33: register struct partition *pi;
34:
35: io->i_bn = LABELSECTOR;
36: io->i_ma = io->i_buf;
37: io->i_cc = 512; /* XXX */
38: lp->d_nsectors = LABELSECTOR + 1; /* # sectors per track */
39: lp->d_ntracks = 1; /* # tracks per cylinder */
40: lp->d_secpercyl = LABELSECTOR + 1; /* # sectors per cylinder */
41:
42: pi = &lp->d_partitions[0];
43: lp->d_npartitions = 1;
44: pi->p_offset = 0;
45: pi->p_size = LABELSECTOR + 1;
46: pi->p_fsize = DEV_BSIZE;
47: pi->p_frag = 1;
48: pi->p_fstype = FS_V71K;
49:
50: if ((*strat)(io, READ) != 512)
51: {
52: printf("%s error reading labelsector\n", devname(io));
53: return(-1);
54: }
55: bcopy(io->i_buf, lp, sizeof (struct disklabel));
56: if (Nolabelerr)
57: return(0);
58: if (lp->d_magic != DISKMAGIC || lp->d_magic2 != DISKMAGIC ||
59: dkcksum(lp) != 0)
60: {
61: printf("%s disklabel missing/corrupt\n", devname(io));
62: if (devlabel(io, DEFAULTLABEL) < 0)
63: return(-1);
64: printf("%s spans volume\n", devname(io));
65: }
66: if (io->i_part >= lp->d_npartitions ||
67: lp->d_partitions[io->i_part].p_size == 0)
68: {
69: printf("%s bad partition # or size = 0\n", devname(io));
70: return(-1);
71: }
72: return(0);
73: }
74:
75: writelabel(io, strat)
76: register struct iob *io;
77: int (*strat)();
78: {
79: register struct disklabel *lp = &io->i_label;
80:
81: if ((io->i_flgs & F_WRITE) == 0)
82: return(-1);
83: io->i_bn = LABELSECTOR;
84: io->i_ma = (char *)&io->i_label;
85: io->i_cc = 512; /* XXX */
86: /*
87: * The geometry had better be set up and correct at this point - we can not
88: * fake the geometry because that would overwrite the contents of the label
89: * itself.
90: */
91: lp->d_secsize = 512; /* XXX */
92: lp->d_magic = DISKMAGIC;
93: lp->d_magic2 = DISKMAGIC;
94: lp->d_checksum = 0;
95: lp->d_checksum = dkcksum(lp);
96:
97: if ((*strat)(io, WRITE) != 512)
98: {
99: printf("%s error writing label\n", devname(io));
100: return(-1);
101: }
102: return(0);
103: }
104:
105: /*
106: * Compute checksum for disk label.
107: */
108: dkcksum(lp)
109: register struct disklabel *lp;
110: {
111: register u_short *start, *end;
112: register u_short sum = 0;
113:
114: start = (u_short *)lp;
115: end = (u_short *)&lp->d_partitions[lp->d_npartitions];
116: while (start < end)
117: sum ^= *start++;
118: return (sum);
119: }
120:
121: /*
122: * Check for partitions which overlap each other. While it is legal
123: * to have partitions which overlap (as long as they are not used at the
124: * same time) it is often a mistake or oversite.
125: */
126:
127: overlapchk(lp)
128: register struct disklabel *lp;
129: {
130: register struct partition *pp;
131: int i, part, openmask;
132: daddr_t start, end;
133:
134: #define RAWPART 2
135: /*
136: * 'c' is normally (but not always) the partition which spans the whole
137: * drive, thus it is not normally an error for it to overlap all other
138: * partitions.
139: */
140: openmask = ~0 & ~(1 << RAWPART);
141: for (part = 0; part < lp->d_npartitions; part++)
142: {
143: pp = &lp->d_partitions[part];
144: if (part == RAWPART || pp->p_size == 0)
145: continue;
146: start = pp->p_offset;
147: end = start + pp->p_size;
148:
149: for (pp = lp->d_partitions, i = 0;
150: i < lp->d_npartitions;
151: pp++, i++)
152: {
153: /*
154: * We make sure to not report zero length partitions or that a
155: * partition overlaps itself. We've already checked lower partitions
156: * so avoid giving something like "a overlaps b" and then "b overlaps a".
157: */
158: if (i <= part || pp->p_size == 0)
159: continue;
160: if (pp->p_offset + pp->p_size <= start ||
161: pp->p_offset >= end)
162: continue;
163: if ((openmask & (1 << i)) == 0)
164: continue;
165: printf("warning: partition '%c' overlaps '%c'\n",
166: 'a' + part, 'a' + i);
167: }
168: }
169: }
Defined functions
Defined macros