summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'libsparse/sparse.c')
-rw-r--r--libsparse/sparse.c56
1 files changed, 56 insertions, 0 deletions
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{