summaryrefslogtreecommitdiffstats
blob: db06884719d78e8e5b676313d25b1816ea8fb772 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef _LIBSPARSE_SPARSE_H_
#define _LIBSPARSE_SPARSE_H_

#include <stdbool.h>
#include <stdint.h>

struct sparse_file;

/**
 * sparse_file_new - create a new sparse file cookie
 *
 * @block_size - minimum size of a chunk
 * @len - size of the expanded sparse file.
 *
 * Creates a new sparse_file cookie that can be used to associate data
 * blocks.  Can later be written to a file with a variety of options.
 * block_size specifies the minimum size of a chunk in the file.  The maximum
 * size of the file is 2**32 * block_size (16TB for 4k block size).
 *
 * Returns the sparse file cookie, or NULL on error.
 */
struct sparse_file *sparse_file_new(unsigned int block_size, int64_t len);

/**
 * sparse_file_destroy - destroy a sparse file cookie
 *
 * @s - sparse file cookie
 *
 * Destroys a sparse file cookie.  After destroy, all memory passed in to
 * sparse_file_add_data can be freed by the caller
 */
void sparse_file_destroy(struct sparse_file *s);

/**
 * sparse_file_add_data - associate a data chunk with a sparse file
 *
 * @s - sparse file cookie
 * @data - pointer to data block
 * @len - length of the data block
 * @block - offset in blocks into the sparse file to place the data chunk
 *
 * Associates a data chunk with a sparse file cookie.  The region
 * [block * block_size : block * block_size + len) must not already be used in
 * the sparse file. If len is not a multiple of the block size the data
 * will be padded with zeros.
 *
 * The data pointer must remain valid until the sparse file is closed or the
 * data block is removed from the sparse file.
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_data(struct sparse_file *s,
		void *data, unsigned int len, unsigned int block);

/**
 * sparse_file_add_fill - associate a fill chunk with a sparse file
 *
 * @s - sparse file cookie
 * @fill_val - 32 bit fill data
 * @len - length of the fill block
 * @block - offset in blocks into the sparse file to place the fill chunk
 *
 * Associates a chunk filled with fill_val with a sparse file cookie.
 * The region [block * block_size : block * block_size + len) must not already
 * be used in the sparse file. If len is not a multiple of the block size the
 * data will be padded with zeros.
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_fill(struct sparse_file *s,
		uint32_t fill_val, unsigned int len, unsigned int block);

/**
 * sparse_file_add_file - associate a chunk of a file with a sparse file
 *
 * @s - sparse file cookie
 * @filename - filename of the file to be copied
 * @file_offset - offset into the copied file
 * @len - length of the copied block
 * @block - offset in blocks into the sparse file to place the file chunk
 *
 * Associates a chunk of an existing file with a sparse file cookie.
 * The region [block * block_size : block * block_size + len) must not already
 * be used in the sparse file. If len is not a multiple of the block size the
 * data will be padded with zeros.
 *
 * Allows adding large amounts of data to a sparse file without needing to keep
 * it all mapped.  File size is limited by available virtual address space,
 * exceptionally large files may need to be added in multiple chunks.
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_add_file(struct sparse_file *s,
		const char *filename, int64_t file_offset, unsigned int len,
		unsigned int block);

/**
 * sparse_file_write - write a sparse file to a file
 *
 * @s - sparse file cookie
 * @fd - file descriptor to write to
 * @gz - write a gzipped file
 * @sparse - write in the Android sparse file format
 * @crc - append a crc chunk
 *
 * Writes a sparse file to a file.  If gz is true, the data will be passed
 * through zlib.  If sparse is true, the file will be written in the Android
 * sparse file format.  If sparse is false, the file will be written by seeking
 * over unused chunks, producing a smaller file if the filesystem supports
 * sparse files.  If crc is true, the crc of the expanded data will be
 * calculated and appended in a crc chunk.
 *
 * Returns 0 on success, negative errno on error.
 */
int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse,
		bool crc);

#endif