/* Read length bytes from metadata position <block, offset> (block is the start of the compressed block on disk, and offset is the offset into the block once decompressed). Data is packed into consecutive blocks, and length bytes may require reading more than one block.  */
int squashfs_read_metadata(struct super_block *sb, void *buffer, u64 *block, int *offset, int length)
/* Read length bytes from metadata position <block, offset> (block is the start of the compressed block on disk, and offset is the offset into the block once decompressed). Data is packed into consecutive blocks, and length bytes may require reading more than one block.  */
int squashfs_read_metadata(struct super_block *sb, void *buffer, u64 *block, int *offset, int length)
{
	struct squashfs_sb_info *msblk = sb->s_fs_info;
	int bytes, copied = length;
	struct squashfs_cache_entry *entry;
	TRACE("Entered squashfs_read_metadata [%llx:%x]\n", *block, *offset);
	while (length) {
		entry = squashfs_cache_get(sb, msblk->block_cache, *block, 0);
		if (entry->error)
			return entry->error;
		else if (*offset >= entry->length)
			return -EIO;
		bytes = squashfs_copy_data(buffer, entry, *offset, length);
		if (buffer)
			buffer += bytes;
		length -= bytes;
		*offset += bytes;
		if (*offset == entry->length) {
			*block = entry->next_index;
			*offset = 0;
		}
		squashfs_cache_put(entry);
	}
	return copied;
}