2 * ----------------------------------------------------------------------------
3 * "THE BEER-WARE LICENSE" (Revision 42):
4 * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
5 * can do whatever you want with this stuff. If we meet some day, and you think
6 * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
7 * ----------------------------------------------------------------------------
10 #include <sys/cdefs.h>
11 __FBSDID("$FreeBSD$");
13 #include <sys/types.h>
14 #include <sys/stdint.h>
15 #include <sys/disklabel.h>
17 #include <sys/diskpc98.h>
19 #include <sys/diskmbr.h>
28 Track_Aligned(const struct disk *d, daddr_t offset)
33 if (offset % d->bios_sect)
40 Prev_Track_Aligned(const struct disk *d, daddr_t offset)
45 return (offset / d->bios_sect) * d->bios_sect;
52 Next_Track_Aligned(const struct disk *d, daddr_t offset)
57 return Prev_Track_Aligned(d, offset + d->bios_sect-1);
64 Cyl_Aligned(const struct disk *d, daddr_t offset)
67 if (!d->bios_sect || !d->bios_hd)
69 if (offset % (d->bios_sect * d->bios_hd))
76 Prev_Cyl_Aligned(const struct disk *d, daddr_t offset)
79 if (!d->bios_sect || !d->bios_hd)
81 return (offset / (d->bios_sect * d->bios_hd)) * d->bios_sect *
89 Next_Cyl_Aligned(const struct disk *d, daddr_t offset)
92 if (!d->bios_sect || !d->bios_hd)
94 return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd) - 1);
102 * Chunks of type 'whole' can have max NDOSPART children.
103 * Only one of them can have the "active" flag
106 Rule_000(__unused const struct disk *d, const struct chunk *c, char *msg)
115 if (c->type != whole)
117 for (c1 = c->part; c1; c1 = c1->next) {
118 if (c1->type != unused)
121 if (c1->flags & CHUNK_ACTIVE)
127 sprintf(msg + strlen(msg),
128 "%d is too many children of the 'whole' chunk."
129 " Max is %d\n", i, NDOSPART);
132 sprintf(msg + strlen(msg),
133 "Too many active children of 'whole'");
139 * All children of 'whole' and 'extended' must be track-aligned.
140 * Exception: the end can be unaligned if it matches the end of 'whole'
143 Rule_001(const struct disk *d, const struct chunk *c, char *msg)
147 if (c->type != whole && c->type != extended)
149 for (c1 = c->part; c1; c1 = c1->next) {
150 if (c1->type == unused)
152 c1->flags |= CHUNK_ALIGN;
154 if (!Cyl_Aligned(d, c1->offset))
156 if (!Track_Aligned(d, c1->offset))
158 sprintf(msg + strlen(msg),
160 "chunk '%s' [%jd..%jd] does not start"
161 " on a cylinder boundary\n",
163 "chunk '%s' [%jd..%jd] does not start"
164 " on a track boundary\n",
166 c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
167 if ((c->type == whole || c->end == c1->end)
168 || Cyl_Aligned(d, c1->end + 1))
171 sprintf(msg + strlen(msg),
172 "chunk '%s' [%jd..%jd] does not end"
173 " on a cylinder boundary\n",
174 c1->name, (intmax_t)c1->offset, (intmax_t)c1->end);
180 * Max one 'fat' as child of 'whole'
183 Rule_002(__unused const struct disk *d, const struct chunk *c, char *msg)
188 if (c->type != whole)
190 for (i = 0, c1 = c->part; c1; c1 = c1->next) {
196 sprintf(msg + strlen(msg),
197 "Max one 'fat' allowed as child of 'whole'\n");
203 * Max one extended as child of 'whole'
206 Rule_003(__unused const struct disk *d, const struct chunk *c, char *msg)
211 if (c->type != whole)
213 for (i = 0, c1 = c->part; c1; c1 = c1->next) {
214 if (c1->type != extended)
219 sprintf(msg + strlen(msg),
220 "Max one 'extended' allowed as child of 'whole'\n");
226 * Max seven 'part' as children of 'freebsd'
227 * Max one CHUNK_IS_ROOT child per 'freebsd'
230 Rule_004(__unused const struct disk *d, const struct chunk *c, char *msg)
235 if (c->type != freebsd)
238 for (c1 = c->part; c1; c1 = c1->next) {
239 if (c1->type != part)
241 if (c1->flags & CHUNK_IS_ROOT)
246 sprintf(msg + strlen(msg),
247 "Max seven partitions per freebsd slice\n");
250 sprintf(msg + strlen(msg),
251 "Max one root partition child per freebsd slice\n");
256 Check_Chunk(const struct disk *d, const struct chunk *c, char *msg)
268 Check_Chunk(d, c->part, msg);
270 Check_Chunk(d, c->next, msg);
277 Check_Chunk(d, c->part, msg);
279 Check_Chunk(d, c->next, msg);
287 CheckRules(const struct disk *d)
292 Check_Chunk(d, d->chunks, msg);