Improve growing by padding the image, if needed.
The padding ensures first 64 KiB can be overwritten without data lost if we grow the image.
This commit is contained in:
parent
7af02cddd9
commit
f3c27e681f
@ -647,6 +647,87 @@ int ecma119_writer_create(Ecma119Image *target)
|
|||||||
return ISO_SUCCESS;
|
return ISO_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** compute how many padding bytes are needed */
|
||||||
|
static
|
||||||
|
int pad_writer_compute_data_blocks(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
Ecma119Image *target;
|
||||||
|
|
||||||
|
if (writer == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
target = writer->target;
|
||||||
|
if (target->curblock < 32) {
|
||||||
|
target->pad_blocks = 32 - target->curblock;
|
||||||
|
target->curblock = 32;
|
||||||
|
}
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int pad_writer_write_vol_desc(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
static
|
||||||
|
int pad_writer_write_data(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
Ecma119Image *t;
|
||||||
|
uint32_t pad[BLOCK_SIZE];
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (writer == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
t = writer->target;
|
||||||
|
|
||||||
|
if (t->pad_blocks == 0) {
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(pad, 0, BLOCK_SIZE);
|
||||||
|
for (i = 0; i < t->pad_blocks; ++i) {
|
||||||
|
ret = iso_write(t, pad, BLOCK_SIZE);
|
||||||
|
if (ret < 0) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int pad_writer_free_data(IsoImageWriter *writer)
|
||||||
|
{
|
||||||
|
/* nothing to do */
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
int pad_writer_create(Ecma119Image *target)
|
||||||
|
{
|
||||||
|
IsoImageWriter *writer;
|
||||||
|
|
||||||
|
writer = malloc(sizeof(IsoImageWriter));
|
||||||
|
if (writer == NULL) {
|
||||||
|
return ISO_MEM_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer->compute_data_blocks = pad_writer_compute_data_blocks;
|
||||||
|
writer->write_vol_desc = pad_writer_write_vol_desc;
|
||||||
|
writer->write_data = pad_writer_write_data;
|
||||||
|
writer->free_data = pad_writer_free_data;
|
||||||
|
writer->data = NULL;
|
||||||
|
writer->target = target;
|
||||||
|
|
||||||
|
/* add this writer to image */
|
||||||
|
target->writers[target->nwriters++] = writer;
|
||||||
|
return ISO_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void *write_function(void *arg)
|
void *write_function(void *arg)
|
||||||
{
|
{
|
||||||
@ -717,7 +798,7 @@ void *write_function(void *arg)
|
|||||||
static
|
static
|
||||||
int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, Ecma119Image **img)
|
int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, Ecma119Image **img)
|
||||||
{
|
{
|
||||||
int ret, i, voldesc_size;
|
int ret, i, voldesc_size, nwriters;
|
||||||
Ecma119Image *target;
|
Ecma119Image *target;
|
||||||
|
|
||||||
/* 1. Allocate target and copy opts there */
|
/* 1. Allocate target and copy opts there */
|
||||||
@ -788,7 +869,8 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, Ecma119Image **img)
|
|||||||
target->curblock = target->ms_block + 16;
|
target->curblock = target->ms_block + 16;
|
||||||
|
|
||||||
/* the number of writers is dependent of the extensions */
|
/* the number of writers is dependent of the extensions */
|
||||||
target->writers = malloc(2 * sizeof(void*));
|
nwriters = 1 + 1 + 1; /* ECMA-119 + padding + files */
|
||||||
|
target->writers = malloc(nwriters * sizeof(void*));
|
||||||
if (target->writers == NULL) {
|
if (target->writers == NULL) {
|
||||||
iso_image_unref(src);
|
iso_image_unref(src);
|
||||||
free(target);
|
free(target);
|
||||||
@ -806,6 +888,15 @@ int ecma119_image_new(IsoImage *src, Ecma119WriteOpts *opts, Ecma119Image **img)
|
|||||||
/* Volume Descriptor Set Terminator */
|
/* Volume Descriptor Set Terminator */
|
||||||
target->curblock++;
|
target->curblock++;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create the writer for possible padding to ensure that in case of image
|
||||||
|
* growing we can safety overwrite the first 64 KiB of image.
|
||||||
|
*/
|
||||||
|
ret = pad_writer_create(target);
|
||||||
|
if (ret < 0) {
|
||||||
|
goto target_cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
/* create writer for file contents */
|
/* create writer for file contents */
|
||||||
ret = iso_file_src_writer_create(target);
|
ret = iso_file_src_writer_create(target);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
@ -93,6 +93,21 @@ struct ecma119_image
|
|||||||
uint32_t l_path_table_pos;
|
uint32_t l_path_table_pos;
|
||||||
uint32_t m_path_table_pos;
|
uint32_t m_path_table_pos;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Number of pad blocks that we need to write. Padding blocks are blocks
|
||||||
|
* filled by 0s that we put between the directory structures and the file
|
||||||
|
* data. These padding blocks are added by libisofs to improve the handling
|
||||||
|
* of image growing. The idea is that the first blocks in the image are
|
||||||
|
* overwritten with the volume descriptors of the new image. These first
|
||||||
|
* blocks usually correspond to the volume descriptors and directory
|
||||||
|
* structure of the old image, and can be safety overwritten. However,
|
||||||
|
* with very small images they might correspond to valid data. To ensure
|
||||||
|
* this never happens, what we do is to add padding bytes, to ensure no
|
||||||
|
* file data is written in the first 64 KiB, that are the bytes we usually
|
||||||
|
* overwrite.
|
||||||
|
*/
|
||||||
|
uint32_t pad_blocks;
|
||||||
|
|
||||||
size_t nwriters;
|
size_t nwriters;
|
||||||
IsoImageWriter **writers;
|
IsoImageWriter **writers;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user