diff options
author | marcel <marcel@FreeBSD.org> | 2003-11-04 03:49:01 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-11-04 03:49:01 +0000 |
commit | 2e797ba95c8147a6316c68417dfe5fcc85f78d71 (patch) | |
tree | 094aa164b889ed82a7632ebe70457c0cf64bf244 /lib/libdisk | |
parent | d8b13dab5a008a805673ee7788666f80c4622387 (diff) | |
download | FreeBSD-src-2e797ba95c8147a6316c68417dfe5fcc85f78d71.zip FreeBSD-src-2e797ba95c8147a6316c68417dfe5fcc85f78d71.tar.gz |
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.
Diffstat (limited to 'lib/libdisk')
-rw-r--r-- | lib/libdisk/write_ia64_disk.c | 65 |
1 files changed, 55 insertions, 10 deletions
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)); |