summaryrefslogtreecommitdiffstats
path: root/lib/libdisk
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-11-04 03:49:01 +0000
committermarcel <marcel@FreeBSD.org>2003-11-04 03:49:01 +0000
commit2e797ba95c8147a6316c68417dfe5fcc85f78d71 (patch)
tree094aa164b889ed82a7632ebe70457c0cf64bf244 /lib/libdisk
parentd8b13dab5a008a805673ee7788666f80c4622387 (diff)
downloadFreeBSD-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.c65
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));
OpenPOWER on IntegriCloud