├── Makefile ├── NOTICE ├── core ├── include │ └── private │ │ ├── android_filesystem_capability.h │ │ └── android_filesystem_config.h └── libsparse │ ├── Makefile │ ├── backed_block.c │ ├── backed_block.h │ ├── defs.h │ ├── img2simg.c │ ├── include │ └── sparse │ │ └── sparse.h │ ├── output_file.c │ ├── output_file.h │ ├── simg2img.c │ ├── simg2simg.c │ ├── sparse.c │ ├── sparse_crc32.c │ ├── sparse_crc32.h │ ├── sparse_defs.h │ ├── sparse_err.c │ ├── sparse_file.h │ ├── sparse_format.h │ └── sparse_read.c ├── extras └── ext4_utils │ ├── Makefile │ ├── allocate.c │ ├── allocate.h │ ├── canned_fs_config.c │ ├── canned_fs_config.h │ ├── contents.c │ ├── contents.h │ ├── crc16.c │ ├── ext4.h │ ├── ext4_extents.h │ ├── ext4_kernel_headers.h │ ├── ext4_sb.c │ ├── ext4_sb.h │ ├── ext4_utils.c │ ├── ext4_utils.h │ ├── ext4fixup.c │ ├── ext4fixup.h │ ├── ext4fixup_main.c │ ├── extent.c │ ├── extent.h │ ├── indirect.c │ ├── indirect.h │ ├── jbd2.h │ ├── make_ext4fs.c │ ├── make_ext4fs.h │ ├── make_ext4fs_main.c │ ├── sha1.c │ ├── sha1.h │ ├── uuid.c │ ├── uuid.h │ ├── wipe.c │ ├── wipe.h │ └── xattr.h ├── libselinux ├── include │ └── selinux │ │ ├── android.h │ │ ├── avc.h │ │ ├── context.h │ │ ├── label.h │ │ └── selinux.h └── src │ ├── Makefile │ ├── callbacks.c │ ├── callbacks.h │ ├── check_context.c │ ├── dso.h │ ├── freecon.c │ ├── init.c │ ├── label.c │ ├── label_android_property.c │ ├── label_file.c │ ├── label_internal.h │ ├── policy.h │ └── selinux_internal.h └── zlib └── src ├── Makefile ├── adler32.c ├── compress.c ├── crc32.c ├── crc32.h ├── deflate.c ├── deflate.h ├── gzclose.c ├── gzguts.h ├── gzlib.c ├── gzread.c ├── gzwrite.c ├── infback.c ├── inffast.c ├── inffast.h ├── inffixed.h ├── inflate.c ├── inflate.h ├── inftrees.c ├── inftrees.h ├── trees.c ├── trees.h ├── uncompr.c ├── zconf.h ├── zlib.h ├── zutil.c └── zutil.h /Makefile: -------------------------------------------------------------------------------- 1 | SELIB = libselinux 2 | ZLLIB = zlib/src 3 | SPLIB = core/libsparse 4 | COLIB = core 5 | MALIB = extras/ext4_utils 6 | 7 | all: 8 | $(MAKE) -C $(SELIB)/src all 9 | $(MAKE) -C $(ZLLIB) all 10 | $(MAKE) -C $(SPLIB) libsparse.a 11 | $(MAKE) -C $(MALIB) all 12 | mv $(MALIB)/make_ext4fs make_ext4fs 13 | 14 | clean: 15 | $(MAKE) -C $(SELIB)/src clean 16 | $(MAKE) -C $(ZLLIB) clean 17 | $(MAKE) -C $(SPLIB) clean 18 | $(MAKE) -C $(MALIB) clean 19 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Copyright 2008, The Android Open Source Project 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | * Redistributions of source code must retain the above copyright 6 | notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright 8 | notice, this list of conditions and the following disclaimer in the 9 | documentation and/or other materials provided with the distribution. 10 | * Neither the name of Google Inc. nor the names of its contributors may 11 | be used to endorse or promote products derived from this software 12 | without specific prior written permission. 13 | 14 | THIS SOFTWARE IS PROVIDED BY Google Inc. ``AS IS'' AND ANY EXPRESS OR 15 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 17 | EVENT SHALL Google Inc. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 18 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 20 | OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 21 | WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 22 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 23 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | -------------------------------------------------------------------------------- /core/include/private/android_filesystem_capability.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2013 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 | /* 18 | * Taken from linux/capability.h, with minor modifications 19 | */ 20 | 21 | #ifndef _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_FILESYSTEM_CAPABILITY_H 22 | #define _SYSTEM_CORE_INCLUDE_PRIVATE_ANDROID_FILESYSTEM_CAPABILITY_H 23 | 24 | #include 25 | 26 | #define __user 27 | #define __u32 uint32_t 28 | #define __le32 uint32_t 29 | 30 | #define _LINUX_CAPABILITY_VERSION_1 0x19980330 31 | #define _LINUX_CAPABILITY_U32S_1 1 32 | #define _LINUX_CAPABILITY_VERSION_2 0x20071026 33 | #define _LINUX_CAPABILITY_U32S_2 2 34 | #define _LINUX_CAPABILITY_VERSION_3 0x20080522 35 | #define _LINUX_CAPABILITY_U32S_3 2 36 | 37 | typedef struct __user_cap_header_struct { 38 | __u32 version; 39 | int pid; 40 | } __user *cap_user_header_t; 41 | 42 | typedef struct __user_cap_data_struct { 43 | __u32 effective; 44 | __u32 permitted; 45 | __u32 inheritable; 46 | } __user *cap_user_data_t; 47 | 48 | #define VFS_CAP_REVISION_MASK 0xFF000000 49 | #define VFS_CAP_REVISION_SHIFT 24 50 | #define VFS_CAP_FLAGS_MASK ~VFS_CAP_REVISION_MASK 51 | #define VFS_CAP_FLAGS_EFFECTIVE 0x000001 52 | #define VFS_CAP_REVISION_1 0x01000000 53 | #define VFS_CAP_U32_1 1 54 | #define XATTR_CAPS_SZ_1 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_1)) 55 | #define VFS_CAP_REVISION_2 0x02000000 56 | #define VFS_CAP_U32_2 2 57 | #define XATTR_CAPS_SZ_2 (sizeof(__le32)*(1 + 2*VFS_CAP_U32_2)) 58 | #define XATTR_CAPS_SZ XATTR_CAPS_SZ_2 59 | #define VFS_CAP_U32 VFS_CAP_U32_2 60 | #define VFS_CAP_REVISION VFS_CAP_REVISION_2 61 | 62 | struct vfs_cap_data { 63 | __le32 magic_etc; 64 | struct { 65 | __le32 permitted; 66 | __le32 inheritable; 67 | } data[VFS_CAP_U32]; 68 | }; 69 | 70 | #define _LINUX_CAPABILITY_VERSION _LINUX_CAPABILITY_VERSION_1 71 | #define _LINUX_CAPABILITY_U32S _LINUX_CAPABILITY_U32S_1 72 | #define CAP_CHOWN 0 73 | #define CAP_DAC_OVERRIDE 1 74 | #define CAP_DAC_READ_SEARCH 2 75 | #define CAP_FOWNER 3 76 | #define CAP_FSETID 4 77 | #define CAP_KILL 5 78 | #define CAP_SETGID 6 79 | #define CAP_SETUID 7 80 | #define CAP_SETPCAP 8 81 | #define CAP_LINUX_IMMUTABLE 9 82 | #define CAP_NET_BIND_SERVICE 10 83 | #define CAP_NET_BROADCAST 11 84 | #define CAP_NET_ADMIN 12 85 | #define CAP_NET_RAW 13 86 | #define CAP_IPC_LOCK 14 87 | #define CAP_IPC_OWNER 15 88 | #define CAP_SYS_MODULE 16 89 | #define CAP_SYS_RAWIO 17 90 | #define CAP_SYS_CHROOT 18 91 | #define CAP_SYS_PTRACE 19 92 | #define CAP_SYS_PACCT 20 93 | #define CAP_SYS_ADMIN 21 94 | #define CAP_SYS_BOOT 22 95 | #define CAP_SYS_NICE 23 96 | #define CAP_SYS_RESOURCE 24 97 | #define CAP_SYS_TIME 25 98 | #define CAP_SYS_TTY_CONFIG 26 99 | #define CAP_MKNOD 27 100 | #define CAP_LEASE 28 101 | #define CAP_AUDIT_WRITE 29 102 | #define CAP_AUDIT_CONTROL 30 103 | #define CAP_SETFCAP 31 104 | #define CAP_MAC_OVERRIDE 32 105 | #define CAP_MAC_ADMIN 33 106 | #define CAP_SYSLOG 34 107 | #define CAP_WAKE_ALARM 35 108 | #define CAP_BLOCK_SUSPEND 36 109 | #define CAP_AUDIT_READ 37 110 | #define CAP_LAST_CAP CAP_WAKE_ALARM 111 | #define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP) 112 | #define CAP_TO_INDEX(x) ((x) >> 5) 113 | #define CAP_TO_MASK(x) (1 << ((x) & 31)) 114 | 115 | #undef __user 116 | #undef __u32 117 | #undef __le32 118 | 119 | #endif 120 | -------------------------------------------------------------------------------- /core/libsparse/Makefile: -------------------------------------------------------------------------------- 1 | ZLLIB = ../../zlib/src 2 | AR = ar rcs 3 | OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) 4 | 5 | all:libsparse.a simg2img 6 | 7 | libsparse.a: 8 | gcc -Iinclude -c backed_block.c output_file.c sparse.c sparse_crc32.c sparse_err.c sparse_read.c; 9 | $(AR) libsparse.a *.o 10 | 11 | simg2img: 12 | gcc -Iinclude -I$(ZLLIB) -o simg2img simg2img.c sparse_crc32.c libsparse.a $(ZLLIB)/libz.a 13 | 14 | img2simg: 15 | gcc -Iinclude -I$(ZLLIB) -o img2simg img2simg.c sparse_crc32.c libsparse.a $(ZLLIB)/libz.a 16 | 17 | clean: 18 | rm -f $(OBJS) 19 | rm -f libsparse.a 20 | rm -f simg2img 21 | 22 | -------------------------------------------------------------------------------- /core/libsparse/backed_block.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "backed_block.h" 24 | #include "sparse_defs.h" 25 | 26 | struct backed_block { 27 | unsigned int block; 28 | unsigned int len; 29 | enum backed_block_type type; 30 | union { 31 | struct { 32 | void *data; 33 | } data; 34 | struct { 35 | char *filename; 36 | int64_t offset; 37 | } file; 38 | struct { 39 | int fd; 40 | int64_t offset; 41 | } fd; 42 | struct { 43 | uint32_t val; 44 | } fill; 45 | }; 46 | struct backed_block *next; 47 | }; 48 | 49 | struct backed_block_list { 50 | struct backed_block *data_blocks; 51 | struct backed_block *last_used; 52 | unsigned int block_size; 53 | }; 54 | 55 | struct backed_block *backed_block_iter_new(struct backed_block_list *bbl) 56 | { 57 | return bbl->data_blocks; 58 | } 59 | 60 | struct backed_block *backed_block_iter_next(struct backed_block *bb) 61 | { 62 | return bb->next; 63 | } 64 | 65 | unsigned int backed_block_len(struct backed_block *bb) 66 | { 67 | return bb->len; 68 | } 69 | 70 | unsigned int backed_block_block(struct backed_block *bb) 71 | { 72 | return bb->block; 73 | } 74 | 75 | void *backed_block_data(struct backed_block *bb) 76 | { 77 | assert(bb->type == BACKED_BLOCK_DATA); 78 | return bb->data.data; 79 | } 80 | 81 | const char *backed_block_filename(struct backed_block *bb) 82 | { 83 | assert(bb->type == BACKED_BLOCK_FILE); 84 | return bb->file.filename; 85 | } 86 | 87 | int backed_block_fd(struct backed_block *bb) 88 | { 89 | assert(bb->type == BACKED_BLOCK_FD); 90 | return bb->fd.fd; 91 | } 92 | 93 | int64_t backed_block_file_offset(struct backed_block *bb) 94 | { 95 | assert(bb->type == BACKED_BLOCK_FILE || bb->type == BACKED_BLOCK_FD); 96 | if (bb->type == BACKED_BLOCK_FILE) { 97 | return bb->file.offset; 98 | } else { /* bb->type == BACKED_BLOCK_FD */ 99 | return bb->fd.offset; 100 | } 101 | } 102 | 103 | uint32_t backed_block_fill_val(struct backed_block *bb) 104 | { 105 | assert(bb->type == BACKED_BLOCK_FILL); 106 | return bb->fill.val; 107 | } 108 | 109 | enum backed_block_type backed_block_type(struct backed_block *bb) 110 | { 111 | return bb->type; 112 | } 113 | 114 | void backed_block_destroy(struct backed_block *bb) 115 | { 116 | if (bb->type == BACKED_BLOCK_FILE) { 117 | free(bb->file.filename); 118 | } 119 | 120 | free(bb); 121 | } 122 | 123 | struct backed_block_list *backed_block_list_new(unsigned int block_size) 124 | { 125 | struct backed_block_list *b = calloc(sizeof(struct backed_block_list), 1); 126 | b->block_size = block_size; 127 | return b; 128 | } 129 | 130 | void backed_block_list_destroy(struct backed_block_list *bbl) 131 | { 132 | if (bbl->data_blocks) { 133 | struct backed_block *bb = bbl->data_blocks; 134 | while (bb) { 135 | struct backed_block *next = bb->next; 136 | backed_block_destroy(bb); 137 | bb = next; 138 | } 139 | } 140 | 141 | free(bbl); 142 | } 143 | 144 | void backed_block_list_move(struct backed_block_list *from, 145 | struct backed_block_list *to, struct backed_block *start, 146 | struct backed_block *end) 147 | { 148 | struct backed_block *bb; 149 | 150 | if (start == NULL) { 151 | start = from->data_blocks; 152 | } 153 | 154 | if (!end) { 155 | for (end = start; end && end->next; end = end->next) 156 | ; 157 | } 158 | 159 | if (start == NULL || end == NULL) { 160 | return; 161 | } 162 | 163 | from->last_used = NULL; 164 | to->last_used = NULL; 165 | if (from->data_blocks == start) { 166 | from->data_blocks = end->next; 167 | } else { 168 | for (bb = from->data_blocks; bb; bb = bb->next) { 169 | if (bb->next == start) { 170 | bb->next = end->next; 171 | break; 172 | } 173 | } 174 | } 175 | 176 | if (!to->data_blocks) { 177 | to->data_blocks = start; 178 | end->next = NULL; 179 | } else { 180 | for (bb = to->data_blocks; bb; bb = bb->next) { 181 | if (!bb->next || bb->next->block > start->block) { 182 | end->next = bb->next; 183 | bb->next = start; 184 | break; 185 | } 186 | } 187 | } 188 | } 189 | 190 | /* may free b */ 191 | static int merge_bb(struct backed_block_list *bbl, 192 | struct backed_block *a, struct backed_block *b) 193 | { 194 | unsigned int block_len; 195 | 196 | /* Block doesn't exist (possible if one block is the last block) */ 197 | if (!a || !b) { 198 | return -EINVAL; 199 | } 200 | 201 | assert(a->block < b->block); 202 | 203 | /* Blocks are of different types */ 204 | if (a->type != b->type) { 205 | return -EINVAL; 206 | } 207 | 208 | /* Blocks are not adjacent */ 209 | block_len = a->len / bbl->block_size; /* rounds down */ 210 | if (a->block + block_len != b->block) { 211 | return -EINVAL; 212 | } 213 | 214 | switch (a->type) { 215 | case BACKED_BLOCK_DATA: 216 | /* Don't support merging data for now */ 217 | return -EINVAL; 218 | case BACKED_BLOCK_FILL: 219 | if (a->fill.val != b->fill.val) { 220 | return -EINVAL; 221 | } 222 | break; 223 | case BACKED_BLOCK_FILE: 224 | if (a->file.filename != b->file.filename || 225 | a->file.offset + a->len != b->file.offset) { 226 | return -EINVAL; 227 | } 228 | break; 229 | case BACKED_BLOCK_FD: 230 | if (a->fd.fd != b->fd.fd || 231 | a->fd.offset + a->len != b->fd.offset) { 232 | return -EINVAL; 233 | } 234 | break; 235 | } 236 | 237 | /* Blocks are compatible and adjacent, with a before b. Merge b into a, 238 | * and free b */ 239 | a->len += b->len; 240 | a->next = b->next; 241 | 242 | backed_block_destroy(b); 243 | 244 | return 0; 245 | } 246 | 247 | static int queue_bb(struct backed_block_list *bbl, struct backed_block *new_bb) 248 | { 249 | struct backed_block *bb; 250 | 251 | if (bbl->data_blocks == NULL) { 252 | bbl->data_blocks = new_bb; 253 | return 0; 254 | } 255 | 256 | if (bbl->data_blocks->block > new_bb->block) { 257 | new_bb->next = bbl->data_blocks; 258 | bbl->data_blocks = new_bb; 259 | return 0; 260 | } 261 | 262 | /* Optimization: blocks are mostly queued in sequence, so save the 263 | pointer to the last bb that was added, and start searching from 264 | there if the next block number is higher */ 265 | if (bbl->last_used && new_bb->block > bbl->last_used->block) 266 | bb = bbl->last_used; 267 | else 268 | bb = bbl->data_blocks; 269 | bbl->last_used = new_bb; 270 | 271 | for (; bb->next && bb->next->block < new_bb->block; bb = bb->next) 272 | ; 273 | 274 | if (bb->next == NULL) { 275 | bb->next = new_bb; 276 | } else { 277 | new_bb->next = bb->next; 278 | bb->next = new_bb; 279 | } 280 | 281 | merge_bb(bbl, new_bb, new_bb->next); 282 | merge_bb(bbl, bb, new_bb); 283 | 284 | return 0; 285 | } 286 | 287 | /* Queues a fill block of memory to be written to the specified data blocks */ 288 | int backed_block_add_fill(struct backed_block_list *bbl, unsigned int fill_val, 289 | unsigned int len, unsigned int block) 290 | { 291 | struct backed_block *bb = calloc(1, sizeof(struct backed_block)); 292 | if (bb == NULL) { 293 | return -ENOMEM; 294 | } 295 | 296 | bb->block = block; 297 | bb->len = len; 298 | bb->type = BACKED_BLOCK_FILL; 299 | bb->fill.val = fill_val; 300 | bb->next = NULL; 301 | 302 | return queue_bb(bbl, bb); 303 | } 304 | 305 | /* Queues a block of memory to be written to the specified data blocks */ 306 | int backed_block_add_data(struct backed_block_list *bbl, void *data, 307 | unsigned int len, unsigned int block) 308 | { 309 | struct backed_block *bb = calloc(1, sizeof(struct backed_block)); 310 | if (bb == NULL) { 311 | return -ENOMEM; 312 | } 313 | 314 | bb->block = block; 315 | bb->len = len; 316 | bb->type = BACKED_BLOCK_DATA; 317 | bb->data.data = data; 318 | bb->next = NULL; 319 | 320 | return queue_bb(bbl, bb); 321 | } 322 | 323 | /* Queues a chunk of a file on disk to be written to the specified data blocks */ 324 | int backed_block_add_file(struct backed_block_list *bbl, const char *filename, 325 | int64_t offset, unsigned int len, unsigned int block) 326 | { 327 | struct backed_block *bb = calloc(1, sizeof(struct backed_block)); 328 | if (bb == NULL) { 329 | return -ENOMEM; 330 | } 331 | 332 | bb->block = block; 333 | bb->len = len; 334 | bb->type = BACKED_BLOCK_FILE; 335 | bb->file.filename = strdup(filename); 336 | bb->file.offset = offset; 337 | bb->next = NULL; 338 | 339 | return queue_bb(bbl, bb); 340 | } 341 | 342 | /* Queues a chunk of a fd to be written to the specified data blocks */ 343 | int backed_block_add_fd(struct backed_block_list *bbl, int fd, int64_t offset, 344 | unsigned int len, unsigned int block) 345 | { 346 | struct backed_block *bb = calloc(1, sizeof(struct backed_block)); 347 | if (bb == NULL) { 348 | return -ENOMEM; 349 | } 350 | 351 | bb->block = block; 352 | bb->len = len; 353 | bb->type = BACKED_BLOCK_FD; 354 | bb->fd.fd = fd; 355 | bb->fd.offset = offset; 356 | bb->next = NULL; 357 | 358 | return queue_bb(bbl, bb); 359 | } 360 | 361 | int backed_block_split(struct backed_block_list *bbl, struct backed_block *bb, 362 | unsigned int max_len) 363 | { 364 | struct backed_block *new_bb; 365 | 366 | max_len = ALIGN_DOWN(max_len, bbl->block_size); 367 | 368 | if (bb->len <= max_len) { 369 | return 0; 370 | } 371 | 372 | new_bb = malloc(sizeof(struct backed_block)); 373 | if (new_bb == NULL) { 374 | return -ENOMEM; 375 | } 376 | 377 | *new_bb = *bb; 378 | 379 | new_bb->len = bb->len - max_len; 380 | new_bb->block = bb->block + max_len / bbl->block_size; 381 | new_bb->next = bb->next; 382 | bb->next = new_bb; 383 | bb->len = max_len; 384 | 385 | switch (bb->type) { 386 | case BACKED_BLOCK_DATA: 387 | new_bb->data.data = (char *)bb->data.data + max_len; 388 | break; 389 | case BACKED_BLOCK_FILE: 390 | new_bb->file.offset += max_len; 391 | break; 392 | case BACKED_BLOCK_FD: 393 | new_bb->fd.offset += max_len; 394 | break; 395 | case BACKED_BLOCK_FILL: 396 | break; 397 | } 398 | 399 | return 0; 400 | } 401 | -------------------------------------------------------------------------------- /core/libsparse/backed_block.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _BACKED_BLOCK_H_ 18 | #define _BACKED_BLOCK_H_ 19 | 20 | #include 21 | 22 | struct backed_block_list; 23 | struct backed_block; 24 | 25 | enum backed_block_type { 26 | BACKED_BLOCK_DATA, 27 | BACKED_BLOCK_FILE, 28 | BACKED_BLOCK_FD, 29 | BACKED_BLOCK_FILL, 30 | }; 31 | 32 | int backed_block_add_data(struct backed_block_list *bbl, void *data, 33 | unsigned int len, unsigned int block); 34 | int backed_block_add_fill(struct backed_block_list *bbl, unsigned int fill_val, 35 | unsigned int len, unsigned int block); 36 | int backed_block_add_file(struct backed_block_list *bbl, const char *filename, 37 | int64_t offset, unsigned int len, unsigned int block); 38 | int backed_block_add_fd(struct backed_block_list *bbl, int fd, 39 | int64_t offset, unsigned int len, unsigned int block); 40 | 41 | struct backed_block *backed_block_iter_new(struct backed_block_list *bbl); 42 | struct backed_block *backed_block_iter_next(struct backed_block *bb); 43 | unsigned int backed_block_len(struct backed_block *bb); 44 | unsigned int backed_block_block(struct backed_block *bb); 45 | void *backed_block_data(struct backed_block *bb); 46 | const char *backed_block_filename(struct backed_block *bb); 47 | int backed_block_fd(struct backed_block *bb); 48 | int64_t backed_block_file_offset(struct backed_block *bb); 49 | uint32_t backed_block_fill_val(struct backed_block *bb); 50 | enum backed_block_type backed_block_type(struct backed_block *bb); 51 | int backed_block_split(struct backed_block_list *bbl, struct backed_block *bb, 52 | unsigned int max_len); 53 | 54 | struct backed_block *backed_block_iter_new(struct backed_block_list *bbl); 55 | struct backed_block *backed_block_iter_next(struct backed_block *bb); 56 | 57 | struct backed_block_list *backed_block_list_new(unsigned int block_size); 58 | void backed_block_list_destroy(struct backed_block_list *bbl); 59 | 60 | void backed_block_list_move(struct backed_block_list *from, 61 | struct backed_block_list *to, struct backed_block *start, 62 | struct backed_block *end); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /core/libsparse/defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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_DEFS_H_ 18 | 19 | #ifndef __unused 20 | #define __unused __attribute__((__unused__)) 21 | #endif 22 | 23 | #endif /* _LIBSPARSE_DEFS_H_ */ 24 | -------------------------------------------------------------------------------- /core/libsparse/img2simg.c: -------------------------------------------------------------------------------- 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 | #define _FILE_OFFSET_BITS 64 18 | #define _LARGEFILE64_SOURCE 1 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include 31 | 32 | #ifndef O_BINARY 33 | #define O_BINARY 0 34 | #endif 35 | 36 | #if defined(__CYGWIN__) || defined(__APPLE__) && defined(__MACH__) 37 | #define lseek64 lseek 38 | #define off64_t off_t 39 | #endif 40 | 41 | void usage() 42 | { 43 | fprintf(stderr, "Usage: img2simg []\n"); 44 | } 45 | 46 | int main(int argc, char *argv[]) 47 | { 48 | int in; 49 | int out; 50 | int ret; 51 | struct sparse_file *s; 52 | unsigned int block_size = 4096; 53 | off64_t len; 54 | 55 | if (argc < 3 || argc > 4) { 56 | usage(); 57 | exit(-1); 58 | } 59 | 60 | if (argc == 4) { 61 | block_size = atoi(argv[3]); 62 | } 63 | 64 | if (block_size < 1024 || block_size % 4 != 0) { 65 | usage(); 66 | exit(-1); 67 | } 68 | 69 | if (strcmp(argv[1], "-") == 0) { 70 | in = STDIN_FILENO; 71 | } else { 72 | in = open(argv[1], O_RDONLY | O_BINARY); 73 | if (in < 0) { 74 | fprintf(stderr, "Cannot open input file %s\n", argv[1]); 75 | exit(-1); 76 | } 77 | } 78 | 79 | if (strcmp(argv[2], "-") == 0) { 80 | out = STDOUT_FILENO; 81 | } else { 82 | out = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 83 | if (out < 0) { 84 | fprintf(stderr, "Cannot open output file %s\n", argv[2]); 85 | exit(-1); 86 | } 87 | } 88 | 89 | len = lseek64(in, 0, SEEK_END); 90 | lseek64(in, 0, SEEK_SET); 91 | 92 | s = sparse_file_new(block_size, len); 93 | if (!s) { 94 | fprintf(stderr, "Failed to create sparse file\n"); 95 | exit(-1); 96 | } 97 | 98 | sparse_file_verbose(s); 99 | ret = sparse_file_read(s, in, false, false); 100 | if (ret) { 101 | fprintf(stderr, "Failed to read file\n"); 102 | exit(-1); 103 | } 104 | 105 | ret = sparse_file_write(s, out, false, true, false); 106 | if (ret) { 107 | fprintf(stderr, "Failed to write sparse file\n"); 108 | exit(-1); 109 | } 110 | 111 | close(in); 112 | close(out); 113 | 114 | exit(0); 115 | } 116 | -------------------------------------------------------------------------------- /core/libsparse/output_file.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _OUTPUT_FILE_H_ 18 | #define _OUTPUT_FILE_H_ 19 | 20 | #include 21 | 22 | struct output_file; 23 | 24 | struct output_file *output_file_open_fd(int fd, unsigned int block_size, int64_t len, 25 | int gz, int sparse, int chunks, int crc); 26 | struct output_file *output_file_open_callback(int (*write)(void *, const void *, int), 27 | void *priv, unsigned int block_size, int64_t len, int gz, int sparse, 28 | int chunks, int crc); 29 | int write_data_chunk(struct output_file *out, unsigned int len, void *data); 30 | int write_fill_chunk(struct output_file *out, unsigned int len, 31 | uint32_t fill_val); 32 | int write_file_chunk(struct output_file *out, unsigned int len, 33 | const char *file, int64_t offset); 34 | int write_fd_chunk(struct output_file *out, unsigned int len, 35 | int fd, int64_t offset); 36 | int write_skip_chunk(struct output_file *out, int64_t len); 37 | void output_file_close(struct output_file *out); 38 | 39 | int read_all(int fd, void *buf, size_t len); 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /core/libsparse/simg2img.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | 29 | #ifndef O_BINARY 30 | #define O_BINARY 0 31 | #endif 32 | 33 | void usage() 34 | { 35 | fprintf(stderr, "Usage: simg2img \n"); 36 | } 37 | 38 | int main(int argc, char *argv[]) 39 | { 40 | int in; 41 | int out; 42 | int i; 43 | int ret; 44 | struct sparse_file *s; 45 | 46 | if (argc < 3) { 47 | usage(); 48 | exit(-1); 49 | } 50 | 51 | out = open(argv[argc - 1], O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 52 | if (out < 0) { 53 | fprintf(stderr, "Cannot open output file %s\n", argv[argc - 1]); 54 | exit(-1); 55 | } 56 | 57 | for (i = 1; i < argc - 1; i++) { 58 | if (strcmp(argv[i], "-") == 0) { 59 | in = STDIN_FILENO; 60 | } else { 61 | in = open(argv[i], O_RDONLY | O_BINARY); 62 | if (in < 0) { 63 | fprintf(stderr, "Cannot open input file %s\n", argv[i]); 64 | exit(-1); 65 | } 66 | } 67 | 68 | s = sparse_file_import(in, true, false); 69 | if (!s) { 70 | fprintf(stderr, "Failed to read sparse file\n"); 71 | exit(-1); 72 | } 73 | 74 | lseek(out, SEEK_SET, 0); 75 | 76 | ret = sparse_file_write(s, out, false, false, false); 77 | if (ret < 0) { 78 | fprintf(stderr, "Cannot write output file\n"); 79 | exit(-1); 80 | } 81 | sparse_file_destroy(s); 82 | close(in); 83 | } 84 | 85 | close(out); 86 | 87 | exit(0); 88 | } 89 | 90 | -------------------------------------------------------------------------------- /core/libsparse/simg2simg.c: -------------------------------------------------------------------------------- 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 | #define _FILE_OFFSET_BITS 64 18 | #define _LARGEFILE64_SOURCE 1 19 | #define _GNU_SOURCE 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include 32 | 33 | #ifndef O_BINARY 34 | #define O_BINARY 0 35 | #endif 36 | 37 | void usage() 38 | { 39 | fprintf(stderr, "Usage: simg2simg \n"); 40 | } 41 | 42 | int main(int argc, char *argv[]) 43 | { 44 | int in; 45 | int out; 46 | int i; 47 | int ret; 48 | struct sparse_file *s; 49 | int64_t max_size; 50 | struct sparse_file **out_s; 51 | int files; 52 | char filename[4096]; 53 | 54 | if (argc != 4) { 55 | usage(); 56 | exit(-1); 57 | } 58 | 59 | max_size = atoll(argv[3]); 60 | 61 | in = open(argv[1], O_RDONLY | O_BINARY); 62 | if (in < 0) { 63 | fprintf(stderr, "Cannot open input file %s\n", argv[1]); 64 | exit(-1); 65 | } 66 | 67 | s = sparse_file_import(in, true, false); 68 | if (!s) { 69 | fprintf(stderr, "Failed to import sparse file\n"); 70 | exit(-1); 71 | } 72 | 73 | files = sparse_file_resparse(s, max_size, NULL, 0); 74 | if (files < 0) { 75 | fprintf(stderr, "Failed to resparse\n"); 76 | exit(-1); 77 | } 78 | 79 | out_s = calloc(sizeof(struct sparse_file *), files); 80 | if (!out_s) { 81 | fprintf(stderr, "Failed to allocate sparse file array\n"); 82 | exit(-1); 83 | } 84 | 85 | files = sparse_file_resparse(s, max_size, out_s, files); 86 | if (files < 0) { 87 | fprintf(stderr, "Failed to resparse\n"); 88 | exit(-1); 89 | } 90 | 91 | for (i = 0; i < files; i++) { 92 | ret = snprintf(filename, sizeof(filename), "%s.%d", argv[2], i); 93 | if (ret >= (int)sizeof(filename)) { 94 | fprintf(stderr, "Filename too long\n"); 95 | exit(-1); 96 | } 97 | 98 | out = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0664); 99 | if (out < 0) { 100 | fprintf(stderr, "Cannot open output file %s\n", argv[2]); 101 | exit(-1); 102 | } 103 | 104 | ret = sparse_file_write(out_s[i], out, false, true, false); 105 | if (ret) { 106 | fprintf(stderr, "Failed to write sparse file\n"); 107 | exit(-1); 108 | } 109 | close(out); 110 | } 111 | 112 | close(in); 113 | 114 | exit(0); 115 | } 116 | -------------------------------------------------------------------------------- /core/libsparse/sparse.c: -------------------------------------------------------------------------------- 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 | #include 18 | #include 19 | 20 | #include 21 | 22 | #include "defs.h" 23 | #include "sparse_file.h" 24 | 25 | #include "output_file.h" 26 | #include "backed_block.h" 27 | #include "sparse_defs.h" 28 | #include "sparse_format.h" 29 | 30 | struct sparse_file *sparse_file_new(unsigned int block_size, int64_t len) 31 | { 32 | struct sparse_file *s = calloc(sizeof(struct sparse_file), 1); 33 | if (!s) { 34 | return NULL; 35 | } 36 | 37 | s->backed_block_list = backed_block_list_new(block_size); 38 | if (!s->backed_block_list) { 39 | free(s); 40 | return NULL; 41 | } 42 | 43 | s->block_size = block_size; 44 | s->len = len; 45 | 46 | return s; 47 | } 48 | 49 | void sparse_file_destroy(struct sparse_file *s) 50 | { 51 | backed_block_list_destroy(s->backed_block_list); 52 | free(s); 53 | } 54 | 55 | int sparse_file_add_data(struct sparse_file *s, 56 | void *data, unsigned int len, unsigned int block) 57 | { 58 | return backed_block_add_data(s->backed_block_list, data, len, block); 59 | } 60 | 61 | int sparse_file_add_fill(struct sparse_file *s, 62 | uint32_t fill_val, unsigned int len, unsigned int block) 63 | { 64 | return backed_block_add_fill(s->backed_block_list, fill_val, len, block); 65 | } 66 | 67 | int sparse_file_add_file(struct sparse_file *s, 68 | const char *filename, int64_t file_offset, unsigned int len, 69 | unsigned int block) 70 | { 71 | return backed_block_add_file(s->backed_block_list, filename, file_offset, 72 | len, block); 73 | } 74 | 75 | int sparse_file_add_fd(struct sparse_file *s, 76 | int fd, int64_t file_offset, unsigned int len, unsigned int block) 77 | { 78 | return backed_block_add_fd(s->backed_block_list, fd, file_offset, 79 | len, block); 80 | } 81 | unsigned int sparse_count_chunks(struct sparse_file *s) 82 | { 83 | struct backed_block *bb; 84 | unsigned int last_block = 0; 85 | unsigned int chunks = 0; 86 | 87 | for (bb = backed_block_iter_new(s->backed_block_list); bb; 88 | bb = backed_block_iter_next(bb)) { 89 | if (backed_block_block(bb) > last_block) { 90 | /* If there is a gap between chunks, add a skip chunk */ 91 | chunks++; 92 | } 93 | chunks++; 94 | last_block = backed_block_block(bb) + 95 | DIV_ROUND_UP(backed_block_len(bb), s->block_size); 96 | } 97 | if (last_block < DIV_ROUND_UP(s->len, s->block_size)) { 98 | chunks++; 99 | } 100 | 101 | return chunks; 102 | } 103 | 104 | static void sparse_file_write_block(struct output_file *out, 105 | struct backed_block *bb) 106 | { 107 | switch (backed_block_type(bb)) { 108 | case BACKED_BLOCK_DATA: 109 | write_data_chunk(out, backed_block_len(bb), backed_block_data(bb)); 110 | break; 111 | case BACKED_BLOCK_FILE: 112 | write_file_chunk(out, backed_block_len(bb), 113 | backed_block_filename(bb), backed_block_file_offset(bb)); 114 | break; 115 | case BACKED_BLOCK_FD: 116 | write_fd_chunk(out, backed_block_len(bb), 117 | backed_block_fd(bb), backed_block_file_offset(bb)); 118 | break; 119 | case BACKED_BLOCK_FILL: 120 | write_fill_chunk(out, backed_block_len(bb), 121 | backed_block_fill_val(bb)); 122 | break; 123 | } 124 | } 125 | 126 | static int write_all_blocks(struct sparse_file *s, struct output_file *out) 127 | { 128 | struct backed_block *bb; 129 | unsigned int last_block = 0; 130 | int64_t pad; 131 | 132 | for (bb = backed_block_iter_new(s->backed_block_list); bb; 133 | bb = backed_block_iter_next(bb)) { 134 | if (backed_block_block(bb) > last_block) { 135 | unsigned int blocks = backed_block_block(bb) - last_block; 136 | write_skip_chunk(out, (int64_t)blocks * s->block_size); 137 | } 138 | sparse_file_write_block(out, bb); 139 | last_block = backed_block_block(bb) + 140 | DIV_ROUND_UP(backed_block_len(bb), s->block_size); 141 | } 142 | 143 | pad = s->len - (int64_t)last_block * s->block_size; 144 | assert(pad >= 0); 145 | if (pad > 0) { 146 | write_skip_chunk(out, pad); 147 | } 148 | 149 | return 0; 150 | } 151 | 152 | int sparse_file_write(struct sparse_file *s, int fd, bool gz, bool sparse, 153 | bool crc) 154 | { 155 | int ret; 156 | int chunks; 157 | struct output_file *out; 158 | 159 | chunks = sparse_count_chunks(s); 160 | out = output_file_open_fd(fd, s->block_size, s->len, gz, sparse, chunks, crc); 161 | 162 | if (!out) 163 | return -ENOMEM; 164 | 165 | ret = write_all_blocks(s, out); 166 | 167 | output_file_close(out); 168 | 169 | return ret; 170 | } 171 | 172 | int sparse_file_callback(struct sparse_file *s, bool sparse, bool crc, 173 | int (*write)(void *priv, const void *data, int len), void *priv) 174 | { 175 | int ret; 176 | int chunks; 177 | struct output_file *out; 178 | 179 | chunks = sparse_count_chunks(s); 180 | out = output_file_open_callback(write, priv, s->block_size, s->len, false, 181 | sparse, chunks, crc); 182 | 183 | if (!out) 184 | return -ENOMEM; 185 | 186 | ret = write_all_blocks(s, out); 187 | 188 | output_file_close(out); 189 | 190 | return ret; 191 | } 192 | 193 | static int out_counter_write(void *priv, const void *data __unused, int len) 194 | { 195 | int64_t *count = priv; 196 | *count += len; 197 | return 0; 198 | } 199 | 200 | int64_t sparse_file_len(struct sparse_file *s, bool sparse, bool crc) 201 | { 202 | int ret; 203 | int chunks = sparse_count_chunks(s); 204 | int64_t count = 0; 205 | struct output_file *out; 206 | 207 | out = output_file_open_callback(out_counter_write, &count, 208 | s->block_size, s->len, false, sparse, chunks, crc); 209 | if (!out) { 210 | return -1; 211 | } 212 | 213 | ret = write_all_blocks(s, out); 214 | 215 | output_file_close(out); 216 | 217 | if (ret < 0) { 218 | return -1; 219 | } 220 | 221 | return count; 222 | } 223 | 224 | static struct backed_block *move_chunks_up_to_len(struct sparse_file *from, 225 | struct sparse_file *to, unsigned int len) 226 | { 227 | int64_t count = 0; 228 | struct output_file *out_counter; 229 | struct backed_block *last_bb = NULL; 230 | struct backed_block *bb; 231 | struct backed_block *start; 232 | int64_t file_len = 0; 233 | 234 | /* 235 | * overhead is sparse file header, initial skip chunk, split chunk, end 236 | * skip chunk, and crc chunk. 237 | */ 238 | int overhead = sizeof(sparse_header_t) + 4 * sizeof(chunk_header_t) + 239 | sizeof(uint32_t); 240 | len -= overhead; 241 | 242 | start = backed_block_iter_new(from->backed_block_list); 243 | out_counter = output_file_open_callback(out_counter_write, &count, 244 | to->block_size, to->len, false, true, 0, false); 245 | if (!out_counter) { 246 | return NULL; 247 | } 248 | 249 | for (bb = start; bb; bb = backed_block_iter_next(bb)) { 250 | count = 0; 251 | /* will call out_counter_write to update count */ 252 | sparse_file_write_block(out_counter, bb); 253 | if (file_len + count > len) { 254 | /* 255 | * If the remaining available size is more than 1/8th of the 256 | * requested size, split the chunk. Results in sparse files that 257 | * are at least 7/8ths of the requested size 258 | */ 259 | if (!last_bb || (len - file_len > (len / 8))) { 260 | backed_block_split(from->backed_block_list, bb, len - file_len); 261 | last_bb = bb; 262 | } 263 | goto out; 264 | } 265 | file_len += count; 266 | last_bb = bb; 267 | } 268 | 269 | out: 270 | backed_block_list_move(from->backed_block_list, 271 | to->backed_block_list, start, last_bb); 272 | 273 | output_file_close(out_counter); 274 | 275 | return bb; 276 | } 277 | 278 | int sparse_file_resparse(struct sparse_file *in_s, unsigned int max_len, 279 | struct sparse_file **out_s, int out_s_count) 280 | { 281 | struct backed_block *bb; 282 | struct sparse_file *s; 283 | struct sparse_file *tmp; 284 | int c = 0; 285 | 286 | tmp = sparse_file_new(in_s->block_size, in_s->len); 287 | if (!tmp) { 288 | return -ENOMEM; 289 | } 290 | 291 | do { 292 | s = sparse_file_new(in_s->block_size, in_s->len); 293 | 294 | bb = move_chunks_up_to_len(in_s, s, max_len); 295 | 296 | if (c < out_s_count) { 297 | out_s[c] = s; 298 | } else { 299 | backed_block_list_move(s->backed_block_list, tmp->backed_block_list, 300 | NULL, NULL); 301 | sparse_file_destroy(s); 302 | } 303 | c++; 304 | } while (bb); 305 | 306 | backed_block_list_move(tmp->backed_block_list, in_s->backed_block_list, 307 | NULL, NULL); 308 | 309 | sparse_file_destroy(tmp); 310 | 311 | return c; 312 | } 313 | 314 | void sparse_file_verbose(struct sparse_file *s) 315 | { 316 | s->verbose = true; 317 | } 318 | -------------------------------------------------------------------------------- /core/libsparse/sparse_crc32.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or 3 | * code or tables extracted from it, as desired without restriction. 4 | */ 5 | 6 | /* 7 | * First, the polynomial itself and its table of feedback terms. The 8 | * polynomial is 9 | * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 10 | * 11 | * Note that we take it "backwards" and put the highest-order term in 12 | * the lowest-order bit. The X^32 term is "implied"; the LSB is the 13 | * X^31 term, etc. The X^0 term (usually shown as "+1") results in 14 | * the MSB being 1 15 | * 16 | * Note that the usual hardware shift register implementation, which 17 | * is what we're using (we're merely optimizing it by doing eight-bit 18 | * chunks at a time) shifts bits into the lowest-order term. In our 19 | * implementation, that means shifting towards the right. Why do we 20 | * do it this way? Because the calculated CRC must be transmitted in 21 | * order from highest-order term to lowest-order term. UARTs transmit 22 | * characters in order from LSB to MSB. By storing the CRC this way 23 | * we hand it to the UART in the order low-byte to high-byte; the UART 24 | * sends each low-bit to hight-bit; and the result is transmission bit 25 | * by bit from highest- to lowest-order term without requiring any bit 26 | * shuffling on our part. Reception works similarly 27 | * 28 | * The feedback terms table consists of 256, 32-bit entries. Notes 29 | * 30 | * The table can be generated at runtime if desired; code to do so 31 | * is shown later. It might not be obvious, but the feedback 32 | * terms simply represent the results of eight shift/xor opera 33 | * tions for all combinations of data and CRC register values 34 | * 35 | * The values must be right-shifted by eight bits by the "updcrc 36 | * logic; the shift must be unsigned (bring in zeroes). On some 37 | * hardware you could probably optimize the shift in assembler by 38 | * using byte-swap instructions 39 | * polynomial $edb88320 40 | * 41 | * 42 | * CRC32 code derived from work by Gary S. Brown. 43 | */ 44 | 45 | /* Code taken from FreeBSD 8 */ 46 | #include 47 | 48 | static uint32_t crc32_tab[] = { 49 | 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 50 | 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 51 | 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2, 52 | 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 53 | 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 54 | 0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 55 | 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c, 56 | 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, 57 | 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 58 | 0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 59 | 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106, 60 | 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, 61 | 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 62 | 0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 63 | 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950, 64 | 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, 65 | 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 66 | 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 67 | 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 68 | 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, 69 | 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 70 | 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 71 | 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84, 72 | 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 73 | 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 74 | 0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 75 | 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e, 76 | 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, 77 | 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 78 | 0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 79 | 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28, 80 | 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, 81 | 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 82 | 0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 83 | 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242, 84 | 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, 85 | 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 86 | 0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 87 | 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 88 | 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, 89 | 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 90 | 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 91 | 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d 92 | }; 93 | 94 | /* 95 | * A function that calculates the CRC-32 based on the table above is 96 | * given below for documentation purposes. An equivalent implementation 97 | * of this function that's actually used in the kernel can be found 98 | * in sys/libkern.h, where it can be inlined. 99 | */ 100 | 101 | uint32_t sparse_crc32(uint32_t crc_in, const void *buf, int size) 102 | { 103 | const uint8_t *p = buf; 104 | uint32_t crc; 105 | 106 | crc = crc_in ^ ~0U; 107 | while (size--) 108 | crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); 109 | return crc ^ ~0U; 110 | } 111 | 112 | -------------------------------------------------------------------------------- /core/libsparse/sparse_crc32.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include 18 | 19 | uint32_t sparse_crc32(uint32_t crc, const void *buf, size_t size); 20 | 21 | -------------------------------------------------------------------------------- /core/libsparse/sparse_defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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_DEFS_ 18 | #define _LIBSPARSE_SPARSE_DEFS_ 19 | 20 | #include 21 | #include 22 | 23 | #define __le64 u64 24 | #define __le32 u32 25 | #define __le16 u16 26 | 27 | #define __be64 u64 28 | #define __be32 u32 29 | #define __be16 u16 30 | 31 | #define __u64 u64 32 | #define __u32 u32 33 | #define __u16 u16 34 | #define __u8 u8 35 | 36 | typedef unsigned long long u64; 37 | typedef signed long long s64; 38 | typedef unsigned int u32; 39 | typedef unsigned short int u16; 40 | typedef unsigned char u8; 41 | 42 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y)) 43 | #define ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y))) 44 | #define ALIGN_DOWN(x, y) ((y) * ((x) / (y))) 45 | 46 | #define error(fmt, args...) do { fprintf(stderr, "error: %s: " fmt "\n", __func__, ## args); } while (0) 47 | #define error_errno(s, args...) error(s ": %s", ##args, strerror(errno)) 48 | 49 | #endif 50 | -------------------------------------------------------------------------------- /core/libsparse/sparse_err.c: -------------------------------------------------------------------------------- 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 | #include 18 | 19 | #include 20 | #include 21 | #include 22 | 23 | void sparse_default_print(const char *fmt, ...) 24 | { 25 | va_list argp; 26 | 27 | va_start(argp, fmt); 28 | vfprintf(stderr, fmt, argp); 29 | va_end(argp); 30 | } 31 | 32 | void (*sparse_print_error)(const char *fmt, ...) = sparse_default_print; 33 | void (*sparse_print_verbose)(const char *fmt, ...) = sparse_default_print; 34 | -------------------------------------------------------------------------------- /core/libsparse/sparse_file.h: -------------------------------------------------------------------------------- 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_FILE_H_ 18 | #define _LIBSPARSE_SPARSE_FILE_H_ 19 | 20 | #include 21 | 22 | struct sparse_file { 23 | unsigned int block_size; 24 | int64_t len; 25 | bool verbose; 26 | 27 | struct backed_block_list *backed_block_list; 28 | struct output_file *out; 29 | }; 30 | 31 | 32 | #endif /* _LIBSPARSE_SPARSE_FILE_H_ */ 33 | -------------------------------------------------------------------------------- /core/libsparse/sparse_format.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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_FORMAT_H_ 18 | #define _LIBSPARSE_SPARSE_FORMAT_H_ 19 | #include "sparse_defs.h" 20 | 21 | typedef struct sparse_header { 22 | __le32 magic; /* 0xed26ff3a */ 23 | __le16 major_version; /* (0x1) - reject images with higher major versions */ 24 | __le16 minor_version; /* (0x0) - allow images with higer minor versions */ 25 | __le16 file_hdr_sz; /* 28 bytes for first revision of the file format */ 26 | __le16 chunk_hdr_sz; /* 12 bytes for first revision of the file format */ 27 | __le32 blk_sz; /* block size in bytes, must be a multiple of 4 (4096) */ 28 | __le32 total_blks; /* total blocks in the non-sparse output image */ 29 | __le32 total_chunks; /* total chunks in the sparse input image */ 30 | __le32 image_checksum; /* CRC32 checksum of the original data, counting "don't care" */ 31 | /* as 0. Standard 802.3 polynomial, use a Public Domain */ 32 | /* table implementation */ 33 | } sparse_header_t; 34 | 35 | #define SPARSE_HEADER_MAGIC 0xed26ff3a 36 | 37 | #define CHUNK_TYPE_RAW 0xCAC1 38 | #define CHUNK_TYPE_FILL 0xCAC2 39 | #define CHUNK_TYPE_DONT_CARE 0xCAC3 40 | #define CHUNK_TYPE_CRC32 0xCAC4 41 | 42 | typedef struct chunk_header { 43 | __le16 chunk_type; /* 0xCAC1 -> raw; 0xCAC2 -> fill; 0xCAC3 -> don't care */ 44 | __le16 reserved1; 45 | __le32 chunk_sz; /* in blocks in output image */ 46 | __le32 total_sz; /* in bytes of chunk input file including chunk header and data */ 47 | } chunk_header_t; 48 | 49 | /* Following a Raw or Fill or CRC32 chunk is data. 50 | * For a Raw chunk, it's the data in chunk_sz * blk_sz. 51 | * For a Fill chunk, it's 4 bytes of the fill data. 52 | * For a CRC32 chunk, it's 4 bytes of CRC32 53 | */ 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /extras/ext4_utils/Makefile: -------------------------------------------------------------------------------- 1 | SELIB = ../../libselinux 2 | ZLLIB = ../../zlib/src 3 | COLIB = ../../core 4 | SPLIB = ../../core/libsparse 5 | AR = ar rcs 6 | OBJS = $(patsubst %.c,%.o,$(wildcard *.c)) 7 | 8 | all:make_ext4fs 9 | 10 | make_ext4fs: 11 | gcc -DHOST -DANDROID -I$(SELIB)/include -I$(SPLIB)/include -I$(COLIB)/include/ -o make_ext4fs \ 12 | make_ext4fs_main.c make_ext4fs.c ext4fixup.c ext4_utils.c allocate.c contents.c extent.c \ 13 | indirect.c uuid.c sha1.c wipe.c crc16.c ext4_sb.c canned_fs_config.c \ 14 | $(SELIB)/src/libselinux.a $(SPLIB)/libsparse.a $(ZLLIB)/libz.a 15 | 16 | clean: 17 | rm -f $(OBJS) 18 | rm -f make_ext4fs 19 | 20 | -------------------------------------------------------------------------------- /extras/ext4_utils/allocate.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _ALLOCATE_H_ 18 | #define _ALLOCATE_H_ 19 | 20 | #define EXT4_ALLOCATE_FAILED (u32)(~0) 21 | 22 | #include "ext4_utils.h" 23 | 24 | struct region; 25 | 26 | struct region_list { 27 | struct region *first; 28 | struct region *last; 29 | struct region *iter; 30 | u32 partial_iter; 31 | }; 32 | 33 | struct block_allocation { 34 | struct region_list list; 35 | struct region_list oob_list; 36 | char* filename; 37 | struct block_allocation* next; 38 | }; 39 | 40 | 41 | void block_allocator_init(); 42 | void block_allocator_free(); 43 | u32 allocate_block(); 44 | struct block_allocation *allocate_blocks(u32 len); 45 | int block_allocation_num_regions(struct block_allocation *alloc); 46 | int block_allocation_len(struct block_allocation *alloc); 47 | struct ext4_inode *get_inode(u32 inode); 48 | struct ext4_xattr_header *get_xattr_block_for_inode(struct ext4_inode *inode); 49 | void reduce_allocation(struct block_allocation *alloc, u32 len); 50 | u32 get_block(struct block_allocation *alloc, u32 block); 51 | u32 get_oob_block(struct block_allocation *alloc, u32 block); 52 | void get_next_region(struct block_allocation *alloc); 53 | void get_region(struct block_allocation *alloc, u32 *block, u32 *len); 54 | u32 get_free_blocks(u32 bg); 55 | u32 get_free_inodes(u32 bg); 56 | u32 reserve_inodes(int bg, u32 inodes); 57 | void add_directory(u32 inode); 58 | u16 get_directories(int bg); 59 | u16 get_bg_flags(int bg); 60 | void init_unused_inode_tables(void); 61 | u32 allocate_inode(); 62 | void free_alloc(struct block_allocation *alloc); 63 | int reserve_oob_blocks(struct block_allocation *alloc, int blocks); 64 | int advance_blocks(struct block_allocation *alloc, int blocks); 65 | int advance_oob_blocks(struct block_allocation *alloc, int blocks); 66 | int last_region(struct block_allocation *alloc); 67 | void rewind_alloc(struct block_allocation *alloc); 68 | void append_region(struct block_allocation *alloc, 69 | u32 block, u32 len, int bg); 70 | struct block_allocation *create_allocation(); 71 | int append_oob_allocation(struct block_allocation *alloc, u32 len); 72 | void print_blocks(FILE* f, struct block_allocation *alloc); 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /extras/ext4_utils/canned_fs_config.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | #include "private/android_filesystem_config.h" 24 | 25 | #include "canned_fs_config.h" 26 | 27 | typedef struct { 28 | const char* path; 29 | unsigned uid; 30 | unsigned gid; 31 | unsigned mode; 32 | uint64_t capabilities; 33 | } Path; 34 | 35 | static Path* canned_data = NULL; 36 | static int canned_alloc = 0; 37 | static int canned_used = 0; 38 | 39 | static int path_compare(const void* a, const void* b) { 40 | return strcmp(((Path*)a)->path, ((Path*)b)->path); 41 | } 42 | 43 | int load_canned_fs_config(const char* fn) { 44 | FILE* f = fopen(fn, "r"); 45 | if (f == NULL) { 46 | fprintf(stderr, "failed to open %s: %s\n", fn, strerror(errno)); 47 | return -1; 48 | } 49 | 50 | char line[PATH_MAX + 200]; 51 | while (fgets(line, sizeof(line), f)) { 52 | while (canned_used >= canned_alloc) { 53 | canned_alloc = (canned_alloc+1) * 2; 54 | canned_data = (Path*) realloc(canned_data, canned_alloc * sizeof(Path)); 55 | } 56 | Path* p = canned_data + canned_used; 57 | p->path = strdup(strtok(line, " ")); 58 | p->uid = atoi(strtok(NULL, " ")); 59 | p->gid = atoi(strtok(NULL, " ")); 60 | p->mode = strtol(strtok(NULL, " "), NULL, 8); // mode is in octal 61 | p->capabilities = 0; 62 | 63 | char* token = NULL; 64 | do { 65 | token = strtok(NULL, " "); 66 | if (token && strncmp(token, "capabilities=", 13) == 0) { 67 | p->capabilities = strtoll(token+13, NULL, 0); 68 | break; 69 | } 70 | } while (token); 71 | 72 | canned_used++; 73 | } 74 | 75 | fclose(f); 76 | 77 | qsort(canned_data, canned_used, sizeof(Path), path_compare); 78 | printf("loaded %d fs_config entries\n", canned_used); 79 | 80 | return 0; 81 | } 82 | 83 | void canned_fs_config(const char* path, int dir, 84 | unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities) { 85 | Path key; 86 | key.path = path+1; // canned paths lack the leading '/' 87 | Path* p = (Path*) bsearch(&key, canned_data, canned_used, sizeof(Path), path_compare); 88 | if (p == NULL) { 89 | fprintf(stderr, "failed to find [%s] in canned fs_config\n", path); 90 | exit(1); 91 | } 92 | *uid = p->uid; 93 | *gid = p->gid; 94 | *mode = p->mode; 95 | *capabilities = p->capabilities; 96 | 97 | #if 0 98 | // for debugging, run the built-in fs_config and compare the results. 99 | 100 | unsigned c_uid, c_gid, c_mode; 101 | uint64_t c_capabilities; 102 | fs_config(path, dir, &c_uid, &c_gid, &c_mode, &c_capabilities); 103 | 104 | if (c_uid != *uid) printf("%s uid %d %d\n", path, *uid, c_uid); 105 | if (c_gid != *gid) printf("%s gid %d %d\n", path, *gid, c_gid); 106 | if (c_mode != *mode) printf("%s mode 0%o 0%o\n", path, *mode, c_mode); 107 | if (c_capabilities != *capabilities) printf("%s capabilities %llx %llx\n", path, *capabilities, c_capabilities); 108 | #endif 109 | } 110 | -------------------------------------------------------------------------------- /extras/ext4_utils/canned_fs_config.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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 _CANNED_FS_CONFIG_H 18 | #define _CANNED_FS_CONFIG_H 19 | 20 | #include 21 | 22 | int load_canned_fs_config(const char* fn); 23 | void canned_fs_config(const char* path, int dir, 24 | unsigned* uid, unsigned* gid, unsigned* mode, uint64_t* capabilities); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /extras/ext4_utils/contents.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _DIRECTORY_H_ 18 | #define _DIRECTORY_H_ 19 | 20 | struct dentry { 21 | char *path; 22 | char *full_path; 23 | const char *filename; 24 | char *link; 25 | unsigned long size; 26 | u8 file_type; 27 | u16 mode; 28 | u16 uid; 29 | u16 gid; 30 | u32 *inode; 31 | u32 mtime; 32 | char *secon; 33 | uint64_t capabilities; 34 | }; 35 | 36 | u32 make_directory(u32 dir_inode_num, u32 entries, struct dentry *dentries, 37 | u32 dirs); 38 | u32 make_file(const char *filename, u64 len); 39 | u32 make_link(const char *link); 40 | int inode_set_permissions(u32 inode_num, u16 mode, u16 uid, u16 gid, u32 mtime); 41 | int inode_set_selinux(u32 inode_num, const char *secon); 42 | int inode_set_capabilities(u32 inode_num, uint64_t capabilities); 43 | struct block_allocation* get_saved_allocation_chain(); 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /extras/ext4_utils/crc16.c: -------------------------------------------------------------------------------- 1 | /*- 2 | * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or 3 | * code or tables extracted from it, as desired without restriction. 4 | */ 5 | 6 | /* CRC32 code derived from work by Gary S. Brown. */ 7 | 8 | /* Code taken from FreeBSD 8 */ 9 | 10 | /* Converted to crc16 */ 11 | 12 | #include "ext4_utils.h" 13 | 14 | static u16 crc16_tab[] = { 15 | 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 16 | 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 17 | 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 18 | 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 19 | 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 20 | 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 21 | 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 22 | 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 23 | 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 24 | 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 25 | 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 26 | 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 27 | 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 28 | 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 29 | 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 30 | 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 31 | 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 32 | 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 33 | 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 34 | 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 35 | 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 36 | 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 37 | 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 38 | 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 39 | 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 40 | 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 41 | 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 42 | 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 43 | 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 44 | 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 45 | 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 46 | 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040, 47 | }; 48 | 49 | u16 ext4_crc16(u16 crc_in, const void *buf, int size) 50 | { 51 | const u8 *p = buf; 52 | u16 crc = crc_in; 53 | 54 | while (size--) 55 | crc = crc16_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); 56 | 57 | return crc; 58 | } 59 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4_extents.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | **************************************************************************** 3 | *** 4 | *** This header was automatically generated from a Linux kernel header 5 | *** of the same name, to make information necessary for userspace to 6 | *** call into the kernel available to libc. It contains only constants, 7 | *** structures, and macros generated from the original header, and thus, 8 | *** contains no copyrightable information. 9 | *** 10 | **************************************************************************** 11 | ****************************************************************************/ 12 | #ifndef _EXT4_EXTENTS 13 | #define _EXT4_EXTENTS 14 | 15 | #include "ext4.h" 16 | 17 | #define AGGRESSIVE_TEST_ 18 | 19 | #define EXTENTS_STATS__ 20 | 21 | #define CHECK_BINSEARCH__ 22 | 23 | #define EXT_DEBUG__ 24 | #ifdef EXT_DEBUG 25 | #define ext_debug(a...) printk(a) 26 | #else 27 | #define ext_debug(a...) 28 | #endif 29 | 30 | #define EXT_STATS_ 31 | 32 | struct ext4_extent { 33 | __le32 ee_block; 34 | __le16 ee_len; 35 | __le16 ee_start_hi; 36 | __le32 ee_start_lo; 37 | }; 38 | 39 | struct ext4_extent_idx { 40 | __le32 ei_block; 41 | __le32 ei_leaf_lo; 42 | __le16 ei_leaf_hi; 43 | __u16 ei_unused; 44 | }; 45 | 46 | struct ext4_extent_header { 47 | __le16 eh_magic; 48 | __le16 eh_entries; 49 | __le16 eh_max; 50 | __le16 eh_depth; 51 | __le32 eh_generation; 52 | }; 53 | 54 | #define EXT4_EXT_MAGIC 0xf30a 55 | 56 | struct ext4_ext_path { 57 | ext4_fsblk_t p_block; 58 | __u16 p_depth; 59 | struct ext4_extent *p_ext; 60 | struct ext4_extent_idx *p_idx; 61 | struct ext4_extent_header *p_hdr; 62 | struct buffer_head *p_bh; 63 | }; 64 | 65 | #define EXT4_EXT_CACHE_NO 0 66 | #define EXT4_EXT_CACHE_GAP 1 67 | #define EXT4_EXT_CACHE_EXTENT 2 68 | 69 | #define EXT_CONTINUE 0 70 | #define EXT_BREAK 1 71 | #define EXT_REPEAT 2 72 | 73 | #define EXT_MAX_BLOCK 0xffffffff 74 | 75 | #define EXT_INIT_MAX_LEN (1UL << 15) 76 | #define EXT_UNINIT_MAX_LEN (EXT_INIT_MAX_LEN - 1) 77 | 78 | #define EXT_FIRST_EXTENT(__hdr__) ((struct ext4_extent *) (((char *) (__hdr__)) + sizeof(struct ext4_extent_header))) 79 | #define EXT_FIRST_INDEX(__hdr__) ((struct ext4_extent_idx *) (((char *) (__hdr__)) + sizeof(struct ext4_extent_header))) 80 | #define EXT_HAS_FREE_INDEX(__path__) (le16_to_cpu((__path__)->p_hdr->eh_entries) < le16_to_cpu((__path__)->p_hdr->eh_max)) 81 | #define EXT_LAST_EXTENT(__hdr__) (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) 82 | #define EXT_LAST_INDEX(__hdr__) (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_entries) - 1) 83 | #define EXT_MAX_EXTENT(__hdr__) (EXT_FIRST_EXTENT((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) 84 | #define EXT_MAX_INDEX(__hdr__) (EXT_FIRST_INDEX((__hdr__)) + le16_to_cpu((__hdr__)->eh_max) - 1) 85 | 86 | #endif 87 | 88 | 89 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4_kernel_headers.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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 _EXT4_UTILS_EXT4_KERNEL_HEADERS_H_ 18 | #define _EXT4_UTILS_EXT4_KERNEL_HEADERS_H_ 19 | 20 | #include 21 | 22 | #ifdef __BIONIC__ 23 | #include 24 | #else 25 | #define __le64 uint64_t 26 | #define __le32 uint32_t 27 | #define __le16 uint16_t 28 | 29 | #define __be64 uint64_t 30 | #define __be32 uint32_t 31 | #define __be16 uint16_t 32 | 33 | #define __u64 uint64_t 34 | #define __u32 uint32_t 35 | #define __u16 uint16_t 36 | #define __u8 uint8_t 37 | #endif 38 | 39 | #include "ext4.h" 40 | #include "xattr.h" 41 | #include "ext4_extents.h" 42 | #include "jbd2.h" 43 | 44 | #ifndef __BIONIC__ 45 | #undef __le64 46 | #undef __le32 47 | #undef __le16 48 | 49 | #undef __be64 50 | #undef __be32 51 | #undef __be16 52 | 53 | #undef __u64 54 | #undef __u32 55 | #undef __u16 56 | #undef __u8 57 | #endif 58 | 59 | #endif 60 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4_sb.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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 | #include 18 | 19 | #include "ext4_sb.h" 20 | 21 | int ext4_parse_sb(struct ext4_super_block *sb, struct fs_info *info) 22 | { 23 | uint64_t len_blocks; 24 | 25 | if (sb->s_magic != EXT4_SUPER_MAGIC) 26 | return -EINVAL; 27 | 28 | if ((sb->s_state & EXT4_VALID_FS) != EXT4_VALID_FS) 29 | return -EINVAL; 30 | 31 | info->block_size = 1024 << sb->s_log_block_size; 32 | info->blocks_per_group = sb->s_blocks_per_group; 33 | info->inodes_per_group = sb->s_inodes_per_group; 34 | info->inode_size = sb->s_inode_size; 35 | info->inodes = sb->s_inodes_count; 36 | info->feat_ro_compat = sb->s_feature_ro_compat; 37 | info->feat_compat = sb->s_feature_compat; 38 | info->feat_incompat = sb->s_feature_incompat; 39 | info->bg_desc_reserve_blocks = sb->s_reserved_gdt_blocks; 40 | info->label = sb->s_volume_name; 41 | 42 | len_blocks = ((uint64_t)sb->s_blocks_count_hi << 32) + 43 | sb->s_blocks_count_lo; 44 | info->len = (uint64_t)info->block_size * len_blocks; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4_sb.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2014 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 _EXT4_UTILS_EXT4_SB_H_ 18 | #define _EXT4_UTILS_EXT4_SB_H_ 19 | 20 | #include "ext4_kernel_headers.h" 21 | 22 | #define EXT4_SUPER_MAGIC 0xEF53 23 | 24 | #ifdef __cplusplus 25 | extern "C" { 26 | #endif 27 | 28 | struct fs_info { 29 | int64_t len; /* If set to 0, ask the block device for the size, 30 | * if less than 0, reserve that much space at the 31 | * end of the partition, else use the size given. */ 32 | uint32_t block_size; 33 | uint32_t blocks_per_group; 34 | uint32_t inodes_per_group; 35 | uint32_t inode_size; 36 | uint32_t inodes; 37 | uint32_t journal_blocks; 38 | uint16_t feat_ro_compat; 39 | uint16_t feat_compat; 40 | uint16_t feat_incompat; 41 | uint32_t bg_desc_reserve_blocks; 42 | const char *label; 43 | uint8_t no_journal; 44 | }; 45 | 46 | int ext4_parse_sb(struct ext4_super_block *sb, struct fs_info *info); 47 | 48 | #ifdef __cplusplus 49 | } 50 | #endif 51 | 52 | #endif 53 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4_utils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _EXT4_UTILS_H_ 18 | #define _EXT4_UTILS_H_ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | #ifndef _GNU_SOURCE 25 | #define _GNU_SOURCE 26 | #endif 27 | #define _FILE_OFFSET_BITS 64 28 | #define _LARGEFILE64_SOURCE 1 29 | #include 30 | #include 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | 41 | #if defined(__CYGWIN__) || defined(__APPLE__) && defined(__MACH__) 42 | #define lseek64 lseek 43 | #define ftruncate64 ftruncate 44 | #define mmap64 mmap 45 | #define off64_t off_t 46 | #endif 47 | 48 | #include "ext4_sb.h" 49 | 50 | extern int force; 51 | 52 | #define warn(fmt, args...) do { fprintf(stderr, "warning: %s: " fmt "\n", __func__, ## args); } while (0) 53 | #define error(fmt, args...) do { fprintf(stderr, "error: %s: " fmt "\n", __func__, ## args); if (!force) longjmp(setjmp_env, EXIT_FAILURE); } while (0) 54 | #define error_errno(s, args...) error(s ": %s", ##args, strerror(errno)) 55 | #define critical_error(fmt, args...) do { fprintf(stderr, "critical error: %s: " fmt "\n", __func__, ## args); longjmp(setjmp_env, EXIT_FAILURE); } while (0) 56 | #define critical_error_errno(s, args...) critical_error(s ": %s", ##args, strerror(errno)) 57 | 58 | #define EXT4_JNL_BACKUP_BLOCKS 1 59 | 60 | #ifndef min /* already defined by windows.h */ 61 | #define min(a, b) ((a) < (b) ? (a) : (b)) 62 | #endif 63 | 64 | #define DIV_ROUND_UP(x, y) (((x) + (y) - 1)/(y)) 65 | #define EXT4_ALIGN(x, y) ((y) * DIV_ROUND_UP((x), (y))) 66 | 67 | /* XXX */ 68 | #define cpu_to_le32(x) (x) 69 | #define cpu_to_le16(x) (x) 70 | #define le32_to_cpu(x) (x) 71 | #define le16_to_cpu(x) (x) 72 | 73 | #ifdef __LP64__ 74 | typedef unsigned long u64; 75 | typedef signed long s64; 76 | #else 77 | typedef unsigned long long u64; 78 | typedef signed long long s64; 79 | #endif 80 | typedef unsigned int u32; 81 | typedef unsigned short int u16; 82 | typedef unsigned char u8; 83 | 84 | struct block_group_info; 85 | struct xattr_list_element; 86 | 87 | struct ext2_group_desc { 88 | u32 bg_block_bitmap; 89 | u32 bg_inode_bitmap; 90 | u32 bg_inode_table; 91 | u16 bg_free_blocks_count; 92 | u16 bg_free_inodes_count; 93 | u16 bg_used_dirs_count; 94 | u16 bg_flags; 95 | u32 bg_reserved[2]; 96 | u16 bg_reserved16; 97 | u16 bg_checksum; 98 | }; 99 | 100 | struct fs_aux_info { 101 | struct ext4_super_block *sb; 102 | struct ext4_super_block **backup_sb; 103 | struct ext2_group_desc *bg_desc; 104 | struct block_group_info *bgs; 105 | struct xattr_list_element *xattrs; 106 | u32 first_data_block; 107 | u64 len_blocks; 108 | u32 inode_table_blocks; 109 | u32 groups; 110 | u32 bg_desc_blocks; 111 | u32 default_i_flags; 112 | u32 blocks_per_ind; 113 | u32 blocks_per_dind; 114 | u32 blocks_per_tind; 115 | }; 116 | 117 | extern struct fs_info info; 118 | extern struct fs_aux_info aux_info; 119 | extern struct sparse_file *ext4_sparse_file; 120 | 121 | extern jmp_buf setjmp_env; 122 | 123 | static inline int log_2(int j) 124 | { 125 | int i; 126 | 127 | for (i = 0; j > 0; i++) 128 | j >>= 1; 129 | 130 | return i - 1; 131 | } 132 | 133 | int bitmap_get_bit(u8 *bitmap, u32 bit); 134 | void bitmap_clear_bit(u8 *bitmap, u32 bit); 135 | int ext4_bg_has_super_block(int bg); 136 | void read_sb(int fd, struct ext4_super_block *sb); 137 | void write_sb(int fd, unsigned long long offset, struct ext4_super_block *sb); 138 | void write_ext4_image(int fd, int gz, int sparse, int crc); 139 | void ext4_create_fs_aux_info(void); 140 | void ext4_free_fs_aux_info(void); 141 | void ext4_fill_in_sb(void); 142 | void ext4_create_resize_inode(void); 143 | void ext4_create_journal_inode(void); 144 | void ext4_update_free(void); 145 | void ext4_queue_sb(void); 146 | u64 get_block_device_size(int fd); 147 | int is_block_device_fd(int fd); 148 | u64 get_file_size(int fd); 149 | u64 parse_num(const char *arg); 150 | void ext4_parse_sb_info(struct ext4_super_block *sb); 151 | u16 ext4_crc16(u16 crc_in, const void *buf, int size); 152 | 153 | typedef void (*fs_config_func_t)(const char *path, int dir, unsigned *uid, unsigned *gid, 154 | unsigned *mode, uint64_t *capabilities); 155 | 156 | struct selabel_handle; 157 | 158 | int make_ext4fs_internal(int fd, const char *directory, 159 | const char *mountpoint, fs_config_func_t fs_config_func, int gzip, 160 | int sparse, int crc, int wipe, 161 | struct selabel_handle *sehnd, int verbose, time_t fixed_time, 162 | FILE* block_list_file); 163 | 164 | int read_ext(int fd, int verbose); 165 | 166 | #ifdef __cplusplus 167 | } 168 | #endif 169 | 170 | #endif 171 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4fixup.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | int ext4fixup(char *fsdev); 18 | int ext4fixup_internal(char *fsdev, int v_flag, int n_flag, 19 | int stop_phase, int stop_loc, int stop_count); 20 | 21 | -------------------------------------------------------------------------------- /extras/ext4_utils/ext4fixup_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include 18 | #include 19 | #include 20 | #include 21 | #include "ext4fixup.h" 22 | 23 | static void usage(char *me) 24 | { 25 | fprintf(stderr, "%s: usage: %s [-vn] \n", me, me); 26 | } 27 | 28 | int main(int argc, char **argv) 29 | { 30 | int opt; 31 | int verbose = 0; 32 | int no_write = 0; 33 | char *fsdev; 34 | char *me; 35 | int stop_phase = 0, stop_loc = 0, stop_count = 0; 36 | 37 | me = basename(argv[0]); 38 | 39 | while ((opt = getopt(argc, argv, "vnd:")) != -1) { 40 | switch (opt) { 41 | case 'v': 42 | verbose = 1; 43 | break; 44 | case 'n': 45 | no_write = 1; 46 | break; 47 | case 'd': 48 | sscanf(optarg, "%d,%d,%d", &stop_phase, &stop_loc, &stop_count); 49 | break; 50 | } 51 | } 52 | 53 | if (optind >= argc) { 54 | fprintf(stderr, "expected image or block device after options\n"); 55 | usage(me); 56 | exit(EXIT_FAILURE); 57 | } 58 | 59 | fsdev = argv[optind++]; 60 | 61 | if (optind < argc) { 62 | fprintf(stderr, "Unexpected argument: %s\n", argv[optind]); 63 | usage(me); 64 | exit(EXIT_FAILURE); 65 | } 66 | 67 | return ext4fixup_internal(fsdev, verbose, no_write, stop_phase, stop_loc, stop_count); 68 | } 69 | -------------------------------------------------------------------------------- /extras/ext4_utils/extent.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include "ext4_utils.h" 18 | #include "extent.h" 19 | 20 | #include 21 | 22 | #include 23 | #include 24 | #include 25 | 26 | 27 | /* Creates data buffers for the first backing_len bytes of a block allocation 28 | and queues them to be written */ 29 | static u8 *extent_create_backing(struct block_allocation *alloc, 30 | u64 backing_len) 31 | { 32 | u8 *data = calloc(backing_len, 1); 33 | if (!data) 34 | critical_error_errno("calloc"); 35 | 36 | u8 *ptr = data; 37 | for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) { 38 | u32 region_block; 39 | u32 region_len; 40 | u32 len; 41 | get_region(alloc, ®ion_block, ®ion_len); 42 | 43 | len = min(region_len * info.block_size, backing_len); 44 | 45 | sparse_file_add_data(ext4_sparse_file, ptr, len, region_block); 46 | ptr += len; 47 | backing_len -= len; 48 | } 49 | 50 | return data; 51 | } 52 | 53 | /* Queues each chunk of a file to be written to contiguous data block 54 | regions */ 55 | static void extent_create_backing_file(struct block_allocation *alloc, 56 | u64 backing_len, const char *filename) 57 | { 58 | off64_t offset = 0; 59 | for (; alloc != NULL && backing_len > 0; get_next_region(alloc)) { 60 | u32 region_block; 61 | u32 region_len; 62 | u32 len; 63 | get_region(alloc, ®ion_block, ®ion_len); 64 | 65 | len = min(region_len * info.block_size, backing_len); 66 | 67 | sparse_file_add_file(ext4_sparse_file, filename, offset, len, 68 | region_block); 69 | offset += len; 70 | backing_len -= len; 71 | } 72 | } 73 | 74 | static struct block_allocation *do_inode_allocate_extents( 75 | struct ext4_inode *inode, u64 len) 76 | { 77 | u32 block_len = DIV_ROUND_UP(len, info.block_size); 78 | struct block_allocation *alloc = allocate_blocks(block_len + 1); 79 | u32 extent_block = 0; 80 | u32 file_block = 0; 81 | struct ext4_extent *extent; 82 | u64 blocks; 83 | 84 | if (alloc == NULL) { 85 | error("Failed to allocate %d blocks\n", block_len + 1); 86 | return NULL; 87 | } 88 | 89 | int allocation_len = block_allocation_num_regions(alloc); 90 | if (allocation_len <= 3) { 91 | reduce_allocation(alloc, 1); 92 | } else { 93 | reserve_oob_blocks(alloc, 1); 94 | extent_block = get_oob_block(alloc, 0); 95 | } 96 | 97 | if (!extent_block) { 98 | struct ext4_extent_header *hdr = 99 | (struct ext4_extent_header *)&inode->i_block[0]; 100 | hdr->eh_magic = EXT4_EXT_MAGIC; 101 | hdr->eh_entries = allocation_len; 102 | hdr->eh_max = 3; 103 | hdr->eh_generation = 0; 104 | hdr->eh_depth = 0; 105 | 106 | extent = (struct ext4_extent *)&inode->i_block[3]; 107 | } else { 108 | struct ext4_extent_header *hdr = 109 | (struct ext4_extent_header *)&inode->i_block[0]; 110 | hdr->eh_magic = EXT4_EXT_MAGIC; 111 | hdr->eh_entries = 1; 112 | hdr->eh_max = 3; 113 | hdr->eh_generation = 0; 114 | hdr->eh_depth = 1; 115 | 116 | struct ext4_extent_idx *idx = 117 | (struct ext4_extent_idx *)&inode->i_block[3]; 118 | idx->ei_block = 0; 119 | idx->ei_leaf_lo = extent_block; 120 | idx->ei_leaf_hi = 0; 121 | idx->ei_unused = 0; 122 | 123 | u8 *data = calloc(info.block_size, 1); 124 | if (!data) 125 | critical_error_errno("calloc"); 126 | 127 | sparse_file_add_data(ext4_sparse_file, data, info.block_size, 128 | extent_block); 129 | 130 | if (((int)(info.block_size - sizeof(struct ext4_extent_header) / 131 | sizeof(struct ext4_extent))) < allocation_len) { 132 | error("File size %"PRIu64" is too big to fit in a single extent block\n", 133 | len); 134 | return NULL; 135 | } 136 | 137 | hdr = (struct ext4_extent_header *)data; 138 | hdr->eh_magic = EXT4_EXT_MAGIC; 139 | hdr->eh_entries = allocation_len; 140 | hdr->eh_max = (info.block_size - sizeof(struct ext4_extent_header)) / 141 | sizeof(struct ext4_extent); 142 | hdr->eh_generation = 0; 143 | hdr->eh_depth = 0; 144 | 145 | extent = (struct ext4_extent *)(data + 146 | sizeof(struct ext4_extent_header)); 147 | } 148 | 149 | for (; !last_region(alloc); extent++, get_next_region(alloc)) { 150 | u32 region_block; 151 | u32 region_len; 152 | 153 | get_region(alloc, ®ion_block, ®ion_len); 154 | extent->ee_block = file_block; 155 | extent->ee_len = region_len; 156 | extent->ee_start_hi = 0; 157 | extent->ee_start_lo = region_block; 158 | file_block += region_len; 159 | } 160 | 161 | if (extent_block) 162 | block_len += 1; 163 | 164 | blocks = (u64)block_len * info.block_size / 512; 165 | 166 | inode->i_flags |= EXT4_EXTENTS_FL; 167 | inode->i_size_lo = len; 168 | inode->i_size_high = len >> 32; 169 | inode->i_blocks_lo = blocks; 170 | inode->osd2.linux2.l_i_blocks_high = blocks >> 32; 171 | 172 | rewind_alloc(alloc); 173 | 174 | return alloc; 175 | } 176 | 177 | /* Allocates enough blocks to hold len bytes, with backing_len bytes in a data 178 | buffer, and connects them to an inode. Returns a pointer to the data 179 | buffer. */ 180 | u8 *inode_allocate_data_extents(struct ext4_inode *inode, u64 len, 181 | u64 backing_len) 182 | { 183 | struct block_allocation *alloc; 184 | u8 *data = NULL; 185 | 186 | alloc = do_inode_allocate_extents(inode, len); 187 | if (alloc == NULL) { 188 | error("failed to allocate extents for %"PRIu64" bytes", len); 189 | return NULL; 190 | } 191 | 192 | if (backing_len) { 193 | data = extent_create_backing(alloc, backing_len); 194 | if (!data) 195 | error("failed to create backing for %"PRIu64" bytes", backing_len); 196 | } 197 | 198 | free_alloc(alloc); 199 | 200 | return data; 201 | } 202 | 203 | /* Allocates enough blocks to hold len bytes, queues them to be written 204 | from a file, and connects them to an inode. */ 205 | struct block_allocation* inode_allocate_file_extents(struct ext4_inode *inode, u64 len, 206 | const char *filename) 207 | { 208 | struct block_allocation *alloc; 209 | 210 | alloc = do_inode_allocate_extents(inode, len); 211 | if (alloc == NULL) { 212 | error("failed to allocate extents for %"PRIu64" bytes", len); 213 | return NULL; 214 | } 215 | 216 | extent_create_backing_file(alloc, len, filename); 217 | return alloc; 218 | } 219 | 220 | /* Allocates enough blocks to hold len bytes and connects them to an inode */ 221 | void inode_allocate_extents(struct ext4_inode *inode, u64 len) 222 | { 223 | struct block_allocation *alloc; 224 | 225 | alloc = do_inode_allocate_extents(inode, len); 226 | if (alloc == NULL) { 227 | error("failed to allocate extents for %"PRIu64" bytes", len); 228 | return; 229 | } 230 | 231 | free_alloc(alloc); 232 | } 233 | -------------------------------------------------------------------------------- /extras/ext4_utils/extent.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _EXTENT_H_ 18 | #define _EXTENT_H_ 19 | 20 | #include "allocate.h" 21 | #include "ext4_utils.h" 22 | 23 | void inode_allocate_extents(struct ext4_inode *inode, u64 len); 24 | struct block_allocation* inode_allocate_file_extents( 25 | struct ext4_inode *inode, u64 len, const char *filename); 26 | u8 *inode_allocate_data_extents(struct ext4_inode *inode, u64 len, 27 | u64 backing_len); 28 | void free_extent_blocks(); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /extras/ext4_utils/indirect.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _INDIRECT_H_ 18 | #define _INDIRECT_H_ 19 | 20 | #include "allocate.h" 21 | 22 | void inode_allocate_indirect(struct ext4_inode *inode, unsigned long len); 23 | u8 *inode_allocate_data_indirect(struct ext4_inode *inode, unsigned long len, 24 | unsigned long backing_len); 25 | void inode_attach_resize(struct ext4_inode *inode, 26 | struct block_allocation *alloc); 27 | void free_indirect_blocks(); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /extras/ext4_utils/jbd2.h: -------------------------------------------------------------------------------- 1 | /**************************************************************************** 2 | **************************************************************************** 3 | *** 4 | *** This header was automatically generated from a Linux kernel header 5 | *** of the same name, to make information necessary for userspace to 6 | *** call into the kernel available to libc. It contains only constants, 7 | *** structures, and macros generated from the original header, and thus, 8 | *** contains no copyrightable information. 9 | *** 10 | **************************************************************************** 11 | ****************************************************************************/ 12 | #ifndef _LINUX_JBD2_H 13 | #define _LINUX_JBD2_H 14 | 15 | #define JBD2_DEBUG 16 | #define jfs_debug jbd_debug 17 | 18 | #define journal_oom_retry 1 19 | 20 | #undef JBD2_PARANOID_IOFAIL 21 | 22 | #define JBD2_DEFAULT_MAX_COMMIT_AGE 5 23 | 24 | #define jbd_debug(f, a...) 25 | 26 | #define JBD2_MIN_JOURNAL_BLOCKS 1024 27 | 28 | #define JBD2_MAGIC_NUMBER 0xc03b3998U 29 | 30 | #define JBD2_DESCRIPTOR_BLOCK 1 31 | #define JBD2_COMMIT_BLOCK 2 32 | #define JBD2_SUPERBLOCK_V1 3 33 | #define JBD2_SUPERBLOCK_V2 4 34 | #define JBD2_REVOKE_BLOCK 5 35 | 36 | typedef struct journal_header_s 37 | { 38 | __be32 h_magic; 39 | __be32 h_blocktype; 40 | __be32 h_sequence; 41 | } journal_header_t; 42 | 43 | #define JBD2_CRC32_CHKSUM 1 44 | #define JBD2_MD5_CHKSUM 2 45 | #define JBD2_SHA1_CHKSUM 3 46 | 47 | #define JBD2_CRC32_CHKSUM_SIZE 4 48 | 49 | #define JBD2_CHECKSUM_BYTES (32 / sizeof(__u32)) 50 | 51 | struct commit_header { 52 | __be32 h_magic; 53 | __be32 h_blocktype; 54 | __be32 h_sequence; 55 | unsigned char h_chksum_type; 56 | unsigned char h_chksum_size; 57 | unsigned char h_padding[2]; 58 | __be32 h_chksum[JBD2_CHECKSUM_BYTES]; 59 | __be64 h_commit_sec; 60 | __be32 h_commit_nsec; 61 | }; 62 | 63 | typedef struct journal_block_tag_s 64 | { 65 | __be32 t_blocknr; 66 | __be32 t_flags; 67 | __be32 t_blocknr_high; 68 | } journal_block_tag_t; 69 | 70 | #define JBD2_TAG_SIZE32 (offsetof(journal_block_tag_t, t_blocknr_high)) 71 | #define JBD2_TAG_SIZE64 (sizeof(journal_block_tag_t)) 72 | 73 | typedef struct jbd2_journal_revoke_header_s 74 | { 75 | journal_header_t r_header; 76 | __be32 r_count; 77 | } jbd2_journal_revoke_header_t; 78 | 79 | #define JBD2_FLAG_ESCAPE 1 80 | #define JBD2_FLAG_SAME_UUID 2 81 | #define JBD2_FLAG_DELETED 4 82 | #define JBD2_FLAG_LAST_TAG 8 83 | 84 | typedef struct journal_superblock_s 85 | { 86 | 87 | journal_header_t s_header; 88 | 89 | __be32 s_blocksize; 90 | __be32 s_maxlen; 91 | __be32 s_first; 92 | 93 | __be32 s_sequence; 94 | __be32 s_start; 95 | 96 | __be32 s_errno; 97 | 98 | __be32 s_feature_compat; 99 | __be32 s_feature_incompat; 100 | __be32 s_feature_ro_compat; 101 | 102 | __u8 s_uuid[16]; 103 | 104 | __be32 s_nr_users; 105 | 106 | __be32 s_dynsuper; 107 | 108 | __be32 s_max_transaction; 109 | __be32 s_max_trans_data; 110 | 111 | __u32 s_padding[44]; 112 | 113 | __u8 s_users[16*48]; 114 | 115 | } journal_superblock_t; 116 | 117 | #define JBD2_HAS_COMPAT_FEATURE(j,mask) ((j)->j_format_version >= 2 && ((j)->j_superblock->s_feature_compat & cpu_to_be32((mask)))) 118 | #define JBD2_HAS_RO_COMPAT_FEATURE(j,mask) ((j)->j_format_version >= 2 && ((j)->j_superblock->s_feature_ro_compat & cpu_to_be32((mask)))) 119 | #define JBD2_HAS_INCOMPAT_FEATURE(j,mask) ((j)->j_format_version >= 2 && ((j)->j_superblock->s_feature_incompat & cpu_to_be32((mask)))) 120 | 121 | #define JBD2_FEATURE_COMPAT_CHECKSUM 0x00000001 122 | 123 | #define JBD2_FEATURE_INCOMPAT_REVOKE 0x00000001 124 | #define JBD2_FEATURE_INCOMPAT_64BIT 0x00000002 125 | #define JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT 0x00000004 126 | 127 | #define JBD2_KNOWN_COMPAT_FEATURES JBD2_FEATURE_COMPAT_CHECKSUM 128 | #define JBD2_KNOWN_ROCOMPAT_FEATURES 0 129 | #define JBD2_KNOWN_INCOMPAT_FEATURES (JBD2_FEATURE_INCOMPAT_REVOKE | JBD2_FEATURE_INCOMPAT_64BIT | JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT) 130 | 131 | #define BJ_None 0 132 | #define BJ_Metadata 1 133 | #define BJ_Forget 2 134 | #define BJ_IO 3 135 | #define BJ_Shadow 4 136 | #define BJ_LogCtl 5 137 | #define BJ_Reserved 6 138 | #define BJ_Types 7 139 | 140 | #endif 141 | 142 | -------------------------------------------------------------------------------- /extras/ext4_utils/make_ext4fs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 _MAKE_EXT4FS_H_ 18 | #define _MAKE_EXT4FS_H_ 19 | 20 | #ifdef __cplusplus 21 | extern "C" { 22 | #endif 23 | 24 | struct selabel_handle; 25 | 26 | int make_ext4fs(const char *filename, long long len, 27 | const char *mountpoint, struct selabel_handle *sehnd); 28 | int make_ext4fs_sparse_fd(int fd, long long len, 29 | const char *mountpoint, struct selabel_handle *sehnd); 30 | 31 | #ifdef __cplusplus 32 | } 33 | #endif 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /extras/ext4_utils/make_ext4fs_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2010 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 | #include 18 | #include 19 | #include 20 | #include 21 | 22 | #if defined(__linux__) 23 | #include 24 | #elif defined(__APPLE__) && defined(__MACH__) 25 | #include 26 | #endif 27 | 28 | #ifdef ANDROID 29 | #include 30 | #endif 31 | 32 | #ifndef USE_MINGW 33 | #include 34 | #include 35 | #include 36 | #else 37 | struct selabel_handle; 38 | #endif 39 | 40 | #include "make_ext4fs.h" 41 | #include "ext4_utils.h" 42 | #include "canned_fs_config.h" 43 | 44 | #ifndef USE_MINGW /* O_BINARY is windows-specific flag */ 45 | #define O_BINARY 0 46 | #endif 47 | 48 | extern struct fs_info info; 49 | 50 | 51 | static void usage(char *path) 52 | { 53 | fprintf(stderr, "%s [ -l ] [ -j ] [ -b ]\n", basename(path)); 54 | fprintf(stderr, " [ -g ] [ -i ] [ -I ]\n"); 55 | fprintf(stderr, " [ -L