From 2ff34144df4ce521bfb789a61e24a05aea39b220 Mon Sep 17 00:00:00 2001 From: David Oberhollenzer Date: Fri, 29 May 2020 19:44:09 +0200 Subject: Block processor: Add a raw block submission function This function allows submission of raw blocks to the block processor, completely bypassing the file API. Signed-off-by: David Oberhollenzer --- include/sqfs/block.h | 2 ++ include/sqfs/block_processor.h | 30 ++++++++++++++++++++++++++++++ lib/sqfs/block_processor/common.c | 3 ++- lib/sqfs/block_processor/frontend.c | 27 +++++++++++++++++++++++++++ lib/sqfs/block_processor/internal.h | 5 +++++ lib/sqfs/block_processor/winpthread.c | 3 ++- 6 files changed, 68 insertions(+), 2 deletions(-) diff --git a/include/sqfs/block.h b/include/sqfs/block.h index 582f128..30f181c 100644 --- a/include/sqfs/block.h +++ b/include/sqfs/block.h @@ -149,6 +149,8 @@ typedef enum { * @brief The combination of all flags that are user settable. */ SQFS_BLK_USER_SETTABLE_FLAGS = 0x003F, + + SQFS_BLK_FLAGS_ALL = 0xFC3F, } SQFS_BLK_FLAGS; #endif /* SQFS_BLOCK_H */ diff --git a/include/sqfs/block_processor.h b/include/sqfs/block_processor.h index 5c77155..1846069 100644 --- a/include/sqfs/block_processor.h +++ b/include/sqfs/block_processor.h @@ -214,6 +214,36 @@ SQFS_API int sqfs_block_processor_append(sqfs_block_processor_t *proc, */ SQFS_API int sqfs_block_processor_end_file(sqfs_block_processor_t *proc); +/** + * @brief Submit a raw block for processing. + * + * @memberof sqfs_block_processor_t + * + * This function provides an alternative to the simple file front end to submit + * raw data blocks to the processor. It will throw an error if called in between + * @ref sqfs_block_processor_begin_file and @ref sqfs_block_processor_end_file. + * + * The flags aren't sanity checked (besides being a subset + * of @ref SQFS_BLK_FLAGS_ALL), so in contrast to the simple file API, you can + * shoot yourself in the foot as hard as you want. + * + * If not specified otherwise through flags, the fragment block/deduplication + * and fragment consolidation are still in effect and sparse blocks are + * discarded. + * + * @param proc A pointer to a block processor object. + * @param user An optional user data pointer stored with the block and passed on + * to the underlying @ref sqfs_block_writer_t. + * @param flags A combination of @ref SQFS_BLK_FLAGS that can be used to + * micro manage how the data is processed. + * @param data The data to write to the block. + * + * @return Zero on success, an @ref SQFS_ERROR value on failure. + */ +SQFS_API int sqfs_block_processor_submit_block(sqfs_block_processor_t *proc, + void *user, sqfs_u32 flags, + const void *data, size_t size); + /** * @brief Wait for the in-flight data blocks to finish. * diff --git a/lib/sqfs/block_processor/common.c b/lib/sqfs/block_processor/common.c index b40ec0f..887a101 100644 --- a/lib/sqfs/block_processor/common.c +++ b/lib/sqfs/block_processor/common.c @@ -70,7 +70,8 @@ static int process_completed_block(sqfs_block_processor_t *proc, int err; err = proc->wr->write_data_block(proc->wr, blk->user, blk->size, - blk->checksum, blk->flags, + blk->checksum, + blk->flags & ~BLK_FLAG_INTERNAL, blk->data, &location); if (err) goto out; diff --git a/lib/sqfs/block_processor/frontend.c b/lib/sqfs/block_processor/frontend.c index d6571ea..9e9ecc7 100644 --- a/lib/sqfs/block_processor/frontend.c +++ b/lib/sqfs/block_processor/frontend.c @@ -170,6 +170,33 @@ int sqfs_block_processor_end_file(sqfs_block_processor_t *proc) return 0; } +int sqfs_block_processor_submit_block(sqfs_block_processor_t *proc, void *user, + sqfs_u32 flags, const void *data, + size_t size) +{ + sqfs_block_t *blk; + + if (proc->begin_called) + return SQFS_ERROR_SEQUENCE; + + if (size > proc->max_block_size) + return SQFS_ERROR_OVERFLOW; + + if (flags & ~SQFS_BLK_FLAGS_ALL) + return SQFS_ERROR_UNSUPPORTED; + + blk = get_new_block(proc); + if (blk == NULL) + return SQFS_ERROR_ALLOC; + + blk->flags = flags | BLK_FLAG_MANUAL_SUBMISSION; + blk->user = user; + blk->size = size; + memcpy(blk->data, data, size); + + return proc->append_to_work_queue(proc, blk); +} + const sqfs_block_processor_stats_t *sqfs_block_processor_get_stats(const sqfs_block_processor_t *proc) { diff --git a/lib/sqfs/block_processor/internal.h b/lib/sqfs/block_processor/internal.h index d28e023..0c7e4e6 100644 --- a/lib/sqfs/block_processor/internal.h +++ b/lib/sqfs/block_processor/internal.h @@ -24,6 +24,11 @@ #include #include +enum { + BLK_FLAG_MANUAL_SUBMISSION = 0x10000000, + BLK_FLAG_INTERNAL = 0x10000000, +}; + typedef struct sqfs_block_t { struct sqfs_block_t *next; sqfs_inode_generic_t **inode; diff --git a/lib/sqfs/block_processor/winpthread.c b/lib/sqfs/block_processor/winpthread.c index 44c62f1..afd66c1 100644 --- a/lib/sqfs/block_processor/winpthread.c +++ b/lib/sqfs/block_processor/winpthread.c @@ -344,7 +344,8 @@ static int append_to_work_queue(sqfs_block_processor_t *proc, SIGNAL_ALL(&thproc->queue_cond); } } else { - if (!(blk->flags & SQFS_BLK_FRAGMENT_BLOCK)) + if (!(blk->flags & SQFS_BLK_FRAGMENT_BLOCK) || + blk->flags & BLK_FLAG_MANUAL_SUBMISSION) blk->io_seq_num = thproc->io_enq_id++; store_io_block(thproc, blk); } -- cgit v1.2.3