From 2e797ba95c8147a6316c68417dfe5fcc85f78d71 Mon Sep 17 00:00:00 2001 From: marcel Date: Tue, 4 Nov 2003 03:49:01 +0000 Subject: o Save a copy of the GPT entries for which there's a chunk with an index referencing it. We need to know the original type and name so that we know what to put in the table when we reconstruct it. o Clear the table entries before we rebuild it to avoid that we end up with stale data. o Sequentially populate the table entries from the chunks. For the chunks that have an index (now referencing the saved copy) we use the saved type and name. This way we can handle unknown types better. In all cases we update the start and end LBAs. --- lib/libdisk/write_ia64_disk.c | 65 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 55 insertions(+), 10 deletions(-) (limited to 'lib/libdisk') diff --git a/lib/libdisk/write_ia64_disk.c b/lib/libdisk/write_ia64_disk.c index 789bb0c..bf1af6c 100644 --- a/lib/libdisk/write_ia64_disk.c +++ b/lib/libdisk/write_ia64_disk.c @@ -224,21 +224,57 @@ static int update_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr, struct gpt_ent *tbl) { + struct gpt_ent *save; char *buffer; struct chunk *c; off_t off; size_t bufsz; - int error, idx; + int error, idx, sav; + /* + * Save the entries of those chunks that have an index. They are + * the ones that exist on disk already. + */ + sav = 0; + for (c = disk->chunks->part; c != NULL; c = c->next) { + if ((c->flags & CHUNK_HAS_INDEX)) + sav++; + } + if (sav > 0) { + save = malloc(sav * sizeof(struct gpt_ent)); + if (save == NULL) + abort(); + sav = 0; + for (c = disk->chunks->part; c != NULL; c = c->next) { + if ((c->flags & CHUNK_HAS_INDEX)) { + idx = CHUNK_FTOI(c->flags); + save[sav] = tbl[idx]; + c->flags ^= CHUNK_ITOF(idx); + c->flags |= CHUNK_ITOF(sav); + sav++; + } + } + } else + save = NULL; + + /* + * Clear the table entries. + */ + for (idx = 0; idx < disk->gpt_size; idx++) { + uuid_create_nil(&tbl[idx].ent_type, NULL); + tbl[idx].ent_lba_start = 0; + tbl[idx].ent_lba_end = 0; + tbl[idx].ent_attr = 0; + bzero(tbl[idx].ent_name, sizeof(tbl[idx].ent_name)); + } + + /* + * Repopulate the table from the chunks, possibly using saved + * information. + */ idx = 0; for (c = disk->chunks->part; c != NULL; c = c->next) { if (!(c->flags & CHUNK_HAS_INDEX)) { - while (idx < disk->gpt_size && - !uuid_is_nil(&tbl[idx].ent_type, NULL)) - idx++; - if (idx == disk->gpt_size) - return (ENOSPC); - switch (c->type) { case freebsd: tbl[idx].ent_type = _fbsd; @@ -261,12 +297,21 @@ update_gpt(int fd, const struct disk *disk, struct gpt_hdr *hdr, default: return (EINVAL); } - } else - idx = CHUNK_FTOI(c->flags); - + } else { + sav = CHUNK_FTOI(c->flags); + tbl[idx].ent_type = save[sav].ent_type; + memcpy(tbl[idx].ent_name, save[sav].ent_name, + sizeof(tbl[idx].ent_name)); + } tbl[idx].ent_lba_start = c->offset; tbl[idx].ent_lba_end = c->end; + + idx++; + if (idx == disk->gpt_size) + return (ENOSPC); } + if (save != NULL) + free(save); hdr[0].hdr_crc_table = crc32(tbl, disk->gpt_size * sizeof(struct gpt_ent)); -- cgit v1.1