svn commit: r228076 - head/sys/geom/part

Andrey V. Elsukov ae at FreeBSD.org
Mon Nov 28 16:07:26 UTC 2011


Author: ae
Date: Mon Nov 28 16:07:26 2011
New Revision: 228076
URL: http://svn.freebsd.org/changeset/base/228076

Log:
  Add an ability to increase number of allocated APM entries when we
  have reserved free space in the APM area.
  Also instead of one write request per each APM entry, use MAXPHY
  sized writes when we are updating APM.
  
  MFC after:	1 month

Modified:
  head/sys/geom/part/g_part_apm.c

Modified: head/sys/geom/part/g_part_apm.c
==============================================================================
--- head/sys/geom/part/g_part_apm.c	Mon Nov 28 15:56:55 2011	(r228075)
+++ head/sys/geom/part/g_part_apm.c	Mon Nov 28 16:07:26 2011	(r228076)
@@ -234,6 +234,12 @@ g_part_apm_add(struct g_part_table *base
 		strncpy(entry->ent.ent_name, gpp->gpp_label,
 		    sizeof(entry->ent.ent_name));
 	}
+	if (baseentry->gpe_index >= table->self.ent_pmblkcnt)
+		table->self.ent_pmblkcnt = baseentry->gpe_index + 1;
+	KASSERT(table->self.ent_size >= table->self.ent_pmblkcnt,
+	    ("%s", __func__));
+	KASSERT(table->self.ent_size > baseentry->gpe_index,
+	    ("%s", __func__));
 	return (0);
 }
 
@@ -445,7 +451,7 @@ g_part_apm_read(struct g_part_table *bas
 
 	basetable->gpt_first = table->self.ent_size + 1;
 	basetable->gpt_last = table->ddr.ddr_blkcount - 1;
-	basetable->gpt_entries = table->self.ent_pmblkcnt - 1;
+	basetable->gpt_entries = table->self.ent_size - 1;
 
 	for (index = table->self.ent_pmblkcnt - 1; index > 0; index--) {
 		error = apm_read_ent(cp, index + 1, &ent, table->tivo_series1);
@@ -497,67 +503,78 @@ g_part_apm_type(struct g_part_table *bas
 static int
 g_part_apm_write(struct g_part_table *basetable, struct g_consumer *cp)
 {
-	char buf[512];
+	struct g_provider *pp;
 	struct g_part_entry *baseentry;
 	struct g_part_apm_entry *entry;
 	struct g_part_apm_table *table;
-	int error, index;
+	char *buf, *ptr;
+	uint32_t index;
+	int error;
+	size_t tblsz;
 
+	pp = cp->provider;
 	table = (struct g_part_apm_table *)basetable;
 	/*
 	 * Tivo Series 1 disk partitions are currently read-only.
 	 */
 	if (table->tivo_series1)
 		return (EOPNOTSUPP);
-	bzero(buf, sizeof(buf));
 
-	/* Write the DDR and 'self' entry only when we're newly created. */
+	/* Write the DDR only when we're newly created. */
 	if (basetable->gpt_created) {
+		buf = g_malloc(pp->sectorsize, M_WAITOK | M_ZERO);
 		be16enc(buf, table->ddr.ddr_sig);
 		be16enc(buf + 2, table->ddr.ddr_blksize);
 		be32enc(buf + 4, table->ddr.ddr_blkcount);
-		error = g_write_data(cp, 0, buf, sizeof(buf));
+		error = g_write_data(cp, 0, buf, pp->sectorsize);
+		g_free(buf);
 		if (error)
 			return (error);
 	}
 
-	be16enc(buf, table->self.ent_sig);
-	be16enc(buf + 2, 0);
-	be32enc(buf + 4, table->self.ent_pmblkcnt);
+	/* Allocate the buffer for all entries */
+	tblsz = table->self.ent_pmblkcnt;
+	buf = g_malloc(tblsz * pp->sectorsize, M_WAITOK | M_ZERO);
 
-	if (basetable->gpt_created) {
-		be32enc(buf + 8, table->self.ent_start);
-		be32enc(buf + 12, table->self.ent_size);
-		bcopy(table->self.ent_name, buf + 16,
-		    sizeof(table->self.ent_name));
-		bcopy(table->self.ent_type, buf + 48,
-		    sizeof(table->self.ent_type));
-		error = g_write_data(cp, 512, buf, sizeof(buf));
-		if (error)
-			return (error);
-	}
+	/* Fill the self entry */
+	be16enc(buf, APM_ENT_SIG);
+	be32enc(buf + 4, table->self.ent_pmblkcnt);
+	be32enc(buf + 8, table->self.ent_start);
+	be32enc(buf + 12, table->self.ent_size);
+	bcopy(table->self.ent_name, buf + 16, sizeof(table->self.ent_name));
+	bcopy(table->self.ent_type, buf + 48, sizeof(table->self.ent_type));
 
 	baseentry = LIST_FIRST(&basetable->gpt_entry);
-	for (index = 1; index <= basetable->gpt_entries; index++) {
+	for (index = 1; index < tblsz; index++) {
 		entry = (baseentry != NULL && index == baseentry->gpe_index)
 		    ? (struct g_part_apm_entry *)baseentry : NULL;
+		ptr = buf + index * pp->sectorsize;
+		be16enc(ptr, APM_ENT_SIG);
+		be32enc(ptr + 4, table->self.ent_pmblkcnt);
 		if (entry != NULL && !baseentry->gpe_deleted) {
-			be32enc(buf + 8, entry->ent.ent_start);
-			be32enc(buf + 12, entry->ent.ent_size);
-			bcopy(entry->ent.ent_name, buf + 16,
+			be32enc(ptr + 8, entry->ent.ent_start);
+			be32enc(ptr + 12, entry->ent.ent_size);
+			bcopy(entry->ent.ent_name, ptr + 16,
 			    sizeof(entry->ent.ent_name));
-			bcopy(entry->ent.ent_type, buf + 48,
+			bcopy(entry->ent.ent_type, ptr + 48,
 			    sizeof(entry->ent.ent_type));
 		} else {
-			bzero(buf + 8, 4 + 4 + 32 + 32);
-			strcpy(buf + 48, APM_ENT_TYPE_UNUSED);
+			strcpy(ptr + 48, APM_ENT_TYPE_UNUSED);
 		}
-		error = g_write_data(cp, (index + 1) * 512, buf, sizeof(buf));
-		if (error)
-			return (error);
 		if (entry != NULL)
 			baseentry = LIST_NEXT(baseentry, gpe_entry);
 	}
 
+	for (index = 0; index < tblsz; index += MAXPHYS / pp->sectorsize) {
+		error = g_write_data(cp, (1 + index) * pp->sectorsize,
+		    buf + index * pp->sectorsize,
+		    (tblsz - index > MAXPHYS / pp->sectorsize) ? MAXPHYS:
+		    (tblsz - index) * pp->sectorsize);
+		if (error) {
+			g_free(buf);
+			return (error);
+		}
+	}
+	g_free(buf);
 	return (0);
 }


More information about the svn-src-head mailing list