Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 18 Jan 2011 09:52:53 +0000 (UTC)
From:      "Andrey V. Elsukov" <ae@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r217531 - head/sys/geom/part
Message-ID:  <201101180952.p0I9qrVN032934@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
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);
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201101180952.p0I9qrVN032934>