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$");
17 #include <sys/types.h>
18 #include <sys/diskslice.h>
19 #include <sys/disklabel.h>
21 #include <sys/diskpc98.h>
23 #include <sys/diskmbr.h>
28 Track_Aligned(const struct disk *d, u_long offset)
33 if (offset % d->bios_sect)
39 Prev_Track_Aligned(const struct disk *d, u_long offset)
44 return (offset / d->bios_sect) * d->bios_sect;
48 Next_Track_Aligned(const struct disk *d, u_long offset)
53 return Prev_Track_Aligned(d, offset + d->bios_sect-1);
57 Cyl_Aligned(const struct disk *d, u_long offset)
60 if (!d->bios_sect || !d->bios_hd)
62 if (offset % (d->bios_sect * d->bios_hd))
68 Prev_Cyl_Aligned(const struct disk *d, u_long offset)
71 if (!d->bios_sect || !d->bios_hd)
73 return (offset / (d->bios_sect*d->bios_hd)) * d->bios_sect * d->bios_hd;
77 Next_Cyl_Aligned(const struct disk *d, u_long offset)
80 if (!d->bios_sect || !d->bios_hd)
82 return Prev_Cyl_Aligned(d,offset + (d->bios_sect * d->bios_hd) - 1);
87 * Chunks of type 'whole' can have max NDOSPART children.
88 * Only one of them can have the "active" flag
91 Rule_000(const struct disk *d, const struct chunk *c, char *msg)
100 if (c->type != whole)
102 for (c1 = c->part; c1; c1 = c1->next) {
103 if (c1->type != unused)
106 if (c1->flags & CHUNK_ACTIVE)
112 sprintf(msg + strlen(msg),
113 "%d is too many children of the 'whole' chunk."
114 " Max is %d\n", i, NDOSPART);
117 sprintf(msg + strlen(msg),
118 "Too many active children of 'whole'");
124 * All children of 'whole' and 'extended' must be track-aligned.
125 * Exception: the end can be unaligned if it matches the end of 'whole'
128 Rule_001(const struct disk *d, const struct chunk *c, char *msg)
132 if (c->type != whole && c->type != extended)
134 for (c1 = c->part; c1; c1 = c1->next) {
135 if (c1->type == unused)
137 c1->flags |= CHUNK_ALIGN;
139 if (!Cyl_Aligned(d, c1->offset))
141 if (!Track_Aligned(d, c1->offset))
143 sprintf(msg + strlen(msg),
145 "chunk '%s' [%ld..%ld] does not start"
146 " on a cylinder boundary\n",
148 "chunk '%s' [%ld..%ld] does not start"
149 " on a track boundary\n",
151 c1->name, c1->offset, c1->end);
152 if ((c->type == whole || c->end == c1->end)
153 || Cyl_Aligned(d, c1->end + 1))
156 sprintf(msg + strlen(msg),
157 "chunk '%s' [%ld..%ld] does not end"
158 " on a cylinder boundary\n",
159 c1->name, c1->offset, c1->end);
165 * Max one 'fat' as child of 'whole'
168 Rule_002(const struct disk *d, const struct chunk *c, char *msg)
173 if (c->type != whole)
175 for (i = 0, c1 = c->part; c1; c1 = c1->next) {
181 sprintf(msg + strlen(msg),
182 "Max one 'fat' allowed as child of 'whole'\n");
188 * Max one extended as child of 'whole'
191 Rule_003(const struct disk *d, const struct chunk *c, char *msg)
196 if (c->type != whole)
198 for (i = 0, c1 = c->part; c1; c1 = c1->next) {
199 if (c1->type != extended)
204 sprintf(msg + strlen(msg),
205 "Max one 'extended' allowed as child of 'whole'\n");
211 * Max seven 'part' as children of 'freebsd'
212 * Max one CHUNK_IS_ROOT child per 'freebsd'
215 Rule_004(const struct disk *d, const struct chunk *c, char *msg)
220 if (c->type != freebsd)
223 for (c1 = c->part; c1; c1 = c1->next) {
224 if (c1->type != part)
226 if (c1->flags & CHUNK_IS_ROOT)
231 sprintf(msg + strlen(msg),
232 "Max seven partitions per freebsd slice\n");
235 sprintf(msg + strlen(msg),
236 "Max one root partition child per freebsd slice\n");
241 Check_Chunk(const struct disk *d, const struct chunk *c, char *msg)
252 Check_Chunk(d, c->part, msg);
254 Check_Chunk(d, c->next, msg);
261 Check_Chunk(d, c->part, msg);
263 Check_Chunk(d, c->next, msg);
269 CheckRules(const struct disk *d)
274 Check_Chunk(d, d->chunks, msg);