Provisorily moved tail writer after checksum writer

and accounted for size of backup GPT in cylinder alignment of tail writer.
This commit is contained in:
Thomas Schmitt 2012-06-13 13:31:37 +02:00
parent 912e0cd1be
commit 0ebc8fe186
4 changed files with 59 additions and 23 deletions

View File

@ -1920,7 +1920,9 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
target->gpt_req[i] = NULL; target->gpt_req[i] = NULL;
target->gpt_part_start = 0; target->gpt_part_start = 0;
target->gpt_backup_end = 0; target->gpt_backup_end = 0;
target->gpt_backup_size = 0;
target->gpt_max_entries = 0; target->gpt_max_entries = 0;
target->gpt_is_computed = 0;
target->filesrc_blocks = 0; target->filesrc_blocks = 0;
@ -2083,19 +2085,33 @@ int ecma119_image_new(IsoImage *src, IsoWriteOpts *opts, Ecma119Image **img)
#endif /* ! Libisofs_gpt_writer_lasT */ #endif /* ! Libisofs_gpt_writer_lasT */
/* >>> Should not the checksum writer come before the zero writer ? */ /* >>> Should not the checksum writer come before the zero writer ?
*/
#define Libisofs_checksums_before_paddinG yes
#ifndef Libisofs_checksums_before_paddinG
/* >>> ??? Why is this important ? */
/* IMPORTANT: This must be the last writer before the checksum writer */ /* IMPORTANT: This must be the last writer before the checksum writer */
ret = zero_writer_create(target, target->tail_blocks, 1); ret = zero_writer_create(target, target->tail_blocks, 1);
if (ret < 0) if (ret < 0)
goto target_cleanup; goto target_cleanup;
#endif /* !Libisofs_checksums_before_paddinG */
if ((target->md5_file_checksums & 1) || target->md5_session_checksum) { if ((target->md5_file_checksums & 1) || target->md5_session_checksum) {
ret = checksum_writer_create(target); ret = checksum_writer_create(target);
if (ret < 0) if (ret < 0)
goto target_cleanup; goto target_cleanup;
} }
#ifdef Libisofs_checksums_before_paddinG
ret = zero_writer_create(target, target->tail_blocks, 1);
if (ret < 0)
goto target_cleanup;
#endif /* Libisofs_checksums_before_paddinG */
#ifdef Libisofs_gpt_writer_lasT #ifdef Libisofs_gpt_writer_lasT
/* This writer shall be the last one in the list, because it protects the /* This writer shall be the last one in the list, because it protects the
image on media which are seen as GPT partitioned. image on media which are seen as GPT partitioned.

View File

@ -856,7 +856,9 @@ struct ecma119_image
uint32_t gpt_part_start; uint32_t gpt_part_start;
/* The ISO block number after the backup GPT header , block size 2048 */ /* The ISO block number after the backup GPT header , block size 2048 */
uint32_t gpt_backup_end; uint32_t gpt_backup_end;
uint32_t gpt_backup_size;
uint32_t gpt_max_entries; uint32_t gpt_max_entries;
int gpt_is_computed;
/* Message from write_head_part1()/iso_write_system_area() to the /* Message from write_head_part1()/iso_write_system_area() to the
write_data() methods of the writers. write_data() methods of the writers.

View File

@ -405,7 +405,7 @@ static int assess_gpt_apm(Ecma119Image *t, int *gpt_count, int gpt_idx[128],
iso_msgs_submit(0, iso_msgs_submit(0,
"Too many entries desired for Apple Partition Map. (max 6)", "Too many entries desired for Apple Partition Map. (max 6)",
0, "FAILURE", 0); 0, "FAILURE", 0);
return ISO_ISOLINUX_CANT_PATCH; return ISO_BOOT_TOO_MANY_APM;
} }
return ISO_SUCCESS; return ISO_SUCCESS;
} }

View File

@ -58,6 +58,8 @@ int make_isolinux_mbr(uint32_t *img_blocks, Ecma119Image *t,
int part_offset, int part_number, int fs_type, int part_offset, int part_number, int fs_type,
uint8_t *buf, int flag); uint8_t *buf, int flag);
static int precompute_gpt(Ecma119Image *t);
/* /*
* @param flag bit0= img_blocks is start address rather than end address: * @param flag bit0= img_blocks is start address rather than end address:
@ -1533,9 +1535,12 @@ int iso_align_isohybrid(Ecma119Image *t, int flag)
{ret = ISO_SUCCESS; goto ex;} {ret = ISO_SUCCESS; goto ex;}
always_align = (t->system_area_options >> 8) & 3; always_align = (t->system_area_options >> 8) & 3;
/* >>> Take into account the other stuff: TAIL GPTB */; /* Take into account the backup GPT */;
ret = precompute_gpt(t);
if (ret < 0)
goto ex;
img_blocks = t->curblock + t->tail_blocks; img_blocks = t->curblock + t->tail_blocks + t->gpt_backup_size;
imgsize = ((off_t) img_blocks) * (off_t) 2048; imgsize = ((off_t) img_blocks) * (off_t) 2048;
if (((t->system_area_options & 3) || always_align) if (((t->system_area_options & 3) || always_align)
&& (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head && (off_t) (t->partition_heads_per_cyl * t->partition_secs_per_head
@ -1794,16 +1799,14 @@ void iso_random_8byte(Ecma119Image *t, uint8_t result[8])
} }
static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer) /* Probably already called by tail writer */
static int precompute_gpt(Ecma119Image *t)
{ {
Ecma119Image *t; uint32_t gpt_part_start;
uint32_t gpt_part_start, gpt_size;
int ret; int ret;
if (writer == NULL) { /* Avoid repetition by gpt_tail_writer_compute_data_blocks */
return ISO_ASSERT_FAILURE; t->gpt_is_computed = 1;
}
t = writer->target;
/* Rectify APM requests early in order to learn the size of GPT. /* Rectify APM requests early in order to learn the size of GPT.
iso_write_apm() relies on this being already done here. iso_write_apm() relies on this being already done here.
@ -1877,10 +1880,27 @@ static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer)
/* Necessary number of 2K blocks */ /* Necessary number of 2K blocks */
t->gpt_max_entries = (64 - t->gpt_part_start) * 4; t->gpt_max_entries = (64 - t->gpt_part_start) * 4;
gpt_size = (t->gpt_max_entries / 4 + 1) * 512; t->gpt_backup_size = ((t->gpt_max_entries / 4 + 1) * 512 + 2047) / 2048;
t->curblock += gpt_size / 2048;
if (gpt_size % 2048) return ISO_SUCCESS;
t->curblock++; }
static int gpt_tail_writer_compute_data_blocks(IsoImageWriter *writer)
{
Ecma119Image *t;
int ret;
if (writer == NULL)
return ISO_ASSERT_FAILURE;
t = writer->target;
if (! t->gpt_is_computed) {
ret = precompute_gpt(t);
if (ret < 0)
return ret;
}
t->curblock += t->gpt_backup_size;
/* The ISO block number after the backup GPT header */ /* The ISO block number after the backup GPT header */
t->gpt_backup_end = t->curblock; t->gpt_backup_end = t->curblock;
@ -1899,7 +1919,7 @@ static int gpt_tail_writer_write_data(IsoImageWriter *writer)
Ecma119Image *t; Ecma119Image *t;
uint8_t *head, *new_head, *entries; uint8_t *head, *new_head, *entries;
uint8_t *backup_buf = NULL; uint8_t *backup_buf = NULL;
uint32_t gpt_size, crc, i; uint32_t crc, i;
uint64_t part_start; uint64_t part_start;
int ret; int ret;
@ -1907,12 +1927,10 @@ static int gpt_tail_writer_write_data(IsoImageWriter *writer)
if (t->gpt_backup_end == 0 || t->gpt_max_entries == 0) if (t->gpt_backup_end == 0 || t->gpt_max_entries == 0)
return ISO_SUCCESS; /* No backup GPT area reserved by compute_data() */ return ISO_SUCCESS; /* No backup GPT area reserved by compute_data() */
gpt_size = (t->gpt_max_entries / 4 + 1) * 512; backup_buf = calloc(1, t->gpt_backup_size * 2048);
gpt_size = gpt_size / 2048 + !!(gpt_size % 2048);
backup_buf = calloc(1, gpt_size * 2048);
if (backup_buf == NULL) if (backup_buf == NULL)
return ISO_OUT_OF_MEM; return ISO_OUT_OF_MEM;
memset(backup_buf, 0, gpt_size * 2048); memset(backup_buf, 0, t->gpt_backup_size * 2048);
/* Check whether GPT header block came through */ /* Check whether GPT header block came through */
head = t->sys_area_as_written + 512; head = t->sys_area_as_written + 512;
@ -1929,7 +1947,7 @@ tampered_head:;
goto tampered_head; goto tampered_head;
/* Patch memorized header block */ /* Patch memorized header block */
new_head = backup_buf + gpt_size * 2048 - 512; new_head = backup_buf + t->gpt_backup_size * 2048 - 512;
memcpy(new_head, head, 512); memcpy(new_head, head, 512);
/* Exchange "Location of this header" and "Location of header backup" */ /* Exchange "Location of this header" and "Location of header backup" */
memcpy(new_head + 24, head + 32, 8); memcpy(new_head + 24, head + 32, 8);
@ -1950,14 +1968,14 @@ tampered_head:;
memcpy(new_head - t->gpt_max_entries * 128, memcpy(new_head - t->gpt_max_entries * 128,
entries, t->gpt_max_entries * 128); entries, t->gpt_max_entries * 128);
ret = iso_write(t, backup_buf, gpt_size * 2048); ret = iso_write(t, backup_buf, t->gpt_backup_size * 2048);
free(backup_buf); free(backup_buf);
if (ret < 0) if (ret < 0)
return ret; return ret;
return ISO_SUCCESS; return ISO_SUCCESS;
write_zeros:; write_zeros:;
ret = iso_write(t, backup_buf, gpt_size * 2048); ret = iso_write(t, backup_buf, t->gpt_backup_size * 2048);
free(backup_buf); free(backup_buf);
if (ret < 0) if (ret < 0)
return ret; return ret;