svn commit: r217531 - head/sys/geom/part
Andrey V. Elsukov
ae at FreeBSD.org
Tue Jan 18 09:52:54 UTC 2011
Author: ae
Date: Tue Jan 18 09:52:53 2011
New Revision: 217531
URL: http://svn.freebsd.org/changeset/base/217531
Log:
Limit maximum number of GPT entries to 4k. It is most realistic value
and can prevent kernel memory exhausting when big value is specified
from command line.
Split reading and writing operation to several iteration to do not
trigger KASSERT when data length is greater than MAXPHYS.
PR: kern/144962, kern/147851
MFC after: 2 weeks
Modified:
head/sys/geom/part/g_part_gpt.c
Modified: head/sys/geom/part/g_part_gpt.c
==============================================================================
--- head/sys/geom/part/g_part_gpt.c Tue Jan 18 06:24:52 2011 (r217530)
+++ head/sys/geom/part/g_part_gpt.c Tue Jan 18 09:52:53 2011 (r217531)
@@ -134,7 +134,7 @@ static struct g_part_scheme g_part_gpt_s
sizeof(struct g_part_gpt_table),
.gps_entrysz = sizeof(struct g_part_gpt_entry),
.gps_minent = 128,
- .gps_maxent = INT_MAX,
+ .gps_maxent = 4096,
.gps_bootcodesz = MBRSIZE,
};
G_PART_SCHEME_DECLARE(g_part_gpt);
@@ -317,7 +317,7 @@ gpt_read_tbl(struct g_part_gpt_table *ta
struct g_provider *pp;
struct gpt_ent *ent, *tbl;
char *buf, *p;
- unsigned int idx, sectors, tblsz;
+ unsigned int idx, sectors, tblsz, size;
int error;
if (hdr == NULL)
@@ -329,11 +329,19 @@ gpt_read_tbl(struct g_part_gpt_table *ta
table->state[elt] = GPT_STATE_MISSING;
tblsz = hdr->hdr_entries * hdr->hdr_entsz;
sectors = (tblsz + pp->sectorsize - 1) / pp->sectorsize;
- buf = g_read_data(cp, table->lba[elt] * pp->sectorsize,
- sectors * pp->sectorsize, &error);
- if (buf == NULL)
- return (NULL);
-
+ buf = g_malloc(sectors * pp->sectorsize, M_WAITOK | M_ZERO);
+ for (idx = 0; idx < sectors; idx += MAXPHYS / pp->sectorsize) {
+ size = (sectors - idx > MAXPHYS / pp->sectorsize) ? MAXPHYS:
+ (sectors - idx) * pp->sectorsize;
+ p = g_read_data(cp, (table->lba[elt] + idx) * pp->sectorsize,
+ size, &error);
+ if (p == NULL) {
+ g_free(buf);
+ return (NULL);
+ }
+ bcopy(p, buf + idx * pp->sectorsize, size);
+ g_free(p);
+ }
table->state[elt] = GPT_STATE_CORRUPT;
if (crc32(buf, tblsz) != hdr->hdr_crc_table) {
g_free(buf);
@@ -986,10 +994,15 @@ g_part_gpt_write(struct g_part_table *ba
crc = crc32(buf, table->hdr->hdr_size);
le32enc(buf + 16, crc);
- error = g_write_data(cp, table->lba[GPT_ELT_PRITBL] * pp->sectorsize,
- buf + pp->sectorsize, tblsz * pp->sectorsize);
- if (error)
- goto out;
+ for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
+ error = g_write_data(cp,
+ (table->lba[GPT_ELT_PRITBL] + index) * pp->sectorsize,
+ buf + (index + 1) * pp->sectorsize,
+ (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
+ (tblsz - index) * pp->sectorsize);
+ if (error)
+ goto out;
+ }
error = g_write_data(cp, table->lba[GPT_ELT_PRIHDR] * pp->sectorsize,
buf, pp->sectorsize);
if (error)
@@ -1003,10 +1016,15 @@ g_part_gpt_write(struct g_part_table *ba
crc = crc32(buf, table->hdr->hdr_size);
le32enc(buf + 16, crc);
- error = g_write_data(cp, table->lba[GPT_ELT_SECTBL] * pp->sectorsize,
- buf + pp->sectorsize, tblsz * pp->sectorsize);
- if (error)
- goto out;
+ for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
+ error = g_write_data(cp,
+ (table->lba[GPT_ELT_SECTBL] + index) * pp->sectorsize,
+ buf + (index + 1) * pp->sectorsize,
+ (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
+ (tblsz - index) * pp->sectorsize);
+ if (error)
+ goto out;
+ }
error = g_write_data(cp, table->lba[GPT_ELT_SECHDR] * pp->sectorsize,
buf, pp->sectorsize);
More information about the svn-src-all
mailing list