Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aec73165 authored by Adrien Schildknecht's avatar Adrien Schildknecht Committed by android-build-merger
Browse files

Manually merge commit '61e74d7a' into stage-aosp-master

am: 9f9a239c

Change-Id: Ia404f62a4b3c2acda8ef063d27e10799070f9e7e
parents b8de7b40 9f9a239c
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -175,6 +175,13 @@ int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
 */
int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc);

/**
 * sparse_file_block_size
 *
 * @s - sparse file cookie
 */
unsigned int sparse_file_block_size(struct sparse_file *s);

/**
 * sparse_file_callback - call a callback for blocks in sparse file
 *
@@ -196,6 +203,24 @@ int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc);
int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
		int (*write)(void *priv, const void *data, int len), void *priv);

/**
 * sparse_file_foreach_chunk - call a callback for data blocks in sparse file
 *
 * @s - sparse file cookie
 * @sparse - write in the Android sparse file format
 * @crc - append a crc chunk
 * @write - function to call for each block
 * @priv - value that will be passed as the first argument to write
 *
 * The function has the same behavior as 'sparse_file_callback', except it only
 * iterates on blocks that contain data.
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
	int (*write)(void *priv, const void *data, int len, unsigned int block,
		     unsigned int nr_blocks),
	void *priv);
/**
 * sparse_file_read - read a file into a sparse file cookie
 *
+56 −0
Original line number Diff line number Diff line
@@ -199,6 +199,57 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
	return ret;
}

struct chunk_data {
	void		*priv;
	unsigned int	block;
	unsigned int	nr_blocks;
	int (*write)(void *priv, const void *data, int len, unsigned int block,
		     unsigned int nr_blocks);
};

static int foreach_chunk_write(void *priv, const void *data, int len)
{
	struct chunk_data *chk = priv;

	return chk->write(chk->priv, data, len, chk->block, chk->nr_blocks);
}

int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
	int (*write)(void *priv, const void *data, int len, unsigned int block,
		     unsigned int nr_blocks),
	void *priv)
{
	int ret;
	int chunks;
	struct chunk_data chk;
	struct output_file *out;
	struct backed_block *bb;

	chk.priv = priv;
	chk.write = write;
	chk.block = chk.nr_blocks = 0;
	chunks = sparse_count_chunks(s);
	out = output_file_open_callback(foreach_chunk_write, &chk,
					s->block_size, s->len, false, sparse,
					chunks, crc);

	if (!out)
		return -ENOMEM;

	for (bb = backed_block_iter_new(s->backed_block_list); bb;
			bb = backed_block_iter_next(bb)) {
		chk.block = backed_block_block(bb);
		chk.nr_blocks = (backed_block_len(bb) - 1) / s->block_size + 1;
		ret = sparse_file_write_block(out, bb);
		if (ret)
			return ret;
	}

	output_file_close(out);

	return ret;
}

static int out_counter_write(void *priv, const void *data __unused, int len)
{
	int64_t *count = priv;
@@ -230,6 +281,11 @@ int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc)
	return count;
}

unsigned int sparse_file_block_size(struct sparse_file *s)
{
	return s->block_size;
}

static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
		struct sparse_file *to, unsigned int len)
{