diff options
-rw-r--r-- | include/sqfs/block_writer.h | 26 | ||||
-rw-r--r-- | lib/sqfs/block_processor/common.c | 3 | ||||
-rw-r--r-- | lib/sqfs/block_writer.c | 63 |
3 files changed, 55 insertions, 37 deletions
diff --git a/include/sqfs/block_writer.h b/include/sqfs/block_writer.h index 4ac0762..e921141 100644 --- a/include/sqfs/block_writer.h +++ b/include/sqfs/block_writer.h @@ -69,15 +69,19 @@ struct sqfs_block_hooks_t { * disk. If the block has the @ref SQFS_BLK_ALIGN flag set, the * function is called before padding the file. * - * The function may modify the block itself or write data to the file. - * which is taken into account when padding the file. + * The function may write additional data to the file, which is taken + * into account when padding the file. * * @param user A user pointer. - * @param block The block that is about to be written. + * @param flags A pointer to a combination of @ref E_SQFS_BLK_FLAGS + * describing the block. The callback can modify the + * user settable flags. + * @param size The size of the block in bytes. + * @param data A pointer to the raw block data. * @param file The file that the block will be written to. */ - void (*pre_block_write)(void *user, sqfs_block_t *block, - sqfs_file_t *file); + void (*pre_block_write)(void *user, sqfs_u32 *flags, sqfs_u32 size, + const sqfs_u8 *data, sqfs_file_t *file); /** * @brief Gets called after writing a block to disk. @@ -91,11 +95,14 @@ struct sqfs_block_hooks_t { * the file. * * @param user A user pointer. - * @param block The block that is about to be written. + * @param flags A combination of @ref E_SQFS_BLK_FLAGS describing + * the block. + * @param size The size of the block in bytes. + * @param data A pointer to the raw block data. * @param file The file that the block was written to. */ - void (*post_block_write)(void *user, const sqfs_block_t *block, - sqfs_file_t *file); + void (*post_block_write)(void *user, sqfs_u32 flags, sqfs_u32 size, + const sqfs_u8 *data, sqfs_file_t *file); /** * @brief Gets called before writing a block of padding bytes to disk. @@ -216,7 +223,8 @@ SQFS_API void sqfs_block_writer_destroy(sqfs_block_writer_t *wr); * @return Zero on success, an @ref E_SQFS_ERROR error on failure. */ SQFS_API int sqfs_block_writer_write(sqfs_block_writer_t *wr, - sqfs_block_t *block, + sqfs_u32 size, sqfs_u32 checksum, + sqfs_u32 flags, const sqfs_u8 *data, sqfs_u64 *location); /** diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c index 38941ab..e2d92c5 100644 --- a/lib/sqfs/block_processor/common.c +++ b/lib/sqfs/block_processor/common.c @@ -54,7 +54,8 @@ int process_completed_block(sqfs_block_processor_t *proc, sqfs_block_t *blk) if (!(blk->flags & SQFS_BLK_IS_COMPRESSED)) size |= 1 << 24; - err = sqfs_block_writer_write(proc->wr, blk, &location); + err = sqfs_block_writer_write(proc->wr, blk->size, blk->checksum, + blk->flags, blk->data, &location); if (err) return err; diff --git a/lib/sqfs/block_writer.c b/lib/sqfs/block_writer.c index 52ed3ac..f77fcf8 100644 --- a/lib/sqfs/block_writer.c +++ b/lib/sqfs/block_writer.c @@ -88,16 +88,13 @@ static size_t deduplicate_blocks(sqfs_block_writer_t *wr, size_t count) return i; } -static int align_file(sqfs_block_writer_t *wr, sqfs_block_t *blk) +static int align_file(sqfs_block_writer_t *wr) { void *padding; sqfs_u64 size; size_t diff; int ret; - if (!(blk->flags & SQFS_BLK_ALIGN)) - return 0; - size = wr->file->get_size(wr->file); diff = size % wr->devblksz; if (diff == 0) @@ -162,57 +159,69 @@ void sqfs_block_writer_destroy(sqfs_block_writer_t *wr) free(wr); } -int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_block_t *block, - sqfs_u64 *location) +int sqfs_block_writer_write(sqfs_block_writer_t *wr, sqfs_u32 size, + sqfs_u32 checksum, sqfs_u32 flags, + const sqfs_u8 *data, sqfs_u64 *location) { size_t start, count; sqfs_u64 offset; sqfs_u32 out; int err; - if (wr->hooks != NULL && wr->hooks->pre_block_write != NULL) - wr->hooks->pre_block_write(wr->user_ptr, block, wr->file); + if (wr->hooks != NULL && wr->hooks->pre_block_write != NULL) { + out = flags; + flags &= ~SQFS_BLK_USER_SETTABLE_FLAGS; + + wr->hooks->pre_block_write(wr->user_ptr, &out, size, + data, wr->file); - if (block->flags & SQFS_BLK_FIRST_BLOCK) { + flags |= out & SQFS_BLK_USER_SETTABLE_FLAGS; + } + + if (flags & SQFS_BLK_FIRST_BLOCK) { wr->start = wr->file->get_size(wr->file); wr->file_start = wr->num_blocks; - err = align_file(wr, block); - if (err) - return err; + if (flags & SQFS_BLK_ALIGN) { + err = align_file(wr); + if (err) + return err; + } } - if (block->size != 0) { - out = block->size; - if (!(block->flags & SQFS_BLK_IS_COMPRESSED)) + if (size != 0) { + out = size; + if (!(flags & SQFS_BLK_IS_COMPRESSED)) out |= 1 << 24; offset = wr->file->get_size(wr->file); *location = offset; - err = store_block_location(wr, offset, out, block->checksum); + err = store_block_location(wr, offset, out, checksum); if (err) return err; - err = wr->file->write_at(wr->file, offset, - block->data, block->size); + err = wr->file->write_at(wr->file, offset, data, size); if (err) return err; - wr->stats.bytes_submitted += block->size; + wr->stats.bytes_submitted += size; wr->stats.blocks_submitted += 1; wr->stats.blocks_written = wr->num_blocks; - wr->stats.bytes_written = offset + block->size - - wr->data_area_start; + wr->stats.bytes_written = offset + size - wr->data_area_start; } - if (wr->hooks != NULL && wr->hooks->post_block_write != NULL) - wr->hooks->post_block_write(wr->user_ptr, block, wr->file); + if (wr->hooks != NULL && wr->hooks->post_block_write != NULL) { + wr->hooks->post_block_write(wr->user_ptr, flags, size, data, + wr->file); + } - if (block->flags & SQFS_BLK_LAST_BLOCK) { - err = align_file(wr, block); - if (err) - return err; + if (flags & SQFS_BLK_LAST_BLOCK) { + if (flags & SQFS_BLK_ALIGN) { + err = align_file(wr); + if (err) + return err; + } count = wr->num_blocks - wr->file_start; start = deduplicate_blocks(wr, count); |