diff options
Diffstat (limited to 'lib/sqfs')
| -rw-r--r-- | lib/sqfs/data_writer/common.c | 1 | ||||
| -rw-r--r-- | lib/sqfs/data_writer/fileapi.c | 78 | ||||
| -rw-r--r-- | lib/sqfs/data_writer/internal.h | 2 | 
3 files changed, 61 insertions, 20 deletions
| diff --git a/lib/sqfs/data_writer/common.c b/lib/sqfs/data_writer/common.c index c9d5589..9e11e36 100644 --- a/lib/sqfs/data_writer/common.c +++ b/lib/sqfs/data_writer/common.c @@ -47,6 +47,7 @@ void data_writer_cleanup(sqfs_data_writer_t *proc)  {  	free_blk_list(proc->queue);  	free_blk_list(proc->done); +	free(proc->blk_current);  	free(proc->frag_block);  	free(proc->frag_list);  	free(proc->fragments); diff --git a/lib/sqfs/data_writer/fileapi.c b/lib/sqfs/data_writer/fileapi.c index b78d012..712fd29 100644 --- a/lib/sqfs/data_writer/fileapi.c +++ b/lib/sqfs/data_writer/fileapi.c @@ -35,16 +35,14 @@ int sqfs_data_writer_begin_file(sqfs_data_writer_t *proc,  		return test_and_set_status(proc, SQFS_ERROR_UNSUPPORTED);  	proc->inode = inode; -	proc->blk_flags = flags; +	proc->blk_flags = flags | SQFS_BLK_FIRST_BLOCK;  	proc->blk_index = 0; -	proc->had_fragment = false; +	proc->blk_current = NULL;  	return 0;  } -int sqfs_data_writer_enqueue(sqfs_data_writer_t *proc, sqfs_block_t *block) +static int flush_block(sqfs_data_writer_t *proc, sqfs_block_t *block)  { -	int err; -  	block->index = proc->blk_index++;  	block->flags = proc->blk_flags;  	block->inode = proc->inode; @@ -59,25 +57,63 @@ int sqfs_data_writer_enqueue(sqfs_data_writer_t *proc, sqfs_block_t *block)  	}  	if (block->size < proc->max_block_size) { -		if (block->index > 0) { -			err = add_sentinel_block(proc); +		block->flags |= SQFS_BLK_IS_FRAGMENT; +	} else { +		proc->inode->num_file_blocks += 1; +		proc->blk_flags &= ~SQFS_BLK_FIRST_BLOCK; +	} + +	return data_writer_enqueue(proc, block); +} + +int sqfs_data_writer_append(sqfs_data_writer_t *proc, const void *data, +			    size_t size) +{ +	size_t diff; +	void *new; +	int err; + +	while (size > 0) { +		if (proc->blk_current == NULL) { +			new = alloc_flex(sizeof(*proc->blk_current), 1, +					 proc->max_block_size); + +			if (new == NULL) +				return test_and_set_status(proc, +							   SQFS_ERROR_ALLOC); -			if (err) { -				free(block); +			proc->blk_current = new; +		} + +		diff = proc->max_block_size - proc->blk_current->size; + +		if (diff == 0) { +			err = flush_block(proc, proc->blk_current); +			proc->blk_current = NULL; +			if (err)  				return err; -			} +			continue;  		} -		proc->had_fragment = true; -		block->flags |= SQFS_BLK_IS_FRAGMENT; -	} else { -		if (block->index == 0) -			block->flags |= SQFS_BLK_FIRST_BLOCK; +		if (diff > size) +			diff = size; -		proc->inode->num_file_blocks += 1; +		memcpy(proc->blk_current->data + proc->blk_current->size, +		       data, diff); + +		size -= diff; +		proc->blk_current->size += diff; +		data = (const char *)data + diff;  	} -	return data_writer_enqueue(proc, block); +	if (proc->blk_current != NULL && +	    proc->blk_current->size == proc->max_block_size) { +		err = flush_block(proc, proc->blk_current); +		proc->blk_current = NULL; +		return err; +	} + +	return 0;  }  int sqfs_data_writer_end_file(sqfs_data_writer_t *proc) @@ -87,15 +123,19 @@ int sqfs_data_writer_end_file(sqfs_data_writer_t *proc)  	if (proc->inode == NULL)  		return test_and_set_status(proc, SQFS_ERROR_INTERNAL); -	if (!proc->had_fragment && proc->inode->num_file_blocks > 0) { +	if (!(proc->blk_flags & SQFS_BLK_FIRST_BLOCK)) {  		err = add_sentinel_block(proc);  		if (err)  			return err;  	} +	if (proc->blk_current != NULL) { +		err = flush_block(proc, proc->blk_current); +		proc->blk_current = NULL; +	} +  	proc->inode = NULL;  	proc->blk_flags = 0;  	proc->blk_index = 0; -	proc->had_fragment = false;  	return 0;  } diff --git a/lib/sqfs/data_writer/internal.h b/lib/sqfs/data_writer/internal.h index 9072c19..1aa600b 100644 --- a/lib/sqfs/data_writer/internal.h +++ b/lib/sqfs/data_writer/internal.h @@ -103,9 +103,9 @@ struct sqfs_data_writer_t {  	/* file API */  	sqfs_inode_generic_t *inode; +	sqfs_block_t *blk_current;  	uint32_t blk_flags;  	size_t blk_index; -	bool had_fragment;  	/* used only by workers */  	size_t max_block_size; | 
