svn commit: r218162 - stable/8/sys/geom/part
Andrey V. Elsukov
ae at FreeBSD.org
Tue Feb 1 09:27:30 UTC 2011
Author: ae
Date: Tue Feb 1 09:27:28 2011
New Revision: 218162
URL: http://svn.freebsd.org/changeset/base/218162
Log:
MFC r217531:
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 iterations to do not
trigger KASSERT when data length is greater than MAXPHYS.
PR: kern/144962, kern/147851
Modified:
stable/8/sys/geom/part/g_part_gpt.c
Directory Properties:
stable/8/sys/ (props changed)
stable/8/sys/amd64/include/xen/ (props changed)
stable/8/sys/cddl/contrib/opensolaris/ (props changed)
stable/8/sys/contrib/dev/acpica/ (props changed)
stable/8/sys/contrib/pf/ (props changed)
Modified: stable/8/sys/geom/part/g_part_gpt.c
==============================================================================
--- stable/8/sys/geom/part/g_part_gpt.c Tue Feb 1 09:27:24 2011 (r218161)
+++ stable/8/sys/geom/part/g_part_gpt.c Tue Feb 1 09:27:28 2011 (r218162)
@@ -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-stable-8
mailing list