From owner-svn-src-all@FreeBSD.ORG Tue Jan 18 09:52:53 2011 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D78FB1065694; Tue, 18 Jan 2011 09:52:53 +0000 (UTC) (envelope-from ae@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id C75AE8FC14; Tue, 18 Jan 2011 09:52:53 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id p0I9qrtk032936; Tue, 18 Jan 2011 09:52:53 GMT (envelope-from ae@svn.freebsd.org) Received: (from ae@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id p0I9qrVN032934; Tue, 18 Jan 2011 09:52:53 GMT (envelope-from ae@svn.freebsd.org) Message-Id: <201101180952.p0I9qrVN032934@svn.freebsd.org> From: "Andrey V. Elsukov" Date: Tue, 18 Jan 2011 09:52:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r217531 - head/sys/geom/part X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Jan 2011 09:52:54 -0000 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);