summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrien Schildknecht2016-12-02 22:20:07 -0600
committerandroid-build-merger2016-12-02 22:20:07 -0600
commitad0cd643328fb79faae7d7a6ea974239cf53ebaa (patch)
tree2fe73bb68353f2064d8516302a3ece14c5e26581 /libsparse
parent79cb08e43d788f4eb172facdc62b3f85259bd6be (diff)
parent669716d27c713708cc1b43849fa80a85e7e45ffc (diff)
downloadplatform-system-core-ad0cd643328fb79faae7d7a6ea974239cf53ebaa.tar.gz
platform-system-core-ad0cd643328fb79faae7d7a6ea974239cf53ebaa.tar.xz
platform-system-core-ad0cd643328fb79faae7d7a6ea974239cf53ebaa.zip
Manually merge commit '61e74d7' into stage-aosp-master am: 9f9a239ca3 am: aec7316546
am: 669716d27c Change-Id: I75f9c115fe178008174f1fea8cb8b890b83c2543
Diffstat (limited to 'libsparse')
-rw-r--r--libsparse/include/sparse/sparse.h25
-rw-r--r--libsparse/sparse.c56
2 files changed, 81 insertions, 0 deletions
diff --git a/libsparse/include/sparse/sparse.h b/libsparse/include/sparse/sparse.h
index 42d4adb87..356f65fd0 100644
--- a/libsparse/include/sparse/sparse.h
+++ b/libsparse/include/sparse/sparse.h
@@ -176,6 +176,13 @@ int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
176int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc); 176int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc);
177 177
178/** 178/**
179 * sparse_file_block_size
180 *
181 * @s - sparse file cookie
182 */
183unsigned int sparse_file_block_size(struct sparse_file *s);
184
185/**
179 * sparse_file_callback - call a callback for blocks in sparse file 186 * sparse_file_callback - call a callback for blocks in sparse file
180 * 187 *
181 * @s - sparse file cookie 188 * @s - sparse file cookie
@@ -197,6 +204,24 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
197 int (*write)(void *priv, const void *data, int len), void *priv); 204 int (*write)(void *priv, const void *data, int len), void *priv);
198 205
199/** 206/**
207 * sparse_file_foreach_chunk - call a callback for data blocks in sparse file
208 *
209 * @s - sparse file cookie
210 * @sparse - write in the Android sparse file format
211 * @crc - append a crc chunk
212 * @write - function to call for each block
213 * @priv - value that will be passed as the first argument to write
214 *
215 * The function has the same behavior as 'sparse_file_callback', except it only
216 * iterates on blocks that contain data.
217 *
218 * Returns 0 on success, negative errno on error.
219 */
220int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
221 int (*write)(void *priv, const void *data, int len, unsigned int block,
222 unsigned int nr_blocks),
223 void *priv);
224/**
200 * sparse_file_read - read a file into a sparse file cookie 225 * sparse_file_read - read a file into a sparse file cookie
201 * 226 *
202 * @s - sparse file cookie 227 * @s - sparse file cookie
diff --git a/libsparse/sparse.c b/libsparse/sparse.c
index 311678a34..b17586066 100644
--- a/libsparse/sparse.c
+++ b/libsparse/sparse.c
@@ -199,6 +199,57 @@ int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
199 return ret; 199 return ret;
200} 200}
201 201
202struct chunk_data {
203 void *priv;
204 unsigned int block;
205 unsigned int nr_blocks;
206 int (*write)(void *priv, const void *data, int len, unsigned int block,
207 unsigned int nr_blocks);
208};
209
210static int foreach_chunk_write(void *priv, const void *data, int len)
211{
212 struct chunk_data *chk = priv;
213
214 return chk->write(chk->priv, data, len, chk->block, chk->nr_blocks);
215}
216
217int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
218 int (*write)(void *priv, const void *data, int len, unsigned int block,
219 unsigned int nr_blocks),
220 void *priv)
221{
222 int ret;
223 int chunks;
224 struct chunk_data chk;
225 struct output_file *out;
226 struct backed_block *bb;
227
228 chk.priv = priv;
229 chk.write = write;
230 chk.block = chk.nr_blocks = 0;
231 chunks = sparse_count_chunks(s);
232 out = output_file_open_callback(foreach_chunk_write, &chk,
233 s->block_size, s->len, false, sparse,
234 chunks, crc);
235
236 if (!out)
237 return -ENOMEM;
238
239 for (bb = backed_block_iter_new(s->backed_block_list); bb;
240 bb = backed_block_iter_next(bb)) {
241 chk.block = backed_block_block(bb);
242 chk.nr_blocks = (backed_block_len(bb) - 1) / s->block_size + 1;
243 ret = sparse_file_write_block(out, bb);
244 if (ret)
245 return ret;
246 }
247
248 output_file_close(out);
249
250 return ret;
251}
252
202static int out_counter_write(void *priv, const void *data __unused, int len) 253static int out_counter_write(void *priv, const void *data __unused, int len)
203{ 254{
204 int64_t *count = priv; 255 int64_t *count = priv;
@@ -230,6 +281,11 @@ int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc)
230 return count; 281 return count;
231} 282}
232 283
284unsigned int sparse_file_block_size(struct sparse_file *s)
285{
286 return s->block_size;
287}
288
233static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, 289static struct backed_block *move_chunks_up_to_len(struct sparse_file *from,
234 struct sparse_file *to, unsigned int len) 290 struct sparse_file *to, unsigned int len)
235{ 291{