sparse.h revision 0c4c47f88dfc15cada154a1cf9b4db88b49890f0
165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/*
265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Copyright (C) 2012 The Android Open Source Project
365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Licensed under the Apache License, Version 2.0 (the "License");
565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * you may not use this file except in compliance with the License.
665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * You may obtain a copy of the License at
765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *      http://www.apache.org/licenses/LICENSE-2.0
965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
1065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Unless required by applicable law or agreed to in writing, software
1165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * distributed under the License is distributed on an "AS IS" BASIS,
1265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * See the License for the specific language governing permissions and
1465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * limitations under the License.
1565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
1665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
1765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#ifndef _LIBSPARSE_SPARSE_H_
1865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#define _LIBSPARSE_SPARSE_H_
1965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <stdbool.h>
2165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn#include <stdint.h>
2265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennstruct sparse_file;
2465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
2565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
2665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_new - create a new sparse file cookie
2765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
2865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @block_size - minimum size of a chunk
2965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @len - size of the expanded sparse file.
3065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
3165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Creates a new sparse_file cookie that can be used to associate data
3265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * blocks.  Can later be written to a file with a variety of options.
3365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * block_size specifies the minimum size of a chunk in the file.  The maximum
3465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * size of the file is 2**32 * block_size (16TB for 4k block size).
3565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
3665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Returns the sparse file cookie, or NULL on error.
3765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
3865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennstruct sparse_file *sparse_file_new(unsigned int block_size, int64_t len);
3965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
4065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
4165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_destroy - destroy a sparse file cookie
4265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
4365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @s - sparse file cookie
4465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
4565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Destroys a sparse file cookie.  After destroy, all memory passed in to
4665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_add_data can be freed by the caller
4765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
4865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennvoid sparse_file_destroy(struct sparse_file *s);
4965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
5065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
5165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_add_data - associate a data chunk with a sparse file
5265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
5365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @s - sparse file cookie
5465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @data - pointer to data block
5565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @len - length of the data block
5665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @block - offset in blocks into the sparse file to place the data chunk
5765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
5865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Associates a data chunk with a sparse file cookie.  The region
5965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * [block * block_size : block * block_size + len) must not already be used in
6065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * the sparse file. If len is not a multiple of the block size the data
6165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * will be padded with zeros.
6265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
6365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * The data pointer must remain valid until the sparse file is closed or the
6465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * data block is removed from the sparse file.
6565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
6665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Returns 0 on success, negative errno on error.
6765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
6865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint sparse_file_add_data(struct sparse_file *s,
6965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn		void *data, unsigned int len, unsigned int block);
7065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
7165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
7265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_add_fill - associate a fill chunk with a sparse file
7365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
7465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @s - sparse file cookie
7565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @fill_val - 32 bit fill data
7665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @len - length of the fill block
7765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @block - offset in blocks into the sparse file to place the fill chunk
7865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
7965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Associates a chunk filled with fill_val with a sparse file cookie.
8065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * The region [block * block_size : block * block_size + len) must not already
8165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * be used in the sparse file. If len is not a multiple of the block size the
8265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * data will be padded with zeros.
8365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
8465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Returns 0 on success, negative errno on error.
8565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn */
8665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Rennint sparse_file_add_fill(struct sparse_file *s,
8765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn		uint32_t fill_val, unsigned int len, unsigned int block);
8865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn
8965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn/**
9065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * sparse_file_add_file - associate a chunk of a file with a sparse file
9165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
9265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @s - sparse file cookie
9365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @filename - filename of the file to be copied
9465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @file_offset - offset into the copied file
9565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @len - length of the copied block
9665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * @block - offset in blocks into the sparse file to place the file chunk
9765953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
9865953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Associates a chunk of an existing file with a sparse file cookie.
9965953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * The region [block * block_size : block * block_size + len) must not already
10065953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * be used in the sparse file. If len is not a multiple of the block size the
10165953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * data will be padded with zeros.
10265953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
10365953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * Allows adding large amounts of data to a sparse file without needing to keep
10465953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * it all mapped.  File size is limited by available virtual address space,
10565953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn * exceptionally large files may need to be added in multiple chunks.
10665953da4636fbf5f0a24b8f5f2b5fa7d76ff13d9Marius Renn *
107 * Returns 0 on success, negative errno on error.
108 */
109int sparse_file_add_file(struct sparse_file *s,
110		const char *filename, int64_t file_offset, unsigned int len,
111		unsigned int block);
112
113/**
114 * sparse_file_add_file - associate a chunk of a file with a sparse file
115 *
116 * @s - sparse file cookie
117 * @filename - filename of the file to be copied
118 * @file_offset - offset into the copied file
119 * @len - length of the copied block
120 * @block - offset in blocks into the sparse file to place the file chunk
121 *
122 * Associates a chunk of an existing fd with a sparse file cookie.
123 * The region [block * block_size : block * block_size + len) must not already
124 * be used in the sparse file. If len is not a multiple of the block size the
125 * data will be padded with zeros.
126 *
127 * Allows adding large amounts of data to a sparse file without needing to keep
128 * it all mapped.  File size is limited by available virtual address space,
129 * exceptionally large files may need to be added in multiple chunks.
130 *
131 * The fd must remain open until the sparse file is closed or the fd block is
132 * removed from the sparse file.
133 *
134 * Returns 0 on success, negative errno on error.
135 */
136int sparse_file_add_fd(struct sparse_file *s,
137		int fd, int64_t file_offset, unsigned int len, unsigned int block);
138
139/**
140 * sparse_file_write - write a sparse file to a file
141 *
142 * @s - sparse file cookie
143 * @fd - file descriptor to write to
144 * @gz - write a gzipped file
145 * @sparse - write in the Android sparse file format
146 * @crc - append a crc chunk
147 *
148 * Writes a sparse file to a file.  If gz is true, the data will be passed
149 * through zlib.  If sparse is true, the file will be written in the Android
150 * sparse file format.  If sparse is false, the file will be written by seeking
151 * over unused chunks, producing a smaller file if the filesystem supports
152 * sparse files.  If crc is true, the crc of the expanded data will be
153 * calculated and appended in a crc chunk.
154 *
155 * Returns 0 on success, negative errno on error.
156 */
157int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
158		bool crc);
159
160/**
161 * sparse_file_read - read a file into a sparse file cookie
162 *
163 * @s - sparse file cookie
164 * @fd - file descriptor to read from
165 * @sparse - read a file in the Android sparse file format
166 * @crc - verify the crc of a file in the Android sparse file format
167 *
168 * Reads a file into a sparse file cookie.  If sparse is true, the file is
169 * assumed to be in the Android sparse file format.  If sparse is false, the
170 * file will be sparsed by looking for block aligned chunks of all zeros or
171 * another 32 bit value.  If crc is true, the crc of the sparse file will be
172 * verified.
173 *
174 * Returns 0 on success, negative errno on error.
175 */
176int sparse_file_read(struct sparse_file *s, int fd, bool sparse, bool crc);
177
178/**
179 * sparse_file_import - import an existing sparse file
180 *
181 * @s - sparse file cookie
182 * @verbose - print verbose errors while reading the sparse file
183 * @crc - verify the crc of a file in the Android sparse file format
184 *
185 * Reads an existing sparse file into a sparse file cookie, recreating the same
186 * sparse cookie that was used to write it.  If verbose is true, prints verbose
187 * errors when the sparse file is formatted incorrectly.
188 *
189 * Returns a new sparse file cookie on success, NULL on error.
190 */
191struct sparse_file *sparse_file_import(int fd, bool verbose, bool crc);
192
193/**
194 * sparse_file_import_auto - import an existing sparse or normal file
195 *
196 * @fd - file descriptor to read from
197 * @crc - verify the crc of a file in the Android sparse file format
198 *
199 * Reads an existing sparse or normal file into a sparse file cookie.
200 * Attempts to determine if the file is sparse or not by looking for the sparse
201 * file magic number in the first 4 bytes.  If the file is not sparse, the file
202 * will be sparsed by looking for block aligned chunks of all zeros or another
203 * 32 bit value.  If crc is true, the crc of the sparse file will be verified.
204 *
205 * Returns a new sparse file cookie on success, NULL on error.
206 */
207struct sparse_file *sparse_file_import_auto(int fd, bool crc);
208
209/**
210 * sparse_file_verbose - set a sparse file cookie to print verbose errors
211 *
212 * @s - sparse file cookie
213 *
214 * Print verbose sparse file errors whenever using the sparse file cookie.
215 */
216void sparse_file_verbose(struct sparse_file *s);
217
218/**
219 * sparse_print_verbose - function called to print verbose errors
220 *
221 * By default, verbose errors will print to standard error.
222 * sparse_print_verbose may be overridden to log verbose errors somewhere else.
223 *
224 */
225extern void (*sparse_print_verbose)(const char *fmt, ...);
226
227#endif
228