1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef _LIBSPARSE_SPARSE_H_
18 #define _LIBSPARSE_SPARSE_H_
19 
20 #include <stdbool.h>
21 #include <stddef.h>
22 #include <stdint.h>
23 
24 #ifdef	__cplusplus
25 extern "C" {
26 #endif
27 
28 struct sparse_file;
29 
30 // The callbacks in sparse_file_callback() and sparse_file_foreach_chunk() take
31 // size_t as the length type (was `int` in past). This allows clients to keep
32 // their codes compatibile with both versions as needed.
33 #define	SPARSE_CALLBACK_USES_SIZE_T
34 
35 /**
36  * sparse_file_new - create a new sparse file cookie
37  *
38  * @block_size - minimum size of a chunk
39  * @len - size of the expanded sparse file.
40  *
41  * Creates a new sparse_file cookie that can be used to associate data
42  * blocks.  Can later be written to a file with a variety of options.
43  * block_size specifies the minimum size of a chunk in the file.  The maximum
44  * size of the file is 2**32 * block_size (16TB for 4k block size).
45  *
46  * Returns the sparse file cookie, or NULL on error.
47  */
48 struct sparse_file *sparse_file_new(unsigned int block_size, int64_t len);
49 
50 /**
51  * sparse_file_destroy - destroy a sparse file cookie
52  *
53  * @s - sparse file cookie
54  *
55  * Destroys a sparse file cookie.  After destroy, all memory passed in to
56  * sparse_file_add_data can be freed by the caller
57  */
58 void sparse_file_destroy(struct sparse_file *s);
59 
60 /**
61  * sparse_file_add_data - associate a data chunk with a sparse file
62  *
63  * @s - sparse file cookie
64  * @data - pointer to data block
65  * @len - length of the data block
66  * @block - offset in blocks into the sparse file to place the data chunk
67  *
68  * Associates a data chunk with a sparse file cookie.  The region
69  * [block * block_size : block * block_size + len) must not already be used in
70  * the sparse file. If len is not a multiple of the block size the data
71  * will be padded with zeros.
72  *
73  * The data pointer must remain valid until the sparse file is closed or the
74  * data block is removed from the sparse file.
75  *
76  * Returns 0 on success, negative errno on error.
77  */
78 int sparse_file_add_data(struct sparse_file *s,
79 		void *data, unsigned int len, unsigned int block);
80 
81 /**
82  * sparse_file_add_fill - associate a fill chunk with a sparse file
83  *
84  * @s - sparse file cookie
85  * @fill_val - 32 bit fill data
86  * @len - length of the fill block
87  * @block - offset in blocks into the sparse file to place the fill chunk
88  *
89  * Associates a chunk filled with fill_val with a sparse file cookie.
90  * The region [block * block_size : block * block_size + len) must not already
91  * be used in the sparse file. If len is not a multiple of the block size the
92  * data will be padded with zeros.
93  *
94  * Returns 0 on success, negative errno on error.
95  */
96 int sparse_file_add_fill(struct sparse_file *s,
97 		uint32_t fill_val, unsigned int len, unsigned int block);
98 
99 /**
100  * sparse_file_add_file - associate a chunk of a file with a sparse file
101  *
102  * @s - sparse file cookie
103  * @filename - filename of the file to be copied
104  * @file_offset - offset into the copied file
105  * @len - length of the copied block
106  * @block - offset in blocks into the sparse file to place the file chunk
107  *
108  * Associates a chunk of an existing file with a sparse file cookie.
109  * The region [block * block_size : block * block_size + len) must not already
110  * be used in the sparse file. If len is not a multiple of the block size the
111  * data will be padded with zeros.
112  *
113  * Allows adding large amounts of data to a sparse file without needing to keep
114  * it all mapped.  File size is limited by available virtual address space,
115  * exceptionally large files may need to be added in multiple chunks.
116  *
117  * Returns 0 on success, negative errno on error.
118  */
119 int sparse_file_add_file(struct sparse_file *s,
120 		const char *filename, int64_t file_offset, unsigned int len,
121 		unsigned int block);
122 
123 /**
124  * sparse_file_add_file - associate a chunk of a file with a sparse file
125  *
126  * @s - sparse file cookie
127  * @filename - filename of the file to be copied
128  * @file_offset - offset into the copied file
129  * @len - length of the copied block
130  * @block - offset in blocks into the sparse file to place the file chunk
131  *
132  * Associates a chunk of an existing fd with a sparse file cookie.
133  * The region [block * block_size : block * block_size + len) must not already
134  * be used in the sparse file. If len is not a multiple of the block size the
135  * data will be padded with zeros.
136  *
137  * Allows adding large amounts of data to a sparse file without needing to keep
138  * it all mapped.  File size is limited by available virtual address space,
139  * exceptionally large files may need to be added in multiple chunks.
140  *
141  * The fd must remain open until the sparse file is closed or the fd block is
142  * removed from the sparse file.
143  *
144  * Returns 0 on success, negative errno on error.
145  */
146 int sparse_file_add_fd(struct sparse_file *s,
147 		int fd, int64_t file_offset, unsigned int len, unsigned int block);
148 
149 /**
150  * sparse_file_write - write a sparse file to a file
151  *
152  * @s - sparse file cookie
153  * @fd - file descriptor to write to
154  * @gz - write a gzipped file
155  * @sparse - write in the Android sparse file format
156  * @crc - append a crc chunk
157  *
158  * Writes a sparse file to a file.  If gz is true, the data will be passed
159  * through zlib.  If sparse is true, the file will be written in the Android
160  * sparse file format.  If sparse is false, the file will be written by seeking
161  * over unused chunks, producing a smaller file if the filesystem supports
162  * sparse files.  If crc is true, the crc of the expanded data will be
163  * calculated and appended in a crc chunk.
164  *
165  * Returns 0 on success, negative errno on error.
166  */
167 int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
168 		bool crc);
169 
170 /**
171  * sparse_file_len - return the length of a sparse file if written to disk
172  *
173  * @s - sparse file cookie
174  * @sparse - write in the Android sparse file format
175  * @crc - append a crc chunk
176  *
177  * Returns the size a sparse file would be on disk if it were written in the
178  * specified format.  If sparse is true, this is the size of the data in the
179  * sparse format.  If sparse is false, this is the size of the normal
180  * non-sparse file.
181  */
182 int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc);
183 
184 /**
185  * sparse_file_block_size
186  *
187  * @s - sparse file cookie
188  */
189 unsigned int sparse_file_block_size(struct sparse_file *s);
190 
191 /**
192  * sparse_file_callback - call a callback for blocks in sparse file
193  *
194  * @s - sparse file cookie
195  * @sparse - write in the Android sparse file format
196  * @crc - append a crc chunk
197  * @write - function to call for each block
198  * @priv - value that will be passed as the first argument to write
199  *
200  * Writes a sparse file by calling a callback function.  If sparse is true, the
201  * file will be written in the Android sparse file format.  If crc is true, the
202  * crc of the expanded data will be calculated and appended in a crc chunk.
203  * The callback 'write' will be called with data and length for each data,
204  * and with data==NULL to skip over a region (only used for non-sparse format).
205  * The callback should return negative on error, 0 on success.
206  *
207  * Returns 0 on success, negative errno on error.
208  */
209 int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc,
210 		int (*write)(void *priv, const void *data, size_t len), void *priv);
211 
212 /**
213  * sparse_file_foreach_chunk - call a callback for data blocks in sparse file
214  *
215  * @s - sparse file cookie
216  * @sparse - write in the Android sparse file format
217  * @crc - append a crc chunk
218  * @write - function to call for each block
219  * @priv - value that will be passed as the first argument to write
220  *
221  * The function has the same behavior as 'sparse_file_callback', except it only
222  * iterates on blocks that contain data.
223  *
224  * Returns 0 on success, negative errno on error.
225  */
226 int sparse_file_foreach_chunk(struct sparse_file *s, bool sparse, bool crc,
227 	int (*write)(void *priv, const void *data, size_t len, unsigned int block,
228 		     unsigned int nr_blocks),
229 	void *priv);
230 /**
231  * sparse_file_read - read a file into a sparse file cookie
232  *
233  * @s - sparse file cookie
234  * @fd - file descriptor to read from
235  * @sparse - read a file in the Android sparse file format
236  * @crc - verify the crc of a file in the Android sparse file format
237  *
238  * Reads a file into a sparse file cookie.  If sparse is true, the file is
239  * assumed to be in the Android sparse file format.  If sparse is false, the
240  * file will be sparsed by looking for block aligned chunks of all zeros or
241  * another 32 bit value.  If crc is true, the crc of the sparse file will be
242  * verified.
243  *
244  * Returns 0 on success, negative errno on error.
245  */
246 int sparse_file_read(struct sparse_file *s, int fd, bool sparse, bool crc);
247 
248 /**
249  * sparse_file_read_buf - read a buffer into a sparse file cookie
250  *
251  * @s - sparse file cookie
252  * @buf - buffer to read from
253  * @crc - verify the crc of a file in the Android sparse file format
254  *
255  * Reads a buffer into a sparse file cookie. The buffer must remain
256  * valid until the sparse file cookie is freed. If crc is true, the
257  * crc of the sparse file will be verified.
258  *
259  * Returns 0 on success, negative errno on error.
260  */
261 int sparse_file_read_buf(struct sparse_file *s, char *buf, bool crc);
262 
263 /**
264  * sparse_file_import - import an existing sparse file
265  *
266  * @fd - file descriptor to read from
267  * @verbose - print verbose errors while reading the sparse file
268  * @crc - verify the crc of a file in the Android sparse file format
269  *
270  * Reads an existing sparse file into a sparse file cookie, recreating the same
271  * sparse cookie that was used to write it.  If verbose is true, prints verbose
272  * errors when the sparse file is formatted incorrectly.
273  *
274  * Returns a new sparse file cookie on success, NULL on error.
275  */
276 struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc);
277 
278 /**
279  * sparse_file_import_buf - import an existing sparse file from a buffer
280  *
281  * @buf - buffer to read from
282  * @verbose - print verbose errors while reading the sparse file
283  * @crc - verify the crc of a file in the Android sparse file format
284  *
285  * Reads existing sparse file data into a sparse file cookie, recreating the same
286  * sparse cookie that was used to write it.  If verbose is true, prints verbose
287  * errors when the sparse file is formatted incorrectly.
288  *
289  * Returns a new sparse file cookie on success, NULL on error.
290  */
291 struct sparse_file *sparse_file_import_buf(char* buf, bool verbose, bool crc);
292 
293 /**
294  * sparse_file_import_auto - import an existing sparse or normal file
295  *
296  * @fd - file descriptor to read from
297  * @crc - verify the crc of a file in the Android sparse file format
298  * @verbose - whether to use verbose logging
299  *
300  * Reads an existing sparse or normal file into a sparse file cookie.
301  * Attempts to determine if the file is sparse or not by looking for the sparse
302  * file magic number in the first 4 bytes.  If the file is not sparse, the file
303  * will be sparsed by looking for block aligned chunks of all zeros or another
304  * 32 bit value.  If crc is true, the crc of the sparse file will be verified.
305  *
306  * Returns a new sparse file cookie on success, NULL on error.
307  */
308 struct sparse_file *sparse_file_import_auto(int fd, bool crc, bool verbose);
309 
310 /** sparse_file_resparse - rechunk an existing sparse file into smaller files
311  *
312  * @in_s - sparse file cookie of the existing sparse file
313  * @max_len - maximum file size
314  * @out_s - array of sparse file cookies
315  * @out_s_count - size of out_s array
316  *
317  * Splits chunks of an existing sparse file into smaller sparse files such that
318  * each sparse file is less than max_len.  Returns the number of sparse_files
319  * that would have been written to out_s if out_s were big enough.
320  */
321 int sparse_file_resparse(struct sparse_file *in_s, unsigned int max_len,
322 		struct sparse_file **out_s, int out_s_count);
323 
324 /**
325  * sparse_file_verbose - set a sparse file cookie to print verbose errors
326  *
327  * @s - sparse file cookie
328  *
329  * Print verbose sparse file errors whenever using the sparse file cookie.
330  */
331 void sparse_file_verbose(struct sparse_file *s);
332 
333 /**
334  * sparse_print_verbose - function called to print verbose errors
335  *
336  * By default, verbose errors will print to standard error.
337  * sparse_print_verbose may be overridden to log verbose errors somewhere else.
338  *
339  */
340 extern void (*sparse_print_verbose)(const char *fmt, ...);
341 
342 #ifdef	__cplusplus
343 }
344 #endif
345 
346 #endif
347