diff options
Diffstat (limited to 'lib/sqfshelper')
| -rw-r--r-- | lib/sqfshelper/data_writer.c | 58 | ||||
| -rw-r--r-- | lib/sqfshelper/serialize_fstree.c | 3 | ||||
| -rw-r--r-- | lib/sqfshelper/tree_node_to_inode.c | 97 | 
3 files changed, 59 insertions, 99 deletions
| diff --git a/lib/sqfshelper/data_writer.c b/lib/sqfshelper/data_writer.c index f7d8805..9f418f1 100644 --- a/lib/sqfshelper/data_writer.c +++ b/lib/sqfshelper/data_writer.c @@ -113,7 +113,7 @@ static size_t deduplicate_blocks(data_writer_t *data, size_t count)  static int block_callback(void *user, sqfs_block_t *blk)  { -	file_info_t *fi = blk->user; +	sqfs_inode_generic_t *inode = blk->user;  	data_writer_t *data = user;  	size_t start, count;  	uint64_t offset; @@ -144,7 +144,7 @@ static int block_callback(void *user, sqfs_block_t *blk)  			data->stats.frag_blocks_written += 1;  		} else { -			fi->block_size[blk->index] = htole32(out); +			inode->block_sizes[blk->index] = htole32(out);  			data->stats.blocks_written += 1;  		} @@ -164,8 +164,9 @@ static int block_callback(void *user, sqfs_block_t *blk)  		count = data->num_blocks - data->file_start;  		start = deduplicate_blocks(data, count); +		offset = data->blocks[start].offset; -		fi->startblock = data->blocks[start].offset; +		sqfs_inode_set_file_block_start(inode, offset);  		if (start < data->file_start) {  			offset = start + count; @@ -221,7 +222,7 @@ static int flush_fragment_block(data_writer_t *data)  static int handle_fragment(data_writer_t *data, sqfs_block_t *frag)  { -	file_info_t *fi = frag->user; +	sqfs_inode_generic_t *inode = frag->user;  	size_t i, size, new_sz;  	uint64_t signature;  	void *new; @@ -231,8 +232,9 @@ static int handle_fragment(data_writer_t *data, sqfs_block_t *frag)  	for (i = 0; i < data->frag_list_num; ++i) {  		if (data->frag_list[i].signature == signature) { -			fi->fragment_offset = data->frag_list[i].offset; -			fi->fragment = data->frag_list[i].index; +			sqfs_inode_set_frag_location(inode, +						     data->frag_list[i].index, +						     data->frag_list[i].offset);  			free(frag);  			data->stats.frag_dup += 1; @@ -280,8 +282,8 @@ static int handle_fragment(data_writer_t *data, sqfs_block_t *frag)  	data->frag_list[data->frag_list_num].signature = signature;  	data->frag_list_num += 1; -	fi->fragment_offset = data->frag_block->size; -	fi->fragment = data->num_fragments; +	sqfs_inode_set_frag_location(inode, data->num_fragments, +				     data->frag_block->size);  	data->frag_block->flags |= (frag->flags & SQFS_BLK_DONT_COMPRESS);  	memcpy(data->frag_block->data + data->frag_block->size, @@ -302,7 +304,7 @@ static bool is_zero_block(unsigned char *ptr, size_t size)  	return ptr[0] == 0 && memcmp(ptr, ptr + 1, size - 1) == 0;  } -static int add_sentinel_block(data_writer_t *data, file_info_t *fi, +static int add_sentinel_block(data_writer_t *data, sqfs_inode_generic_t *inode,  			      uint32_t flags)  {  	sqfs_block_t *blk = calloc(1, sizeof(*blk)); @@ -312,20 +314,20 @@ static int add_sentinel_block(data_writer_t *data, file_info_t *fi,  		return -1;  	} -	blk->user = fi; +	blk->user = inode;  	blk->flags = SQFS_BLK_DONT_COMPRESS | SQFS_BLK_DONT_CHECKSUM | flags;  	return sqfs_block_processor_enqueue(data->proc, blk);  }  int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file, -				   file_info_t *fi, +				   sqfs_inode_generic_t *inode,  				   const sqfs_sparse_map_t *map, int flags)  {  	uint32_t blk_flags = SQFS_BLK_FIRST_BLOCK; +	uint64_t filesz, offset;  	size_t diff, i = 0;  	sqfs_block_t *blk; -	uint64_t offset;  	int ret;  	if (flags & DW_DONT_COMPRESS) @@ -334,19 +336,21 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  	if (flags & DW_ALLIGN_DEVBLK)  		blk_flags |= SQFS_BLK_ALLIGN; -	for (offset = 0; offset < fi->size; offset += diff) { -		if (fi->size - offset > (uint64_t)data->super->block_size) { +	sqfs_inode_get_file_size(inode, &filesz); + +	for (offset = 0; offset < filesz; offset += diff) { +		if (filesz - offset > (uint64_t)data->super->block_size) {  			diff = data->super->block_size;  		} else { -			diff = fi->size - offset; +			diff = filesz - offset;  		}  		if (map == NULL) { -			ret = sqfs_file_create_block(file, offset, diff, fi, +			ret = sqfs_file_create_block(file, offset, diff, inode,  						     blk_flags, &blk);  		} else {  			ret = sqfs_file_create_block_dense(file, offset, diff, -							   fi, blk_flags, +							   inode, blk_flags,  							   map, &blk);  		} @@ -358,7 +362,11 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  		if (is_zero_block(blk->data, blk->size)) {  			data->stats.sparse_blocks += 1; -			fi->block_size[blk->index] = 0; +			sqfs_inode_make_extended(inode); +			inode->data.file_ext.sparse += blk->size; +			inode->num_file_blocks += 1; + +			inode->block_sizes[blk->index] = 0;  			free(blk);  			continue;  		} @@ -369,7 +377,8 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  					   SQFS_BLK_LAST_BLOCK))) {  				blk_flags |= SQFS_BLK_LAST_BLOCK; -				if (add_sentinel_block(data, fi, blk_flags)) { +				if (add_sentinel_block(data, inode, +						       blk_flags)) {  					free(blk);  					return -1;  				} @@ -382,25 +391,28 @@ int write_data_from_file_condensed(data_writer_t *data, sqfs_file_t *file,  				return -1;  			blk_flags &= ~SQFS_BLK_FIRST_BLOCK; +			inode->num_file_blocks += 1;  		}  	}  	if (!(blk_flags & (SQFS_BLK_FIRST_BLOCK | SQFS_BLK_LAST_BLOCK))) {  		blk_flags |= SQFS_BLK_LAST_BLOCK; -		if (add_sentinel_block(data, fi, blk_flags)) +		if (add_sentinel_block(data, inode, blk_flags))  			return -1;  	} -	data->stats.bytes_read += fi->size; +	sqfs_inode_make_basic(inode); + +	data->stats.bytes_read += filesz;  	data->stats.file_count += 1;  	return 0;  } -int write_data_from_file(data_writer_t *data, file_info_t *fi, +int write_data_from_file(data_writer_t *data, sqfs_inode_generic_t *inode,  			 sqfs_file_t *file, int flags)  { -	return write_data_from_file_condensed(data, file, fi, NULL, flags); +	return write_data_from_file_condensed(data, file, inode, NULL, flags);  }  data_writer_t *data_writer_create(sqfs_super_t *super, sqfs_compressor_t *cmp, diff --git a/lib/sqfshelper/serialize_fstree.c b/lib/sqfshelper/serialize_fstree.c index 61f9ae2..e012902 100644 --- a/lib/sqfshelper/serialize_fstree.c +++ b/lib/sqfshelper/serialize_fstree.c @@ -92,8 +92,7 @@ int sqfs_serialize_fstree(sqfs_file_t *file, sqfs_super_t *super, fstree_t *fs,  			inode = write_dir_entries(dirwr, fs->inode_table[i],  						  idtbl);  		} else { -			inode = tree_node_to_inode(fs, idtbl, -						   fs->inode_table[i]); +			inode = tree_node_to_inode(idtbl, fs->inode_table[i]);  		}  		if (inode == NULL) diff --git a/lib/sqfshelper/tree_node_to_inode.c b/lib/sqfshelper/tree_node_to_inode.c index fa8c538..5cb04a4 100644 --- a/lib/sqfshelper/tree_node_to_inode.c +++ b/lib/sqfshelper/tree_node_to_inode.c @@ -39,69 +39,38 @@ static int get_type(tree_node_t *node)  		if (node->xattr != NULL)  			return SQFS_INODE_EXT_CDEV;  		return SQFS_INODE_CDEV; -	case S_IFREG: { -		file_info_t *fi = node->data.file; - -		if (node->xattr != NULL || fi->sparse > 0) -			return SQFS_INODE_EXT_FILE; - -		if (fi->startblock > 0xFFFFFFFFUL || fi->size > 0xFFFFFFFFUL) -			return SQFS_INODE_EXT_FILE; - -		return SQFS_INODE_FILE; -	}  	}  	assert(0);  } -static bool has_fragment(const fstree_t *fs, const file_info_t *file) -{ -	if (file->size % fs->block_size == 0) -		return false; - -	return file->fragment_offset < fs->block_size && -		(file->fragment != 0xFFFFFFFF); -} - -sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl, +sqfs_inode_generic_t *tree_node_to_inode(sqfs_id_table_t *idtbl,  					 tree_node_t *node)  { -	size_t i, extra = 0, block_count = 0;  	sqfs_inode_generic_t *inode;  	uint16_t uid_idx, gid_idx;  	uint32_t xattr = 0xFFFFFFFF; -	file_info_t *fi = NULL; - -	if (S_ISLNK(node->mode)) { -		extra = strlen(node->data.slink_target); -	} else if (S_ISREG(node->mode)) { -		fi = node->data.file; - -		block_count = fi->size / fs->block_size; - -		if ((fi->size % fs->block_size) != 0 && !has_fragment(fs, fi)) -			++block_count; - -		extra = block_count * sizeof(uint32_t); -	} - -	inode = alloc_flex(sizeof(*inode), 1, extra); -	if (inode == NULL) { -		perror("creating inode from file system tree node"); -		return NULL; -	} - -	if (S_ISLNK(node->mode)) { -		inode->slink_target = (char *)inode->extra; +	size_t extra = 0; + +	if (S_ISREG(node->mode)) { +		inode = node->data.file->user_ptr; +		node->data.file->user_ptr = NULL; +	} else { +		if (S_ISLNK(node->mode)) +			extra = strlen(node->data.slink_target); + +		inode = alloc_flex(sizeof(*inode), 1, extra); +		if (inode == NULL) { +			perror("creating inode from file system tree node"); +			return NULL; +		} -		memcpy(inode->extra, node->data.slink_target, extra); -	} else if (S_ISREG(node->mode)) { -		inode->block_sizes = (uint32_t *)inode->extra; +		if (S_ISLNK(node->mode)) { +			inode->slink_target = (char *)inode->extra; -		for (i = 0; i < block_count; ++i) { -			inode->block_sizes[i] = -				node->data.file->block_size[i]; +			memcpy(inode->extra, node->data.slink_target, extra);  		} + +		inode->base.type = get_type(node);  	}  	if (sqfs_id_table_id_to_index(idtbl, node->uid, &uid_idx)) @@ -113,7 +82,6 @@ sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl,  	if (node->xattr != NULL)  		xattr = node->xattr->index; -	inode->base.type = get_type(node);  	inode->base.mode = node->mode;  	inode->base.uid_idx = uid_idx;  	inode->base.gid_idx = gid_idx; @@ -151,36 +119,17 @@ sqfs_inode_generic_t *tree_node_to_inode(fstree_t *fs, sqfs_id_table_t *idtbl,  		inode->data.dev_ext.xattr_idx = xattr;  		break;  	case SQFS_INODE_FILE: -		inode->data.file.blocks_start = fi->startblock; -		inode->data.file.fragment_index = 0xFFFFFFFF; -		inode->data.file.fragment_offset = 0xFFFFFFFF; -		inode->data.file.file_size = fi->size; - -		if (has_fragment(fs, fi)) { -			inode->data.file.fragment_index = fi->fragment; -			inode->data.file.fragment_offset = fi->fragment_offset; +		if (xattr != 0xFFFFFFFF) { +			sqfs_inode_make_extended(inode); +			inode->data.file_ext.xattr_idx = xattr;  		}  		break;  	case SQFS_INODE_EXT_FILE: -		inode->data.file_ext.blocks_start = fi->startblock; -		inode->data.file_ext.file_size = fi->size; -		inode->data.file_ext.sparse = fi->sparse; -		inode->data.file_ext.nlink = 1; -		inode->data.file_ext.fragment_idx = 0xFFFFFFFF; -		inode->data.file_ext.fragment_offset = 0xFFFFFFFF; -		inode->data.file_ext.xattr_idx = xattr; - -		if (has_fragment(fs, fi)) { -			inode->data.file_ext.fragment_idx = fi->fragment; -			inode->data.file_ext.fragment_offset = -				fi->fragment_offset; -		}  		break;  	default:  		goto fail;  	} -	inode->num_file_blocks = block_count;  	return inode;  fail:  	free(inode); | 
