1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-29 08:08:37 +00:00

- When adjusting the end of a partition to lie on a cylinder boundary, don't

adjust the size, but the actual end.
- Break out some of the sanity checks on partitions into a sanitize_partition
  function.
- When adjusting partitions, always adjust the start "up", and the end "down"
  so that we stay within the boundaries of the original request.
- Various small nits found by bde.

Reported by:	bde, imp, rgrimes
This commit is contained in:
John Baldwin 2000-08-24 17:54:45 +00:00
parent da140a0594
commit b594e0fea2
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=65054
2 changed files with 188 additions and 92 deletions

View File

@ -210,6 +210,7 @@ static int decimal(char *str, int *num, int deflt);
static char *get_type(int type); static char *get_type(int type);
static int read_config(char *config_file); static int read_config(char *config_file);
static void reset_boot(void); static void reset_boot(void);
static int sanitize_partition(struct dos_partition *);
static void usage(void); static void usage(void);
#if 0 #if 0
static int hex(char *str, int *num, int deflt); static int hex(char *str, int *num, int deflt);
@ -340,8 +341,8 @@ main(int argc, char *argv[])
partp->dp_typ = DOSPTYP_386BSD; partp->dp_typ = DOSPTYP_386BSD;
partp->dp_flag = ACTIVE; partp->dp_flag = ACTIVE;
partp->dp_start = dos_sectors; partp->dp_start = dos_sectors;
partp->dp_size = ((disksecs - dos_sectors) / dos_cylsecs) * partp->dp_size = (disksecs / dos_cylsecs) * dos_cylsecs -
dos_cylsecs; dos_sectors;
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
@ -384,7 +385,7 @@ main(int argc, char *argv[])
} }
if (read_s0()) if (read_s0())
init_sector0(1); init_sector0(dos_sectors);
printf("Media sector size is %d\n", secsize); printf("Media sector size is %d\n", secsize);
printf("Warning: BIOS sector numbering starts with sector 1\n"); printf("Warning: BIOS sector numbering starts with sector 1\n");
@ -512,19 +513,16 @@ static void
init_sector0(unsigned long start) init_sector0(unsigned long start)
{ {
struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]);
unsigned long size;
init_boot(); init_boot();
partp->dp_typ = DOSPTYP_386BSD; partp->dp_typ = DOSPTYP_386BSD;
partp->dp_flag = ACTIVE; partp->dp_flag = ACTIVE;
/* ensure cylinder boundaries */ start = ((start + dos_sectors - 1) / dos_sectors) * dos_sectors;
start = (start / dos_sectors) * dos_sectors;
if(start == 0) if(start == 0)
start = dos_sectors; start = dos_sectors;
size = ((disksecs - start) / dos_cylsecs) * dos_cylsecs;
partp->dp_start = start; partp->dp_start = start;
partp->dp_size = size; partp->dp_size = (disksecs / dos_cylsecs) * dos_cylsecs - start;
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
@ -580,20 +578,8 @@ struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1;
partp->dp_esect = DOSSECT(tsec,tcyl); partp->dp_esect = DOSSECT(tsec,tcyl);
partp->dp_ehd = thd; partp->dp_ehd = thd;
} else { } else {
if(partp->dp_start % dos_sectors != 0) { if (!sanitize_partition(partp))
printf("Adjusting partition to start at a " partp->dp_typ = 0;
"cylinder boundary\n");
partp->dp_start =
(partp->dp_start / dos_sectors) *
dos_sectors;
}
if(partp->dp_size % dos_cylsecs != 0) {
printf("Adjusting partition to end at a "
"cylinder boundary\n");
partp->dp_size =
(partp->dp_size / dos_cylsecs) *
dos_cylsecs;
}
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, dos(partp->dp_start + partp->dp_size - 1, partp->dp_size,
@ -1155,7 +1141,8 @@ process_partition(command)
CMD *command; CMD *command;
{ {
int status = 0, partition; int status = 0, partition;
unsigned long chunks, adj_size, max_end; u_int32_t prev_head_boundary, prev_cyl_boundary;
u_int32_t adj_size, max_end;
struct dos_partition *partp; struct dos_partition *partp;
while (1) while (1)
@ -1199,51 +1186,53 @@ process_partition(command)
*/ */
if (partp->dp_start % dos_sectors != 0) if (partp->dp_start % dos_sectors != 0)
{ {
adj_size = prev_head_boundary = partp->dp_start / dos_sectors * dos_sectors;
(partp->dp_start / dos_sectors + 1) * dos_sectors; if (max_end < dos_sectors ||
if (adj_size > max_end) prev_head_boundary > max_end - dos_sectors)
{ {
/* /*
* Can't go past end of partition * Can't go past end of partition
*/ */
warnx( warnx(
"ERROR line %d: unable to adjust start of partition %d to fall on\n\ "ERROR line %d: unable to adjust start of partition %d to fall on\n\
a cylinder boundary", a head boundary",
current_line_number, partition); current_line_number, partition);
break; break;
} }
warnx( warnx(
"WARNING: adjusting start offset of partition '%d' from %lu\n\ "WARNING: adjusting start offset of partition %d\n\
to %lu, to round to an head boundary", from %u to %u, to fall on a head boundary",
partition, (u_long)partp->dp_start, adj_size); partition, (u_int)partp->dp_start,
partp->dp_start = adj_size; (u_int)(prev_head_boundary + dos_sectors));
partp->dp_start = prev_head_boundary + dos_sectors;
} }
/* /*
* Adjust size downwards, if necessary, to fall on a cylinder * Adjust size downwards, if necessary, to fall on a cylinder
* boundary. * boundary.
*/ */
chunks = prev_cyl_boundary =
((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs;
adj_size = chunks - partp->dp_start; if (prev_cyl_boundary > partp->dp_start)
adj_size = prev_cyl_boundary - partp->dp_start;
else
{
warnx(
"ERROR: could not adjust partition to start on a head boundary\n\
and end on a cylinder boundary.");
return (0);
}
if (adj_size != partp->dp_size) if (adj_size != partp->dp_size)
{ {
warnx( warnx(
"WARNING: adjusting size of partition '%d' from %lu to %lu,\n\ "WARNING: adjusting size of partition %d from %u to %u\n\
to round to a cylinder boundary", to end on a cylinder boundary",
partition, (u_long)partp->dp_size, adj_size); partition, (u_int)partp->dp_size, (u_int)adj_size);
if (chunks > 0) partp->dp_size = adj_size;
{
partp->dp_size = adj_size;
}
else
{
partp->dp_size = 0;
}
} }
if (partp->dp_size < 1) if (partp->dp_size == 0)
{ {
warnx("ERROR line %d: size for partition '%d' is zero", warnx("ERROR line %d: size for partition %d is zero",
current_line_number, partition); current_line_number, partition);
break; break;
} }
@ -1403,3 +1392,62 @@ reset_boot(void)
bzero((char *)partp, sizeof (struct dos_partition)); bzero((char *)partp, sizeof (struct dos_partition));
} }
} }
static int
sanitize_partition(partp)
struct dos_partition *partp;
{
u_int32_t prev_head_boundary, prev_cyl_boundary;
u_int32_t adj_size, max_end;
max_end = partp->dp_start + partp->dp_size;
/*
* Adjust start upwards, if necessary, to fall on an head boundary.
*/
if (partp->dp_start % dos_sectors != 0) {
prev_head_boundary = partp->dp_start / dos_sectors * dos_sectors;
if (max_end < dos_sectors ||
prev_head_boundary > max_end - dos_sectors) {
/*
* Can't go past end of partition
*/
warnx(
"ERROR: unable to adjust start of partition to fall on a head boundary");
return (0);
}
warnx(
"WARNING: adjusting start offset of partition\n\
to %u to fall on a head boundary",
(u_int)(prev_head_boundary + dos_sectors));
partp->dp_start = prev_head_boundary + dos_sectors;
}
/*
* Adjust size downwards, if necessary, to fall on a cylinder
* boundary.
*/
prev_cyl_boundary = ((partp->dp_start + partp->dp_size) / dos_cylsecs) *
dos_cylsecs;
if (prev_cyl_boundary > partp->dp_start)
adj_size = prev_cyl_boundary - partp->dp_start;
else
{
warnx("ERROR: could not adjust partition to start on a head boundary\n\
and end on a cylinder boundary.");
return (0);
}
if (adj_size != partp->dp_size) {
warnx(
"WARNING: adjusting size of partition to %u to end on a\n\
cylinder boundary",
(u_int)adj_size);
partp->dp_size = adj_size;
}
if (partp->dp_size == 0) {
warnx("ERROR: size for partition is zero");
return (0);
}
return (1);
}

View File

@ -210,6 +210,7 @@ static int decimal(char *str, int *num, int deflt);
static char *get_type(int type); static char *get_type(int type);
static int read_config(char *config_file); static int read_config(char *config_file);
static void reset_boot(void); static void reset_boot(void);
static int sanitize_partition(struct dos_partition *);
static void usage(void); static void usage(void);
#if 0 #if 0
static int hex(char *str, int *num, int deflt); static int hex(char *str, int *num, int deflt);
@ -340,8 +341,8 @@ main(int argc, char *argv[])
partp->dp_typ = DOSPTYP_386BSD; partp->dp_typ = DOSPTYP_386BSD;
partp->dp_flag = ACTIVE; partp->dp_flag = ACTIVE;
partp->dp_start = dos_sectors; partp->dp_start = dos_sectors;
partp->dp_size = ((disksecs - dos_sectors) / dos_cylsecs) * partp->dp_size = (disksecs / dos_cylsecs) * dos_cylsecs -
dos_cylsecs; dos_sectors;
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
@ -384,7 +385,7 @@ main(int argc, char *argv[])
} }
if (read_s0()) if (read_s0())
init_sector0(1); init_sector0(dos_sectors);
printf("Media sector size is %d\n", secsize); printf("Media sector size is %d\n", secsize);
printf("Warning: BIOS sector numbering starts with sector 1\n"); printf("Warning: BIOS sector numbering starts with sector 1\n");
@ -512,19 +513,16 @@ static void
init_sector0(unsigned long start) init_sector0(unsigned long start)
{ {
struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]); struct dos_partition *partp = (struct dos_partition *) (&mboot.parts[3]);
unsigned long size;
init_boot(); init_boot();
partp->dp_typ = DOSPTYP_386BSD; partp->dp_typ = DOSPTYP_386BSD;
partp->dp_flag = ACTIVE; partp->dp_flag = ACTIVE;
/* ensure cylinder boundaries */ start = ((start + dos_sectors - 1) / dos_sectors) * dos_sectors;
start = (start / dos_sectors) * dos_sectors;
if(start == 0) if(start == 0)
start = dos_sectors; start = dos_sectors;
size = ((disksecs - start) / dos_cylsecs) * dos_cylsecs;
partp->dp_start = start; partp->dp_start = start;
partp->dp_size = size; partp->dp_size = (disksecs / dos_cylsecs) * dos_cylsecs - start;
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
@ -580,20 +578,8 @@ struct dos_partition *partp = ((struct dos_partition *) &mboot.parts) + i - 1;
partp->dp_esect = DOSSECT(tsec,tcyl); partp->dp_esect = DOSSECT(tsec,tcyl);
partp->dp_ehd = thd; partp->dp_ehd = thd;
} else { } else {
if(partp->dp_start % dos_sectors != 0) { if (!sanitize_partition(partp))
printf("Adjusting partition to start at a " partp->dp_typ = 0;
"cylinder boundary\n");
partp->dp_start =
(partp->dp_start / dos_sectors) *
dos_sectors;
}
if(partp->dp_size % dos_cylsecs != 0) {
printf("Adjusting partition to end at a "
"cylinder boundary\n");
partp->dp_size =
(partp->dp_size / dos_cylsecs) *
dos_cylsecs;
}
dos(partp->dp_start, partp->dp_size, dos(partp->dp_start, partp->dp_size,
&partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd); &partp->dp_scyl, &partp->dp_ssect, &partp->dp_shd);
dos(partp->dp_start + partp->dp_size - 1, partp->dp_size, dos(partp->dp_start + partp->dp_size - 1, partp->dp_size,
@ -1155,7 +1141,8 @@ process_partition(command)
CMD *command; CMD *command;
{ {
int status = 0, partition; int status = 0, partition;
unsigned long chunks, adj_size, max_end; u_int32_t prev_head_boundary, prev_cyl_boundary;
u_int32_t adj_size, max_end;
struct dos_partition *partp; struct dos_partition *partp;
while (1) while (1)
@ -1199,51 +1186,53 @@ process_partition(command)
*/ */
if (partp->dp_start % dos_sectors != 0) if (partp->dp_start % dos_sectors != 0)
{ {
adj_size = prev_head_boundary = partp->dp_start / dos_sectors * dos_sectors;
(partp->dp_start / dos_sectors + 1) * dos_sectors; if (max_end < dos_sectors ||
if (adj_size > max_end) prev_head_boundary > max_end - dos_sectors)
{ {
/* /*
* Can't go past end of partition * Can't go past end of partition
*/ */
warnx( warnx(
"ERROR line %d: unable to adjust start of partition %d to fall on\n\ "ERROR line %d: unable to adjust start of partition %d to fall on\n\
a cylinder boundary", a head boundary",
current_line_number, partition); current_line_number, partition);
break; break;
} }
warnx( warnx(
"WARNING: adjusting start offset of partition '%d' from %lu\n\ "WARNING: adjusting start offset of partition %d\n\
to %lu, to round to an head boundary", from %u to %u, to fall on a head boundary",
partition, (u_long)partp->dp_start, adj_size); partition, (u_int)partp->dp_start,
partp->dp_start = adj_size; (u_int)(prev_head_boundary + dos_sectors));
partp->dp_start = prev_head_boundary + dos_sectors;
} }
/* /*
* Adjust size downwards, if necessary, to fall on a cylinder * Adjust size downwards, if necessary, to fall on a cylinder
* boundary. * boundary.
*/ */
chunks = prev_cyl_boundary =
((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs; ((partp->dp_start + partp->dp_size) / dos_cylsecs) * dos_cylsecs;
adj_size = chunks - partp->dp_start; if (prev_cyl_boundary > partp->dp_start)
adj_size = prev_cyl_boundary - partp->dp_start;
else
{
warnx(
"ERROR: could not adjust partition to start on a head boundary\n\
and end on a cylinder boundary.");
return (0);
}
if (adj_size != partp->dp_size) if (adj_size != partp->dp_size)
{ {
warnx( warnx(
"WARNING: adjusting size of partition '%d' from %lu to %lu,\n\ "WARNING: adjusting size of partition %d from %u to %u\n\
to round to a cylinder boundary", to end on a cylinder boundary",
partition, (u_long)partp->dp_size, adj_size); partition, (u_int)partp->dp_size, (u_int)adj_size);
if (chunks > 0) partp->dp_size = adj_size;
{
partp->dp_size = adj_size;
}
else
{
partp->dp_size = 0;
}
} }
if (partp->dp_size < 1) if (partp->dp_size == 0)
{ {
warnx("ERROR line %d: size for partition '%d' is zero", warnx("ERROR line %d: size for partition %d is zero",
current_line_number, partition); current_line_number, partition);
break; break;
} }
@ -1403,3 +1392,62 @@ reset_boot(void)
bzero((char *)partp, sizeof (struct dos_partition)); bzero((char *)partp, sizeof (struct dos_partition));
} }
} }
static int
sanitize_partition(partp)
struct dos_partition *partp;
{
u_int32_t prev_head_boundary, prev_cyl_boundary;
u_int32_t adj_size, max_end;
max_end = partp->dp_start + partp->dp_size;
/*
* Adjust start upwards, if necessary, to fall on an head boundary.
*/
if (partp->dp_start % dos_sectors != 0) {
prev_head_boundary = partp->dp_start / dos_sectors * dos_sectors;
if (max_end < dos_sectors ||
prev_head_boundary > max_end - dos_sectors) {
/*
* Can't go past end of partition
*/
warnx(
"ERROR: unable to adjust start of partition to fall on a head boundary");
return (0);
}
warnx(
"WARNING: adjusting start offset of partition\n\
to %u to fall on a head boundary",
(u_int)(prev_head_boundary + dos_sectors));
partp->dp_start = prev_head_boundary + dos_sectors;
}
/*
* Adjust size downwards, if necessary, to fall on a cylinder
* boundary.
*/
prev_cyl_boundary = ((partp->dp_start + partp->dp_size) / dos_cylsecs) *
dos_cylsecs;
if (prev_cyl_boundary > partp->dp_start)
adj_size = prev_cyl_boundary - partp->dp_start;
else
{
warnx("ERROR: could not adjust partition to start on a head boundary\n\
and end on a cylinder boundary.");
return (0);
}
if (adj_size != partp->dp_size) {
warnx(
"WARNING: adjusting size of partition to %u to end on a\n\
cylinder boundary",
(u_int)adj_size);
partp->dp_size = adj_size;
}
if (partp->dp_size == 0) {
warnx("ERROR: size for partition is zero");
return (0);
}
return (1);
}