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-all
mailing list