Whamcloud - gitweb
Merge branch 'maint' into next
authorTheodore Ts'o <tytso@mit.edu>
Tue, 30 May 2017 00:43:01 +0000 (20:43 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 30 May 2017 00:43:01 +0000 (20:43 -0400)
119 files changed:
Android.bp [new file with mode: 0644]
Android.mk [deleted file]
MCONFIG.in
Makefile.in
configure
configure.ac
contrib/Android.bp [new file with mode: 0644]
contrib/Android.mk [deleted file]
contrib/android/Android.bp [new file with mode: 0644]
contrib/android/base_fs.c [new file with mode: 0644]
contrib/android/base_fs.h [new file with mode: 0644]
contrib/android/basefs_allocator.c [new file with mode: 0644]
contrib/android/basefs_allocator.h [new file with mode: 0644]
contrib/android/block_list.c [new file with mode: 0644]
contrib/android/block_list.h [new file with mode: 0644]
contrib/android/block_range.c [new file with mode: 0644]
contrib/android/block_range.h [new file with mode: 0644]
contrib/android/e2fsdroid.c [new file with mode: 0644]
contrib/android/ext2simg.c [new file with mode: 0644]
contrib/android/fsmap.c [new file with mode: 0644]
contrib/android/fsmap.h [new file with mode: 0644]
contrib/android/hashmap.c [new file with mode: 0644]
contrib/android/hashmap.h [new file with mode: 0644]
contrib/android/perms.c [new file with mode: 0644]
contrib/android/perms.h [new file with mode: 0644]
debugfs/Android.bp [new file with mode: 0644]
debugfs/Android.mk [deleted file]
debugfs/Makefile.in
debugfs/debugfs.c
debugfs/htree.c
debugfs/set_fields.c
e2fsck/Android.bp [new file with mode: 0644]
e2fsck/Android.mk [deleted file]
e2fsck/Makefile.in
e2fsck/e2fsck.h
e2fsck/message.c
e2fsck/pass1.c
e2fsck/pass2.c
e2fsck/pass5.c
e2fsck/problem.c
e2fsck/problem.h
e2fsck/rehash.c
ext2ed/doc/ext2ed-design.sgml
ext2ed/doc/ext2fs-overview.sgml
ext2ed/ext2.descriptors
include/nonunix/linux/types.h
intl/Makefile.in
lib/Android.bp [new file with mode: 0644]
lib/Android.mk [deleted file]
lib/blkid/Android.bp [new file with mode: 0644]
lib/blkid/Android.mk [deleted file]
lib/blkid/Makefile.in
lib/blkid/devname.c
lib/e2p/Android.bp [new file with mode: 0644]
lib/e2p/Android.mk [deleted file]
lib/e2p/Makefile.in
lib/et/Android.bp [new file with mode: 0644]
lib/et/Android.mk [deleted file]
lib/et/Makefile.in
lib/et/error_message.c
lib/ext2fs/Android.bp [new file with mode: 0644]
lib/ext2fs/Android.mk [deleted file]
lib/ext2fs/Makefile.in
lib/ext2fs/alloc.c
lib/ext2fs/bitops.h
lib/ext2fs/blkmap64_rb.c
lib/ext2fs/bmap.c
lib/ext2fs/ext2_fs.h
lib/ext2fs/ext2_io.h
lib/ext2fs/ext2fs.h
lib/ext2fs/flushb.c
lib/ext2fs/gen_bitmap.c
lib/ext2fs/jfs_compat.h
lib/ext2fs/sparse_io.c [new file with mode: 0644]
lib/ext2fs/swapfs.c
lib/ext2fs/test_io.c
lib/ext2fs/unix_io.c
lib/ss/Android.bp [new file with mode: 0644]
lib/ss/Android.mk [deleted file]
lib/ss/Makefile.in
lib/support/Android.bp [new file with mode: 0644]
lib/support/Android.mk [deleted file]
lib/support/Makefile.in
lib/uuid/Android.bp [new file with mode: 0644]
lib/uuid/Android.mk [deleted file]
lib/uuid/Makefile.in
misc/Android.bp [new file with mode: 0644]
misc/Android.mk [deleted file]
misc/Makefile.in
misc/create_inode.c
misc/create_inode.h
misc/mke2fs.c
misc/tune2fs.c
po/Makefile.in.in
po/at-expand.pl
resize/Android.bp [new file with mode: 0644]
resize/Android.mk [deleted file]
resize/Makefile.in
tests/Makefile.in
tests/d_fallocate_blkmap/expect
tests/d_inline_dump/expect
tests/d_special_files/expect
tests/f_badcluster/expect
tests/f_convert_bmap/expect.1
tests/f_convert_bmap_and_extent/expect.1
tests/f_convert_bmap_sparse/expect.1
tests/f_create_symlinks/expect
tests/f_large_dir/expect [new file with mode: 0644]
tests/f_large_dir/is_slow_test [new file with mode: 0644]
tests/f_large_dir/name [new file with mode: 0644]
tests/f_large_dir/script [new file with mode: 0644]
tests/f_mmp/is_slow_test [new file with mode: 0644]
tests/f_mmp_garbage/is_slow_test [new file with mode: 0644]
tests/f_recnect_bad/expect.1
tests/r_64bit_big_expand/is_slow_test [new file with mode: 0644]
tests/r_ext4_big_expand/is_slow_test [new file with mode: 0644]
tests/test_one.in
util/android_config.h
util/gen-android-files

diff --git a/Android.bp b/Android.bp
new file mode 100644 (file)
index 0000000..a095aea
--- /dev/null
@@ -0,0 +1,10 @@
+// Copyright 2017 The Android Open Source Project
+
+subdirs = [
+    "contrib",
+    "debugfs",
+    "e2fsck",
+    "lib",
+    "misc",
+    "resize",
+]
diff --git a/Android.mk b/Android.mk
deleted file mode 100644 (file)
index 5053e7d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
index e82963d..22b74eb 100644 (file)
@@ -4,6 +4,8 @@ all::
 
 check::
 
+fullcheck::
+
 SHELL = /bin/sh
 
 COMPRESS_EXT = gz bz2 bz Z
index 7da9ad7..37b6069 100644 (file)
@@ -78,8 +78,9 @@ coverage.txt: coverage.txt-recursive
 
 check-recursive: all
 
-TAGS clean-recursive distclean-recursive depend-recursive check-recursive \
-  mostlyclean-recursive realclean-recursive coverage.txt-recursive:
+TAGS clean-recursive distclean-recursive depend-recursive fullcheck-recursive \
+  check-recursive mostlyclean-recursive realclean-recursive \
+  coverage.txt-recursive:
        @for subdir in $(SUBDIRS); do \
          if test -d $$subdir ; then \
            target=`echo $@|$(SED) 's/-recursive//'`; \
@@ -151,3 +152,4 @@ realclean-local: distclean-local
 
 check::        all check-recursive
 
+fullcheck:: all fullcheck-recursive
index 5f7b429..818a8c7 100755 (executable)
--- a/configure
+++ b/configure
@@ -12368,7 +12368,7 @@ fi
 done
 
 fi
-for ac_header in       dirent.h        errno.h         execinfo.h      getopt.h        malloc.h        mntent.h        paths.h         semaphore.h     setjmp.h        signal.h        stdarg.h        stdint.h        stdlib.h        termios.h       termio.h        unistd.h        utime.h         attr/xattr.h    linux/falloc.h  linux/fd.h      linux/major.h   linux/loop.h    net/if_dl.h     netinet/in.h    sys/acl.h       sys/disklabel.h         sys/disk.h      sys/file.h      sys/ioctl.h     sys/key.h       sys/mkdev.h     sys/mman.h      sys/mount.h     sys/prctl.h     sys/resource.h  sys/select.h    sys/socket.h    sys/sockio.h    sys/stat.h      sys/syscall.h   sys/sysctl.h    sys/sysmacros.h         sys/time.h      sys/types.h     sys/un.h        sys/wait.h
+for ac_header in       dirent.h        errno.h         execinfo.h      getopt.h        malloc.h        mntent.h        paths.h         semaphore.h     setjmp.h        signal.h        stdarg.h        stdint.h        stdlib.h        termios.h       termio.h        unistd.h        utime.h         attr/xattr.h    linux/falloc.h  linux/fd.h      linux/major.h   linux/loop.h    linux/types.h   net/if_dl.h     netinet/in.h    sys/acl.h       sys/disklabel.h         sys/disk.h      sys/file.h      sys/ioctl.h     sys/key.h       sys/mkdev.h     sys/mman.h      sys/mount.h     sys/prctl.h     sys/resource.h  sys/select.h    sys/socket.h    sys/sockio.h    sys/stat.h      sys/syscall.h   sys/sysctl.h    sys/sysmacros.h         sys/time.h      sys/types.h     sys/un.h        sys/wait.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -13073,7 +13073,7 @@ fi
 if test -n "$DLOPEN_LIB" ; then
    ac_cv_func_dlopen=yes
 fi
-for ac_func in         __secure_getenv         add_key         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         dlopen  fadvise64       fallocate       fallocate64     fchown  fdatasync       fstat64         ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         keyctl  llistxattr      llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   pread   pwrite  pread64         pwrite64        secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   utimes  valloc
+for ac_func in         __secure_getenv         add_key         backtrace       blkid_probe_get_topology        blkid_probe_enable_partitions   chflags         dlopen  fadvise64       fallocate       fallocate64     fchown  fcntl   fdatasync       fstat64         fsync   ftruncate64     futimes         getcwd  getdtablesize   getmntinfo      getpwuid_r      getrlimit       getrusage       jrand48         keyctl  llistxattr      llseek  lseek64         mallinfo        mbstowcs        memalign        mempcpy         mmap    msync   nanosleep       open64  pathconf        posix_fadvise   posix_fadvise64         posix_memalign  prctl   pread   pwrite  pread64         pwrite64        secure_getenv   setmntent       setresgid       setresuid       snprintf        srandom         stpcpy  strcasecmp      strdup  strnlen         strptime        strtoull        sync_file_range         sysconf         usleep  utime   utimes  valloc
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
index 9da7b86..4c994da 100644 (file)
@@ -920,6 +920,7 @@ AC_CHECK_HEADERS(m4_flatten([
        linux/fd.h
        linux/major.h
        linux/loop.h
+       linux/types.h
        net/if_dl.h
        netinet/in.h
        sys/acl.h
@@ -1094,8 +1095,10 @@ AC_CHECK_FUNCS(m4_flatten([
        fallocate
        fallocate64
        fchown
+       fcntl
        fdatasync
        fstat64
+       fsync
        ftruncate64
        futimes
        getcwd
diff --git a/contrib/Android.bp b/contrib/Android.bp
new file mode 100644 (file)
index 0000000..c2d5cd9
--- /dev/null
@@ -0,0 +1,37 @@
+// Copyright 2017 The Android Open Source Project
+
+subdirs = ["android"]
+
+//##########################################################################
+// Build fsstress
+
+cc_binary {
+    name: "fsstress",
+    host_supported: true,
+
+    srcs: ["fsstress.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    system_shared_libs: ["libc"],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+//########################################################################
+// Build add_ext4_encrypt
+
+cc_binary {
+    name: "add_ext4_encrypt",
+    host_supported: true,
+
+    srcs: ["add_ext4_encrypt.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+    ],
+    system_shared_libs: ["libc"],
+}
diff --git a/contrib/Android.mk b/contrib/Android.mk
deleted file mode 100644 (file)
index f8d74c3..0000000
+++ /dev/null
@@ -1,80 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-###########################################################################
-# Build fsstress
-#
-fsstress_src_files := \
-       fsstress.c
-
-fsstress_c_includes := 
-
-fsstress_cflags := -O2 -g -W -Wall
-
-fsstress_shared_libraries := 
-
-fsstress_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(fsstress_src_files)
-mke2fs_c_includesLOCAL_CFLAGS := $(fsstress_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(fsstress_system_shared_libraries)
-LOCAL_MODULE := fsstress
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(fsstress_src_files)
-LOCAL_CFLAGS := $(fsstress_cflags)
-LOCAL_MODULE := fsstress_host
-LOCAL_MODULE_STEM := fsstress
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_HOST_OS := linux
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#########################################################################
-# Build add_ext4_encrypt
-#
-include $(CLEAR_VARS)
-
-add_ext4_encrypt_src_files := \
-       add_ext4_encrypt.c
-
-add_ext4_encrypt_c_includes := \
-       external/e2fsprogs/lib
-
-add_ext4_encrypt_cflags := -O2 -g -W -Wall
-
-add_ext4_encrypt_shared_libraries := \
-       libext2fs \
-       libext2_com_err
-
-add_ext4_encrypt_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(add_ext4_encrypt_src_files)
-LOCAL_C_INCLUDES := $(add_ext4_encrypt_c_includes)
-LOCAL_CFLAGS := $(add_ext4_encrypt_cflags)
-LOCAL_SHARED_LIBRARIES := $(add_ext4_encrypt_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(add_ext4_encrypt_system_shared_libraries)
-LOCAL_MODULE := add_ext4_encrypt
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(add_ext4_encrypt_src_files)
-LOCAL_C_INCLUDES := $(add_ext4_encrypt_c_includes)
-LOCAL_CFLAGS := $(add_ext4_encrypt_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(add_ext4_encrypt_shared_libraries))
-LOCAL_MODULE := add_ext4_encrypt_host
-LOCAL_MODULE_STEM := add_ext4_encrypt
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
diff --git a/contrib/android/Android.bp b/contrib/android/Android.bp
new file mode 100644 (file)
index 0000000..afa335e
--- /dev/null
@@ -0,0 +1,55 @@
+// Copyright 2017 The Android Open Source Project
+
+//##########################################################################
+// Build e2fsdroid
+
+cc_binary {
+    name: "e2fsdroid",
+    host_supported: true,
+
+    srcs: [
+        "e2fsdroid.c",
+        "block_range.c",
+        "fsmap.c",
+        "block_list.c",
+        "base_fs.c",
+        "perms.c",
+        "basefs_allocator.c",
+        "hashmap.c",
+    ],
+    cflags: ["-W", "-Wall"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+        "libext2_misc",
+        "libcutils",
+        "libbase",
+        "libselinux",
+        "libcrypto",
+    ],
+}
+
+//##########################################################################
+// Build ext2simg
+
+cc_binary {
+    name: "ext2simg",
+    host_supported: true,
+
+    srcs: ["ext2simg.c"],
+    cflags: ["-W", "-Wall"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+        "libsparse",
+    ],
+
+    target: {
+        host: {
+            shared_libs: ["libz-host"],
+        },
+        android: {
+            shared_libs: ["libz"],
+        },
+    },
+}
diff --git a/contrib/android/base_fs.c b/contrib/android/base_fs.c
new file mode 100644 (file)
index 0000000..2dcb5fe
--- /dev/null
@@ -0,0 +1,207 @@
+#include "base_fs.h"
+#include <stdio.h>
+
+#define BASE_FS_VERSION "Base EXT4 version 1.0"
+
+struct base_fs {
+       FILE *file;
+       const char *mountpoint;
+       struct basefs_entry entry;
+};
+
+static FILE *basefs_open(const char *file)
+{
+       char *line = NULL;
+       size_t len;
+       FILE *f = fopen(file, "r");
+       if (!f)
+               return NULL;
+
+       if (getline(&line, &len, f) == -1 || !line)
+               goto err_getline;
+
+       if (strncmp(line, BASE_FS_VERSION, strlen(BASE_FS_VERSION)))
+               goto err_header;
+
+       free(line);
+       return f;
+
+err_header:
+       free(line);
+err_getline:
+       fclose(f);
+       return NULL;
+}
+
+static struct basefs_entry *basefs_readline(FILE *f, const char *mountpoint,
+                                           int *err)
+{
+       char *line = NULL, *saveptr1, *saveptr2, *block_range, *block;
+       int offset;
+       size_t len;
+       struct basefs_entry *entry = NULL;
+       blk64_t range_start, range_end;
+
+       if (getline(&line, &len, f) == -1) {
+               if (feof(f))
+                       goto end;
+               goto err_getline;
+       }
+
+       entry = calloc(1, sizeof(*entry));
+       if (!entry)
+               goto err_alloc;
+
+       /*
+        * With BASEFS version 1.0, a typical line looks like this:
+        * /bin/mke2fs 5000-5004,8000,9000-9990
+        */
+       if (sscanf(line, "%ms%n", &entry->path, &offset) != 1)
+               goto err_sscanf;
+       len = strlen(mountpoint);
+       memmove(entry->path, entry->path + len, strlen(entry->path) - len + 1);
+
+       while (line[offset] == ' ')
+               ++offset;
+
+       block_range = strtok_r(line + offset, ",\n", &saveptr1);
+       while (block_range) {
+               block = strtok_r(block_range, "-", &saveptr2);
+               if (!block)
+                       break;
+               range_start = atoll(block);
+               block = strtok_r(NULL, "-", &saveptr2);
+               range_end = block ? atoll(block) : range_start;
+               add_blocks_to_range(&entry->head, &entry->tail, range_start,
+                                   range_end);
+               block_range = strtok_r(NULL, ",\n", &saveptr1);
+       }
+end:
+       *err = 0;
+       free(line);
+       return entry;
+
+err_sscanf:
+       free(entry);
+err_alloc:
+       free(line);
+err_getline:
+       *err = 1;
+       return NULL;
+}
+
+static void free_base_fs_entry(void *e)
+{
+       struct basefs_entry *entry = e;
+       if (entry) {
+               free(entry->path);
+               free(entry);
+       }
+}
+
+struct hashmap *basefs_parse(const char *file, const char *mountpoint)
+{
+       int err;
+       struct hashmap *entries = NULL;
+       struct basefs_entry *entry;
+       FILE *f = basefs_open(file);
+       if (!f)
+               return NULL;
+       entries = hashmap_create(djb2_hash, free_base_fs_entry, 1024);
+       if (!entries)
+               goto end;
+
+       while ((entry = basefs_readline(f, mountpoint, &err)))
+               hashmap_add(entries, entry, entry->path);
+
+       if (err) {
+               fclose(f);
+               hashmap_free(entries);
+               return NULL;
+       }
+end:
+       fclose(f);
+       return entries;
+}
+
+static void *init(const char *file, const char *mountpoint)
+{
+       struct base_fs *params = malloc(sizeof(*params));
+
+       if (!params)
+               return NULL;
+       params->mountpoint = mountpoint;
+       params->file = fopen(file, "w+");
+       if (!params->file) {
+               free(params);
+               return NULL;
+       }
+       if (fwrite(BASE_FS_VERSION"\n", 1, strlen(BASE_FS_VERSION"\n"),
+                  params->file) != strlen(BASE_FS_VERSION"\n")) {
+               fclose(params->file);
+               free(params);
+               return NULL;
+       }
+       return params;
+}
+
+static int start_new_file(char *path, ext2_ino_t ino EXT2FS_ATTR((unused)),
+                         struct ext2_inode *inode, void *data)
+{
+       struct base_fs *params = data;
+
+       params->entry.head = params->entry.tail = NULL;
+       params->entry.path = LINUX_S_ISREG(inode->i_mode) ? path : NULL;
+       return 0;
+}
+
+static int add_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk64_t blocknr,
+                    int metadata, void *data)
+{
+       struct base_fs *params = data;
+
+       if (params->entry.path && !metadata)
+               add_blocks_to_range(&params->entry.head, &params->entry.tail,
+                                   blocknr, blocknr);
+       return 0;
+}
+
+static int inline_data(void *inline_data EXT2FS_ATTR((unused)),
+                      void *data EXT2FS_ATTR((unused)))
+{
+       return 0;
+}
+
+static int end_new_file(void *data)
+{
+       struct base_fs *params = data;
+
+       if (!params->entry.path)
+               return 0;
+       if (fprintf(params->file, "%s%s ", params->mountpoint,
+                   params->entry.path) < 0
+           || write_block_ranges(params->file, params->entry.head, ",")
+           || fwrite("\n", 1, 1, params->file) != 1)
+               return -1;
+
+       delete_block_ranges(params->entry.head);
+       return 0;
+}
+
+static int cleanup(void *data)
+{
+       struct base_fs *params = data;
+
+       fclose(params->file);
+       free(params);
+       return 0;
+}
+
+struct fsmap_format base_fs_format = {
+       .init = init,
+       .start_new_file = start_new_file,
+       .add_block = add_block,
+       .inline_data = inline_data,
+       .end_new_file = end_new_file,
+       .cleanup = cleanup,
+};
diff --git a/contrib/android/base_fs.h b/contrib/android/base_fs.h
new file mode 100644 (file)
index 0000000..94bae29
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef BASE_FS_H
+# define BASE_FS_H
+
+# include "fsmap.h"
+# include "hashmap.h"
+# include "block_range.h"
+
+struct basefs_entry {
+       char *path;
+       struct block_range *head;
+       struct block_range *tail;
+};
+
+extern struct fsmap_format base_fs_format;
+
+struct hashmap *basefs_parse(const char *file, const char *mountpoint);
+
+#endif /* !BASE_FS_H */
diff --git a/contrib/android/basefs_allocator.c b/contrib/android/basefs_allocator.c
new file mode 100644 (file)
index 0000000..3d014a2
--- /dev/null
@@ -0,0 +1,147 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include "basefs_allocator.h"
+#include "block_range.h"
+#include "hashmap.h"
+#include "base_fs.h"
+
+struct base_fs_allocator {
+       struct hashmap *entries;
+       struct basefs_entry *cur_entry;
+};
+
+static errcode_t basefs_block_allocator(ext2_filsys, blk64_t, blk64_t *,
+                                       struct blk_alloc_ctx *ctx);
+
+static void fs_free_blocks_range(ext2_filsys fs, struct block_range *blocks)
+{
+       while (blocks) {
+               ext2fs_unmark_block_bitmap_range2(fs->block_map, blocks->start,
+                       blocks->end - blocks->start + 1);
+               blocks = blocks->next;
+       }
+}
+
+static void fs_reserve_blocks_range(ext2_filsys fs, struct block_range *blocks)
+{
+       while (blocks) {
+               ext2fs_mark_block_bitmap_range2(fs->block_map,
+                       blocks->start, blocks->end - blocks->start + 1);
+               blocks = blocks->next;
+       }
+}
+
+errcode_t base_fs_alloc_load(ext2_filsys fs, const char *file,
+                            const char *mountpoint)
+{
+       errcode_t retval;
+       struct basefs_entry *e;
+       struct hashmap_entry *it = NULL;
+       struct base_fs_allocator *allocator;
+       struct hashmap *entries = basefs_parse(file, mountpoint);
+       if (!entries)
+               return -1;
+
+       allocator = malloc(sizeof(*allocator));
+       if (!allocator)
+               goto err_alloc;
+
+       retval = ext2fs_read_bitmaps(fs);
+       if (retval)
+               goto err_bitmap;
+       while ((e = hashmap_iter_in_order(entries, &it)))
+               fs_reserve_blocks_range(fs, e->head);
+
+       allocator->cur_entry = NULL;
+       allocator->entries = entries;
+
+       /* Overhide the default allocator */
+       fs->get_alloc_block2 = basefs_block_allocator;
+       fs->priv_data = allocator;
+
+       return 0;
+
+err_bitmap:
+       free(allocator);
+err_alloc:
+       hashmap_free(entries);
+       return EXIT_FAILURE;
+}
+
+static errcode_t basefs_block_allocator(ext2_filsys fs, blk64_t goal,
+                                       blk64_t *ret, struct blk_alloc_ctx *ctx)
+{
+       errcode_t retval;
+       struct block_range *next_range;
+       struct base_fs_allocator *allocator = fs->priv_data;
+       struct basefs_entry *e = allocator->cur_entry;
+
+       /* Try to get a block from the base_fs */
+       if (e && e->head && ctx && (ctx->flags & BLOCK_ALLOC_DATA)) {
+               *ret = e->head->start;
+               e->head->start += 1;
+               if (e->head->start > e->head->end) {
+                       next_range = e->head->next;
+                       free(e->head);
+                       e->head = next_range;
+               }
+       } else { /* Allocate a new block */
+               retval = ext2fs_new_block2(fs, goal, fs->block_map, ret);
+               if (retval)
+                       return retval;
+               ext2fs_mark_block_bitmap2(fs->block_map, *ret);
+       }
+       return 0;
+}
+
+void base_fs_alloc_cleanup(ext2_filsys fs)
+{
+       struct basefs_entry *e;
+       struct hashmap_entry *it = NULL;
+       struct base_fs_allocator *allocator = fs->priv_data;
+
+       while ((e = hashmap_iter_in_order(allocator->entries, &it))) {
+               fs_free_blocks_range(fs, e->head);
+               delete_block_ranges(e->head);
+               e->head = e->tail = NULL;
+       }
+
+       fs->priv_data = NULL;
+       fs->get_alloc_block2 = NULL;
+       hashmap_free(allocator->entries);
+       free(allocator);
+}
+
+errcode_t base_fs_alloc_set_target(ext2_filsys fs, const char *target_path,
+       const char *name EXT2FS_ATTR((unused)),
+       ext2_ino_t parent_ino EXT2FS_ATTR((unused)),
+       ext2_ino_t root EXT2FS_ATTR((unused)), mode_t mode)
+{
+       struct base_fs_allocator *allocator = fs->priv_data;
+
+       if (mode != S_IFREG)
+               return 0;
+
+       if (allocator)
+               allocator->cur_entry = hashmap_lookup(allocator->entries,
+                                                     target_path);
+       return 0;
+}
+
+errcode_t base_fs_alloc_unset_target(ext2_filsys fs,
+        const char *target_path EXT2FS_ATTR((unused)),
+       const char *name EXT2FS_ATTR((unused)),
+       ext2_ino_t parent_ino EXT2FS_ATTR((unused)),
+       ext2_ino_t root EXT2FS_ATTR((unused)), mode_t mode)
+{
+       struct base_fs_allocator *allocator = fs->priv_data;
+
+       if (!allocator || !allocator->cur_entry || mode != S_IFREG)
+               return 0;
+
+       fs_free_blocks_range(fs, allocator->cur_entry->head);
+       delete_block_ranges(allocator->cur_entry->head);
+       allocator->cur_entry->head = allocator->cur_entry->tail = NULL;
+       allocator->cur_entry = NULL;
+       return 0;
+}
diff --git a/contrib/android/basefs_allocator.h b/contrib/android/basefs_allocator.h
new file mode 100644 (file)
index 0000000..f1109cd
--- /dev/null
@@ -0,0 +1,16 @@
+#ifndef BASE_FS_ALLOCATOR_H
+# define BASE_FS_ALLOCATOR_H
+
+# include <time.h>
+# include <ext2fs/ext2fs.h>
+
+errcode_t base_fs_alloc_load(ext2_filsys fs, const char *file,
+                            const char *mountpoint);
+void base_fs_alloc_cleanup(ext2_filsys fs);
+
+errcode_t base_fs_alloc_set_target(ext2_filsys fs, const char *target_path,
+       const char *name, ext2_ino_t parent_ino, ext2_ino_t root, mode_t mode);
+errcode_t base_fs_alloc_unset_target(ext2_filsys fs, const char *target_path,
+       const char *name, ext2_ino_t parent_ino, ext2_ino_t root, mode_t mode);
+
+#endif /* !BASE_FS_ALLOCATOR_H */
diff --git a/contrib/android/block_list.c b/contrib/android/block_list.c
new file mode 100644 (file)
index 0000000..25dcc51
--- /dev/null
@@ -0,0 +1,94 @@
+#include "block_list.h"
+#include "block_range.h"
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+struct block_list {
+       FILE *f;
+       const char *mountpoint;
+
+       struct {
+               const char *filename;
+               struct block_range *head;
+               struct block_range *tail;
+       } entry;
+};
+
+static void *init(const char *file, const char *mountpoint)
+{
+       struct block_list *params = malloc(sizeof(*params));
+
+       if (!params)
+               return NULL;
+       params->mountpoint = mountpoint;
+       params->f = fopen(file, "w+");
+       if (!params->f) {
+               free(params);
+               return NULL;
+       }
+       return params;
+}
+
+static int start_new_file(char *path, ext2_ino_t ino EXT2FS_ATTR((unused)),
+                         struct ext2_inode *inode EXT2FS_ATTR((unused)),
+                         void *data)
+{
+       struct block_list *params = data;
+
+       params->entry.head = params->entry.tail = NULL;
+       params->entry.filename = LINUX_S_ISREG(inode->i_mode) ? path : NULL;
+       return 0;
+}
+
+static int add_block(ext2_filsys fs EXT2FS_ATTR((unused)), blk64_t blocknr,
+                    int metadata, void *data)
+{
+       struct block_list *params = data;
+
+       if (params->entry.filename && !metadata)
+               add_blocks_to_range(&params->entry.head, &params->entry.tail,
+                                   blocknr, blocknr);
+       return 0;
+}
+
+static int inline_data(void *inline_data EXT2FS_ATTR((unused)),
+                      void *data EXT2FS_ATTR((unused)))
+{
+       return 0;
+}
+
+static int end_new_file(void *data)
+{
+       struct block_list *params = data;
+
+       if (!params->entry.filename || !params->entry.head)
+               return 0;
+       if (fprintf(params->f, "%s%s ", params->mountpoint,
+                   params->entry.filename) < 0
+           || write_block_ranges(params->f, params->entry.head, " ")
+           || fwrite("\n", 1, 1, params->f) != 1)
+               return -1;
+
+       delete_block_ranges(params->entry.head);
+       return 0;
+}
+
+static int cleanup(void *data)
+{
+       struct block_list *params = data;
+
+       fclose(params->f);
+       free(params);
+       return 0;
+}
+
+struct fsmap_format block_list_format = {
+       .init = init,
+       .start_new_file = start_new_file,
+       .add_block = add_block,
+       .inline_data = inline_data,
+       .end_new_file = end_new_file,
+       .cleanup = cleanup,
+};
diff --git a/contrib/android/block_list.h b/contrib/android/block_list.h
new file mode 100644 (file)
index 0000000..47041e4
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef BLOCK_LIST_H
+# define BLOCK_LIST_H
+
+# include "fsmap.h"
+
+extern struct fsmap_format block_list_format;
+
+#endif /* !BLOCK_LIST_H */
diff --git a/contrib/android/block_range.c b/contrib/android/block_range.c
new file mode 100644 (file)
index 0000000..2f951c7
--- /dev/null
@@ -0,0 +1,64 @@
+#define _GNU_SOURCE
+
+#include "block_range.h"
+#include <stdio.h>
+
+struct block_range *new_block_range(blk64_t start, blk64_t end)
+{
+       struct block_range *range = malloc(sizeof(*range));
+       range->start = start;
+       range->end = end;
+       range->next = NULL;
+       return range;
+}
+
+void add_blocks_to_range(struct block_range **head, struct block_range **tail,
+                        blk64_t blk_start, blk64_t blk_end)
+{
+       if (*head == NULL)
+               *head = *tail = new_block_range(blk_start, blk_end);
+       else if ((*tail)->end + 1 == blk_start)
+               (*tail)->end += (blk_end - blk_start + 1);
+       else {
+               struct block_range *range = new_block_range(blk_start, blk_end);
+               (*tail)->next = range;
+               *tail = range;
+       }
+}
+
+void delete_block_ranges(struct block_range *head)
+{
+       struct block_range *tmp;
+
+       while (head) {
+               tmp = head->next;
+               free(head);
+               head = tmp;
+       }
+}
+
+int write_block_ranges(FILE *f, struct block_range *range,
+                                    char *sep)
+{
+       int len;
+       char *buf;
+
+       while (range) {
+               if (range->start == range->end)
+                       len = asprintf(&buf, "%llu%s", range->start, sep);
+               else
+                       len = asprintf(&buf, "%llu-%llu%s", range->start,
+                                      range->end, sep);
+               if (fwrite(buf, 1, len, f) != (size_t)len) {
+                       free(buf);
+                       return -1;
+               }
+               free(buf);
+               range = range->next;
+       }
+
+       len = strlen(sep);
+       if (fseek(f, -len, SEEK_CUR) == -len)
+               return -1;
+       return 0;
+}
diff --git a/contrib/android/block_range.h b/contrib/android/block_range.h
new file mode 100644 (file)
index 0000000..31e3c23
--- /dev/null
@@ -0,0 +1,18 @@
+#ifndef BLOCK_RANGE_H
+# define BLOCK_RANGE_H
+
+# include <sys/types.h>
+# include <ext2fs/ext2fs.h>
+
+struct block_range {
+       blk64_t start;
+       blk64_t end;
+       struct block_range *next;
+};
+
+void add_blocks_to_range(struct block_range **head, struct block_range **tail,
+                        blk64_t blk_start, blk64_t blk_end);
+void delete_block_ranges(struct block_range *head);
+int write_block_ranges(FILE *f, struct block_range *range, char *sep);
+
+#endif /* !BLOCK_RANGE_H */
diff --git a/contrib/android/e2fsdroid.c b/contrib/android/e2fsdroid.c
new file mode 100644 (file)
index 0000000..1ae133d
--- /dev/null
@@ -0,0 +1,194 @@
+#include <stdio.h>
+#include <getopt.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <ext2fs/ext2fs.h>
+
+#include "perms.h"
+#include "base_fs.h"
+#include "block_list.h"
+#include "basefs_allocator.h"
+#include "create_inode.h"
+
+static char *prog_name = "e2fsdroid";
+static char *in_file;
+static char *block_list;
+static char *basefs_out;
+static char *basefs_in;
+static char *mountpoint = "";
+static time_t fixed_time = -1;
+static char *fs_config_file;
+static struct selinux_opt seopt_file[8];
+static int max_nr_opt = (int)sizeof(seopt_file) / sizeof(seopt_file[0]);
+static char *product_out;
+static char *src_dir;
+static int android_configure;
+static int android_sparse_file = 1;
+
+static void usage(int ret)
+{
+       fprintf(stderr, "%s [-B block_list] [-D basefs_out] [-T timestamp]\n"
+                       "\t[-C fs_config] [-S file_contexts] [-p product_out]\n"
+                       "\t[-a mountpoint] [-d basefs_in] [-f src_dir] [-e] image\n",
+                prog_name);
+       exit(ret);
+}
+
+static char *absolute_path(const char *file)
+{
+       char *ret;
+       char cwd[PATH_MAX];
+
+       if (file[0] != '/') {
+               getcwd(cwd, PATH_MAX);
+               ret = malloc(strlen(cwd) + 1 + strlen(file) + 1);
+               if (ret)
+                       sprintf(ret, "%s/%s", cwd, file);
+       } else
+               ret = strdup(file);
+       return ret;
+}
+
+int main(int argc, char *argv[])
+{
+       int c;
+       char *p;
+       int flags = EXT2_FLAG_RW;
+       errcode_t retval;
+       io_manager io_mgr;
+       ext2_filsys fs = NULL;
+       struct fs_ops_callbacks fs_callbacks = { NULL, NULL };
+       char *token;
+       int nr_opt = 0;
+
+       add_error_table(&et_ext2_error_table);
+
+       while ((c = getopt (argc, argv, "T:C:S:p:a:D:d:B:f:e")) != EOF) {
+               switch (c) {
+               case 'T':
+                       fixed_time = strtoul(optarg, &p, 0);
+                       android_configure = 1;
+                       break;
+               case 'C':
+                       fs_config_file = absolute_path(optarg);
+                       android_configure = 1;
+                       break;
+               case 'S':
+                       token = strtok(optarg, ",");
+                       while (token) {
+                               if (nr_opt == max_nr_opt) {
+                                       fprintf(stderr, "Expected at most %d selinux opts\n",
+                                               max_nr_opt);
+                                       exit(EXIT_FAILURE);
+                               }
+                               seopt_file[nr_opt].type = SELABEL_OPT_PATH;
+                               seopt_file[nr_opt].value = absolute_path(token);
+                               nr_opt++;
+                               token = strtok(NULL, ",");
+                       }
+                       android_configure = 1;
+                       break;
+               case 'p':
+                       product_out = absolute_path(optarg);
+                       break;
+               case 'a':
+                       mountpoint = strdup(optarg);
+                       break;
+               case 'D':
+                       basefs_out = absolute_path(optarg);
+                       break;
+               case 'd':
+                       basefs_in = absolute_path(optarg);
+                       break;
+               case 'B':
+                       block_list = absolute_path(optarg);
+                       break;
+               case 'f':
+                       src_dir = absolute_path(optarg);
+                       break;
+               case 'e':
+                       android_sparse_file = 0;
+                       break;
+               default:
+                       usage(EXIT_FAILURE);
+               }
+       }
+       if (optind >= argc) {
+               fprintf(stderr, "Expected filename after options\n");
+               exit(EXIT_FAILURE);
+       }
+       in_file = strdup(argv[optind]);
+
+       io_mgr = android_sparse_file ? sparse_io_manager: unix_io_manager;
+       retval = ext2fs_open(in_file, flags, 0, 0, io_mgr, &fs);
+       if (retval) {
+               com_err(prog_name, retval, "while opening file %s\n", in_file);
+               return retval;
+       }
+
+       if (src_dir) {
+               ext2fs_read_bitmaps(fs);
+               if (basefs_in) {
+                       retval = base_fs_alloc_load(fs, basefs_in, mountpoint);
+                       if (retval) {
+                               com_err(prog_name, retval, "%s",
+                               "while reading base_fs file");
+                           exit(1);
+                       }
+                       fs_callbacks.create_new_inode =
+                               base_fs_alloc_set_target;
+                       fs_callbacks.end_create_new_inode =
+                               base_fs_alloc_unset_target;
+               }
+               retval = populate_fs2(fs, EXT2_ROOT_INO, src_dir,
+                                     EXT2_ROOT_INO, &fs_callbacks);
+               if (retval) {
+                       com_err(prog_name, retval, "%s",
+                       "while populating file system");
+                   exit(1);
+               }
+               if (basefs_in)
+                       base_fs_alloc_cleanup(fs);
+       }
+
+       if (android_configure) {
+               retval = android_configure_fs(fs, src_dir, product_out, mountpoint,
+                       seopt_file, nr_opt, fs_config_file, fixed_time);
+               if (retval) {
+                       com_err(prog_name, retval, "%s",
+                               "while configuring the file system");
+                       exit(1);
+               }
+       }
+
+       if (block_list) {
+               retval = fsmap_iter_filsys(fs, &block_list_format, block_list,
+                                          mountpoint);
+               if (retval) {
+                       com_err(prog_name, retval, "%s",
+                               "while creating the block_list");
+                       exit(1);
+               }
+       }
+
+       if (basefs_out) {
+               retval = fsmap_iter_filsys(fs, &base_fs_format,
+                                          basefs_out, mountpoint);
+               if (retval) {
+                       com_err(prog_name, retval, "%s",
+                               "while creating the basefs file");
+                       exit(1);
+               }
+       }
+
+       retval = ext2fs_close_free(&fs);
+       if (retval) {
+               com_err(prog_name, retval, "%s",
+                               "while writing superblocks");
+               exit(1);
+       }
+
+       remove_error_table(&et_ext2_error_table);
+       return 0;
+}
diff --git a/contrib/android/ext2simg.c b/contrib/android/ext2simg.c
new file mode 100644 (file)
index 0000000..fcefe1d
--- /dev/null
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <libgen.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <ext2fs/ext2fs.h>
+#include <et/com_err.h>
+#include <sparse/sparse.h>
+
+struct {
+       int     crc;
+       int     sparse;
+       int     gzip;
+       char    *in_file;
+       char    *out_file;
+       bool    overwrite_input;
+} params = {
+       .crc        = 0,
+       .sparse     = 1,
+       .gzip       = 0,
+};
+
+#define ext2fs_fatal(Retval, Format, ...) \
+       do { \
+               com_err("error", Retval, Format, __VA_ARGS__); \
+               exit(EXIT_FAILURE); \
+       } while(0)
+
+#define sparse_fatal(Format) \
+       do { \
+               fprintf(stderr, "sparse: "Format); \
+               exit(EXIT_FAILURE); \
+       } while(0)
+
+static void usage(char *path)
+{
+       char *progname = basename(path);
+
+       fprintf(stderr, "%s [ options ] <image or block device> <output image>\n"
+                       "  -c include CRC block\n"
+                       "  -z gzip output\n"
+                       "  -S don't use sparse output format\n", progname);
+}
+
+static struct buf_item {
+       struct buf_item     *next;
+       void                *buf[0];
+} *buf_list;
+
+static void add_chunk(ext2_filsys fs, struct sparse_file *s, blk_t chunk_start, blk_t chunk_end)
+{
+       int retval;
+       unsigned int nb_blk = chunk_end - chunk_start;
+       size_t len = nb_blk * fs->blocksize;
+       int64_t offset = (int64_t)chunk_start * (int64_t)fs->blocksize;
+
+       if (params.overwrite_input == false) {
+               if (sparse_file_add_file(s, params.in_file, offset, len, chunk_start) < 0)
+                       sparse_fatal("adding data to the sparse file");
+       } else {
+               /*
+                * The input file will be overwritten, make a copy of
+                * the blocks
+                */
+               struct buf_item *bi = calloc(1, sizeof(struct buf_item) + len);
+               if (buf_list == NULL)
+                       buf_list = bi;
+               else {
+                       bi->next = buf_list;
+                       buf_list = bi;
+               }
+
+               retval = io_channel_read_blk64(fs->io, chunk_start, nb_blk, bi->buf);
+               if (retval < 0)
+                       ext2fs_fatal(retval, "reading block %u - %u", chunk_start, chunk_end);
+
+               if (sparse_file_add_data(s, bi->buf, len, chunk_start) < 0)
+                       sparse_fatal("adding data to the sparse file");
+       }
+}
+
+static void free_chunks(void)
+{
+       struct buf_item *bi;
+
+       while (buf_list) {
+               bi = buf_list->next;
+               free(buf_list);
+               buf_list = bi;
+       }
+}
+
+static struct sparse_file *ext_to_sparse(const char *in_file)
+{
+       errcode_t retval;
+       ext2_filsys fs;
+       struct sparse_file *s;
+       int64_t chunk_start = -1;
+       blk_t first_blk, last_blk, nb_blk, cur_blk;
+
+       retval = ext2fs_open(in_file, 0, 0, 0, unix_io_manager, &fs);
+       if (retval)
+               ext2fs_fatal(retval, "while reading %s", in_file);
+
+       retval = ext2fs_read_block_bitmap(fs);
+       if (retval)
+               ext2fs_fatal(retval, "while reading block bitmap of %s", in_file);
+
+       first_blk = ext2fs_get_block_bitmap_start2(fs->block_map);
+       last_blk = ext2fs_get_block_bitmap_end2(fs->block_map);
+       nb_blk = last_blk - first_blk + 1;
+
+       s = sparse_file_new(fs->blocksize, (uint64_t)fs->blocksize * (uint64_t)nb_blk);
+       if (!s)
+               sparse_fatal("creating sparse file");
+
+       /*
+        * The sparse format encodes the size of a chunk (and its header) in a
+        * 32-bit unsigned integer (UINT32_MAX)
+        * When writing the chunk, the library uses a single call to write().
+        * Linux's implementation of the 'write' syscall does not allow transfers
+        * larger than INT32_MAX (32-bit _and_ 64-bit systems).
+        * Make sure we do not create chunks larger than this limit.
+        */
+       int64_t max_blk_per_chunk = (INT32_MAX - 12) / fs->blocksize;
+
+       /* Iter on the blocks to merge contiguous chunk */
+       for (cur_blk = first_blk; cur_blk <= last_blk; ++cur_blk) {
+               if (ext2fs_test_block_bitmap2(fs->block_map, cur_blk)) {
+                       if (chunk_start == -1) {
+                               chunk_start = cur_blk;
+                       } else if (cur_blk - chunk_start + 1 == max_blk_per_chunk) {
+                               add_chunk(fs, s, chunk_start, cur_blk);
+                               chunk_start = -1;
+                       }
+               } else if (chunk_start != -1) {
+                       add_chunk(fs, s, chunk_start, cur_blk);
+                       chunk_start = -1;
+               }
+       }
+       if (chunk_start != -1)
+               add_chunk(fs, s, chunk_start, cur_blk - 1);
+
+       ext2fs_free(fs);
+       return s;
+}
+
+static bool same_file(const char *in, const char *out)
+{
+       struct stat st1, st2;
+
+       if (access(out, F_OK) == -1)
+               return false;
+
+       if (lstat(in, &st1) == -1)
+               ext2fs_fatal(errno, "stat %s\n", in);
+       if (lstat(out, &st2) == -1)
+               ext2fs_fatal(errno, "stat %s\n", out);
+       return st1.st_ino == st2.st_ino;
+}
+
+int main(int argc, char *argv[])
+{
+       int opt;
+       int out_fd;
+       errcode_t retval;
+       struct sparse_file *s;
+
+       while ((opt = getopt(argc, argv, "czS")) != -1) {
+               switch(opt) {
+               case 'c':
+                       params.crc = 1;
+                       break;
+               case 'z':
+                       params.gzip = 1;
+                       break;
+               case 'S':
+                       params.sparse = 0;
+                       break;
+               default:
+                       usage(argv[0]);
+                       exit(EXIT_FAILURE);
+               }
+       }
+       if (optind + 1 >= argc) {
+               usage(argv[0]);
+               exit(EXIT_FAILURE);
+       }
+       params.in_file = strdup(argv[optind++]);
+       params.out_file = strdup(argv[optind]);
+       params.overwrite_input = same_file(params.in_file, params.out_file);
+
+       s = ext_to_sparse(params.in_file);
+
+       out_fd = open(params.out_file, O_WRONLY | O_CREAT | O_TRUNC, 0664);
+       if (out_fd == -1)
+               ext2fs_fatal(errno, "opening %s\n", params.out_file);
+       if (sparse_file_write(s, out_fd, params.gzip, params.sparse, params.crc) < 0)
+               sparse_fatal("writing sparse file");
+
+       sparse_file_destroy(s);
+
+       free(params.in_file);
+       free(params.out_file);
+       free_chunks();
+       close(out_fd);
+
+       return 0;
+}
diff --git a/contrib/android/fsmap.c b/contrib/android/fsmap.c
new file mode 100644 (file)
index 0000000..36adb7f
--- /dev/null
@@ -0,0 +1,119 @@
+#include "fsmap.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include "support/nls-enable.h"
+
+struct walk_ext_priv_data {
+       char                    *path;
+       ext2_filsys             fs;
+       struct fsmap_format     *format;
+};
+
+static int walk_block(ext2_filsys fs  EXT2FS_ATTR((unused)), blk64_t *blocknr,
+                     e2_blkcnt_t blockcnt,
+                     blk64_t ref64_blk EXT2FS_ATTR((unused)),
+                     int ref_offset EXT2FS_ATTR((unused)),
+                     void *priv)
+{
+       struct walk_ext_priv_data *pdata = priv;
+       struct fsmap_format *format = pdata->format;
+
+       return format->add_block(fs, *blocknr, blockcnt < 0, format->private);
+}
+
+static errcode_t ino_iter_blocks(ext2_filsys fs, ext2_ino_t ino,
+                                struct walk_ext_priv_data *pdata)
+{
+       errcode_t retval;
+       struct ext2_inode inode;
+       struct fsmap_format *format = pdata->format;
+
+       retval = ext2fs_read_inode(fs, ino, &inode);
+       if (retval)
+               return retval;
+
+       if (!ext2fs_inode_has_valid_blocks2(fs, &inode))
+               return format->inline_data(&(inode.i_block[0]),
+                                          format->private);
+
+       retval = ext2fs_block_iterate3(fs, ino, 0, NULL, walk_block, pdata);
+       if (retval)
+               com_err(__func__, retval, _("listing blocks of ino \"%u\""),
+                       ino);
+       return retval;
+}
+
+static int is_dir(ext2_filsys fs, ext2_ino_t ino)
+{
+       struct ext2_inode inode;
+
+       if (ext2fs_read_inode(fs, ino, &inode))
+               return 0;
+       return S_ISDIR(inode.i_mode);
+}
+
+static int walk_ext_dir(ext2_ino_t dir EXT2FS_ATTR((unused)),
+                       int flags EXT2FS_ATTR((unused)),
+                       struct ext2_dir_entry *de,
+                       int offset EXT2FS_ATTR((unused)),
+                       int blocksize EXT2FS_ATTR((unused)),
+                       char *buf EXT2FS_ATTR((unused)), void *priv_data)
+{
+       errcode_t retval;
+       struct ext2_inode inode;
+       char *filename, *cur_path, *name = de->name;
+       int name_len = de->name_len & 0xff;
+       struct walk_ext_priv_data *pdata = priv_data;
+       struct fsmap_format *format = pdata->format;
+
+       if (!strncmp(name, ".", name_len)
+           || !strncmp(name, "..", name_len)
+           || !strncmp(name, "lost+found", 10))
+               return 0;
+
+       if (asprintf(&filename, "%s/%.*s", pdata->path, name_len, name) < 0)
+               return -ENOMEM;
+
+       retval = ext2fs_read_inode(pdata->fs, de->inode, &inode);
+       if (retval) {
+               com_err(__func__, retval, _("reading ino \"%u\""), de->inode);
+               goto end;
+       }
+       format->start_new_file(filename, de->inode, &inode, format->private);
+       retval = ino_iter_blocks(pdata->fs, de->inode, pdata);
+       if (retval)
+               return retval;
+       format->end_new_file(format->private);
+
+       retval = 0;
+       if (is_dir(pdata->fs, de->inode)) {
+               cur_path = pdata->path;
+               pdata->path = filename;
+               retval = ext2fs_dir_iterate2(pdata->fs, de->inode, 0, NULL,
+                                   walk_ext_dir, pdata);
+               pdata->path = cur_path;
+       }
+
+end:
+       free(filename);
+       return retval;
+}
+
+errcode_t fsmap_iter_filsys(ext2_filsys fs, struct fsmap_format *format,
+                           const char *file, const char *mountpoint)
+{
+       struct walk_ext_priv_data pdata;
+       errcode_t retval;
+
+       format->private = format->init(file, mountpoint);
+       pdata.fs = fs;
+       pdata.path = "";
+       pdata.format = format;
+
+       retval = ext2fs_dir_iterate2(fs, EXT2_ROOT_INO, 0, NULL, walk_ext_dir, &pdata);
+
+       format->cleanup(format->private);
+       return retval;
+}
diff --git a/contrib/android/fsmap.h b/contrib/android/fsmap.h
new file mode 100644 (file)
index 0000000..9f84a71
--- /dev/null
@@ -0,0 +1,29 @@
+#ifndef FSMAP_H
+# define FSMAP_H
+
+# ifndef _GNU_SOURCE
+#  define _GNU_SOURCE // asprintf
+# endif
+# include <stdio.h>
+# include <stdint.h>
+# include <stdbool.h>
+# include <sys/types.h>
+# include <ext2fs/ext2fs.h>
+
+struct fsmap_format {
+       void* (* init)(const char *file, const char *mountpoint);
+       int   (* start_new_file)(char *path, ext2_ino_t ino,
+                                struct ext2_inode *inode, void *data);
+       int   (* add_block)(ext2_filsys fs, blk64_t blocknr, int metadata,
+                           void *data);
+       int   (* inline_data)(void *inline_data, void *data);
+       int   (* end_new_file)(void *data);
+       int   (* cleanup)(void *data);
+
+       void *private;
+};
+
+errcode_t fsmap_iter_filsys(ext2_filsys fs, struct fsmap_format *format,
+                           const char *file, const char *mountpoint);
+
+#endif /* !FSMAP_H */
diff --git a/contrib/android/hashmap.c b/contrib/android/hashmap.c
new file mode 100644 (file)
index 0000000..eee0071
--- /dev/null
@@ -0,0 +1,76 @@
+#include "hashmap.h"
+#include <string.h>
+
+uint32_t djb2_hash(const void *str)
+{
+       int c;
+       const char *s = str;
+       uint32_t hash = 5381;
+
+       while ((c = *s++))
+               hash = ((hash << 5) + hash) + c;
+       return hash;
+}
+
+struct hashmap *hashmap_create(uint32_t(*hash_fct)(const void*),
+                              void(*free_fct)(void*), size_t size)
+{
+       struct hashmap *h = calloc(sizeof(struct hashmap) +
+                                     sizeof(struct hashmap_entry) * size, 1);
+       h->size = size;
+       h->free = free_fct;
+       h->hash = hash_fct;
+       h->first = h->last = NULL;
+       return h;
+}
+
+void hashmap_add(struct hashmap *h, void *data, const void *key)
+{
+       uint32_t hash = h->hash(key) % h->size;
+       struct hashmap_entry *e = malloc(sizeof(*e));
+
+       e->data = data;
+       e->key = key;
+       e->next = h->entries[hash];
+       h->entries[hash] = e;
+
+       e->list_prev = NULL;
+       e->list_next = h->first;
+       if (h->first)
+               h->first->list_prev = e;
+       h->first = e;
+       if (!h->last)
+               h->last = e;
+}
+
+void *hashmap_lookup(struct hashmap *h, const void *key)
+{
+       struct hashmap_entry *iter;
+       uint32_t hash = h->hash(key) % h->size;
+
+       for (iter = h->entries[hash]; iter; iter = iter->next)
+               if (!strcmp(iter->key, key))
+                       return iter->data;
+       return NULL;
+}
+
+void *hashmap_iter_in_order(struct hashmap *h, struct hashmap_entry **it)
+{
+       *it = *it ? (*it)->list_next : h->first;
+       return *it ? (*it)->data : NULL;
+}
+
+void hashmap_free(struct hashmap *h)
+{
+       for (size_t i = 0; i < h->size; ++i) {
+               struct hashmap_entry *it = h->entries[i];
+               while (it) {
+                       struct hashmap_entry *tmp = it->next;
+                       if (h->free)
+                               h->free(it->data);
+                       free(it);
+                       it = tmp;
+               }
+       }
+       free(h);
+}
diff --git a/contrib/android/hashmap.h b/contrib/android/hashmap.h
new file mode 100644 (file)
index 0000000..70d0ed1
--- /dev/null
@@ -0,0 +1,32 @@
+#ifndef HASHMAP_H
+# define HASHMAP_H
+
+# include <stdlib.h>
+# include <stdint.h>
+
+struct hashmap {
+       uint32_t size;
+       uint32_t(*hash)(const void *key);
+       void(*free)(void*);
+       struct hashmap_entry *first;
+       struct hashmap_entry *last;
+       struct hashmap_entry {
+               void *data;
+               const void *key;
+               struct hashmap_entry *next;
+               struct hashmap_entry *list_next;
+               struct hashmap_entry *list_prev;
+       } *entries[0];
+};
+
+struct hashmap *hashmap_create(uint32_t(*hash_fct)(const void*),
+                              void(*free_fct)(void*), size_t size);
+void hashmap_add(struct hashmap *h, void *data, const void *key);
+void *hashmap_lookup(struct hashmap *h, const void *key);
+void *hashmap_iter_in_order(struct hashmap *h, struct hashmap_entry **it);
+void hashmap_del(struct hashmap *h, struct hashmap_entry *e);
+void hashmap_free(struct hashmap *h);
+
+uint32_t djb2_hash(const void *str);
+
+#endif /* !HASHMAP_H */
diff --git a/contrib/android/perms.c b/contrib/android/perms.c
new file mode 100644 (file)
index 0000000..9a7a93f
--- /dev/null
@@ -0,0 +1,325 @@
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE //asprintf
+#endif
+#include "perms.h"
+#include "support/nls-enable.h"
+#include <time.h>
+#include <sys/stat.h>
+
+#ifndef XATTR_SELINUX_SUFFIX
+# define XATTR_SELINUX_SUFFIX  "selinux"
+#endif
+#ifndef XATTR_CAPS_SUFFIX
+# define XATTR_CAPS_SUFFIX     "capability"
+#endif
+
+struct inode_params {
+       ext2_filsys fs;
+       char *path;
+       char *filename;
+       char *src_dir;
+       char *target_out;
+       char *mountpoint;
+       fs_config_f fs_config_func;
+       struct selabel_handle *sehnd;
+       time_t fixed_time;
+};
+
+static errcode_t ino_add_xattr(ext2_filsys fs, ext2_ino_t ino, const char *name,
+                              const void *value, int value_len)
+{
+       errcode_t retval, close_retval;
+       struct ext2_xattr_handle *xhandle;
+
+       retval = ext2fs_xattrs_open(fs, ino, &xhandle);
+       if (retval) {
+               com_err(__func__, retval, _("while opening inode %u"), ino);
+               return retval;
+       }
+       retval = ext2fs_xattrs_read(xhandle);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while reading xattrs of inode %u"), ino);
+               goto xattrs_close;
+       }
+       retval = ext2fs_xattr_set(xhandle, name, value, value_len);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while setting xattrs of inode %u"), ino);
+               goto xattrs_close;
+       }
+       retval = ext2fs_xattrs_write(xhandle);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while writting xattrs of inode %u"), ino);
+               goto xattrs_close;
+       }
+xattrs_close:
+       close_retval = ext2fs_xattrs_close(&xhandle);
+       if (close_retval) {
+               com_err(__func__, close_retval,
+                       _("while closing xattrs of inode %u"), ino);
+               return retval ? retval : close_retval;
+       }
+       return retval;
+}
+
+static errcode_t set_selinux_xattr(ext2_filsys fs, ext2_ino_t ino,
+                                  struct inode_params *params)
+{
+       errcode_t retval;
+       char *secontext = NULL;
+       struct ext2_inode inode;
+
+       if (params->sehnd == NULL)
+               return 0;
+
+       retval = ext2fs_read_inode(fs, ino, &inode);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while reading inode %u"), ino);
+               return retval;
+       }
+
+       retval = selabel_lookup(params->sehnd, &secontext, params->filename,
+                               inode.i_mode);
+       if (retval < 0) {
+               com_err(__func__, retval,
+                       _("searching for label \"%s\""), params->filename);
+               exit(1);
+       }
+
+       retval = ino_add_xattr(fs, ino,  "security." XATTR_SELINUX_SUFFIX,
+                              secontext, strlen(secontext) + 1);
+
+       freecon(secontext);
+       return retval;
+}
+
+static errcode_t set_perms_and_caps(ext2_filsys fs, ext2_ino_t ino,
+                                   struct inode_params *params)
+{
+       errcode_t retval;
+       uint64_t capabilities = 0;
+       struct ext2_inode inode;
+       struct vfs_cap_data cap_data;
+       unsigned int uid = 0, gid = 0, imode = 0;
+
+       retval = ext2fs_read_inode(fs, ino, &inode);
+       if (retval) {
+               com_err(__func__, retval, _("while reading inode %u"), ino);
+               return retval;
+       }
+
+       /* Permissions */
+       if (params->fs_config_func != NULL) {
+               params->fs_config_func(params->filename, S_ISDIR(inode.i_mode),
+                                      params->target_out, &uid, &gid, &imode,
+                                      &capabilities);
+               inode.i_uid = uid & 0xffff;
+               inode.i_gid = gid & 0xffff;
+               inode.i_mode = (inode.i_mode & S_IFMT) | (imode & 0xffff);
+               retval = ext2fs_write_inode(fs, ino, &inode);
+               if (retval) {
+                       com_err(__func__, retval,
+                               _("while writting inode %u"), ino);
+                       return retval;
+               }
+       }
+
+       /* Capabilities */
+       if (!capabilities)
+               return 0;
+       memset(&cap_data, 0, sizeof(cap_data));
+       cap_data.magic_etc = VFS_CAP_REVISION | VFS_CAP_FLAGS_EFFECTIVE;
+       cap_data.data[0].permitted = (uint32_t) (capabilities & 0xffffffff);
+       cap_data.data[1].permitted = (uint32_t) (capabilities >> 32);
+       return ino_add_xattr(fs, ino,  "security." XATTR_CAPS_SUFFIX,
+                            &cap_data, sizeof(cap_data));
+}
+
+static errcode_t set_timestamp(ext2_filsys fs, ext2_ino_t ino,
+                              struct inode_params *params)
+{
+       errcode_t retval;
+       struct ext2_inode inode;
+       struct stat stat;
+       char *src_filename = NULL;
+
+       retval = ext2fs_read_inode(fs, ino, &inode);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while reading inode %u"), ino);
+               return retval;
+       }
+
+       if (params->fixed_time == -1 && params->src_dir) {
+               /* replace mountpoint from filename with src_dir */
+               if (asprintf(&src_filename, "%s/%s", params->src_dir,
+                       params->filename + strlen(params->mountpoint)) < 0) {
+                       return -ENOMEM;
+               }
+               retval = lstat(src_filename, &stat);
+               if (retval < 0) {
+                       com_err(__func__, retval,
+                               _("while lstat file %s"), src_filename);
+                       goto end;
+               }
+               inode.i_atime = inode.i_ctime = inode.i_mtime = stat.st_mtime;
+       } else {
+               inode.i_atime = inode.i_ctime = inode.i_mtime = params->fixed_time;
+       }
+
+       retval = ext2fs_write_inode(fs, ino, &inode);
+       if (retval) {
+               com_err(__func__, retval,
+                       _("while writting inode %u"), ino);
+               goto end;
+       }
+
+end:
+       free(src_filename);
+       return retval;
+}
+
+static int is_dir(ext2_filsys fs, ext2_ino_t ino)
+{
+       struct ext2_inode inode;
+
+       if (ext2fs_read_inode(fs, ino, &inode))
+               return 0;
+       return S_ISDIR(inode.i_mode);
+}
+
+static errcode_t androidify_inode(ext2_filsys fs, ext2_ino_t ino,
+                                 struct inode_params *params)
+{
+       errcode_t retval;
+
+       retval = set_timestamp(fs, ino, params);
+       if (retval)
+               return retval;
+
+       retval = set_selinux_xattr(fs, ino, params);
+       if (retval)
+               return retval;
+
+       return set_perms_and_caps(fs, ino, params);
+}
+
+static int walk_dir(ext2_ino_t dir EXT2FS_ATTR((unused)),
+                   int flags EXT2FS_ATTR((unused)),
+                   struct ext2_dir_entry *de,
+                   int offset EXT2FS_ATTR((unused)),
+                   int blocksize EXT2FS_ATTR((unused)),
+                   char *buf EXT2FS_ATTR((unused)), void *priv_data)
+{
+       __u16 name_len;
+       errcode_t retval;
+       struct inode_params *params = (struct inode_params *)priv_data;
+
+       name_len = de->name_len & 0xff;
+       if (!strncmp(de->name, ".", name_len)
+           || (!strncmp(de->name, "..", name_len)))
+               return 0;
+
+       if (asprintf(&params->filename, "%s/%.*s", params->path, name_len,
+                    de->name) < 0)
+               return -ENOMEM;
+
+       if (!strncmp(de->name, "lost+found", 10)) {
+               retval = set_selinux_xattr(params->fs, de->inode, params);
+               if (retval)
+                       goto end;
+       } else {
+               retval = androidify_inode(params->fs, de->inode, params);
+               if (retval)
+                       goto end;
+               if (is_dir(params->fs, de->inode)) {
+                       char *cur_path = params->path;
+                       char *cur_filename = params->filename;
+                       params->path = params->filename;
+                       ext2fs_dir_iterate2(params->fs, de->inode, 0, NULL,
+                                           walk_dir, params);
+                       params->path = cur_path;
+                       params->filename = cur_filename;
+               }
+       }
+
+end:
+       free(params->filename);
+       return retval;
+}
+
+errcode_t __android_configure_fs(ext2_filsys fs, char *src_dir,
+                                char *target_out,
+                                char *mountpoint,
+                                fs_config_f fs_config_func,
+                                struct selabel_handle *sehnd,
+                                time_t fixed_time)
+{
+       errcode_t retval;
+       struct inode_params params = {
+               .fs = fs,
+               .src_dir = src_dir,
+               .target_out = target_out,
+               .fs_config_func = fs_config_func,
+               .sehnd = sehnd,
+               .fixed_time = fixed_time,
+               .path = mountpoint,
+               .filename = mountpoint,
+               .mountpoint = mountpoint,
+       };
+
+       /* walk_dir will add the "/". Don't add it twice. */
+       if (strlen(mountpoint) == 1 && mountpoint[0] == '/')
+               params.path = "";
+
+       retval = set_selinux_xattr(fs, EXT2_ROOT_INO, &params);
+       if (retval)
+               return retval;
+       retval = set_timestamp(fs, EXT2_ROOT_INO, &params);
+       if (retval)
+               return retval;
+
+       return ext2fs_dir_iterate2(fs, EXT2_ROOT_INO, 0, NULL, walk_dir,
+                                  &params);
+}
+
+errcode_t android_configure_fs(ext2_filsys fs, char *src_dir, char *target_out,
+                              char *mountpoint,
+                              struct selinux_opt *seopts,
+                              unsigned int nopt,
+                              char *fs_config_file, time_t fixed_time)
+{
+       errcode_t retval;
+       fs_config_f fs_config_func = NULL;
+       struct selabel_handle *sehnd = NULL;
+
+       /* Retrieve file contexts */
+       if (nopt > 0) {
+               sehnd = selabel_open(SELABEL_CTX_FILE, seopts, nopt);
+               if (!sehnd) {
+                       com_err(__func__, -EINVAL,
+                               _("while opening file contexts \"%s\""),
+                               seopts[0].value);
+                       return -EINVAL;
+               }
+       }
+
+       /* Load the FS config */
+       if (fs_config_file) {
+               retval = load_canned_fs_config(fs_config_file);
+               if (retval < 0) {
+                       com_err(__func__, retval,
+                               _("while loading fs_config \"%s\""),
+                               fs_config_file);
+                       return retval;
+               }
+               fs_config_func = canned_fs_config;
+       } else if (mountpoint)
+               fs_config_func = fs_config;
+
+       return __android_configure_fs(fs, src_dir, target_out, mountpoint,
+                                     fs_config_func, sehnd, fixed_time);
+}
diff --git a/contrib/android/perms.h b/contrib/android/perms.h
new file mode 100644 (file)
index 0000000..9955bb5
--- /dev/null
@@ -0,0 +1,42 @@
+#ifndef ANDROID_PERMS_H
+# define ANDROID_PERMS_H
+
+# include "config.h"
+# include <ext2fs/ext2fs.h>
+
+typedef void (*fs_config_f)(const char *path, int dir,
+                           const char *target_out_path,
+                           unsigned *uid, unsigned *gid,
+                           unsigned *mode, uint64_t *capabilities);
+
+# ifdef _WIN32
+struct selabel_handle;
+static inline errcode_t android_configure_fs(ext2_filsys fs,
+                                            char *src_dir,
+                                            char *target_out,
+                                            char *mountpoint,
+                                            void *seopts,
+                                            unsigned int nopt,
+                                            char *fs_config_file,
+                                            time_t fixed_time)
+{
+       return 0;
+}
+# else
+#  include <selinux/selinux.h>
+#  include <selinux/label.h>
+#  if !defined(HOST)
+#   include <selinux/android.h>
+#  endif
+#  include <private/android_filesystem_config.h>
+#  include <private/canned_fs_config.h>
+
+errcode_t android_configure_fs(ext2_filsys fs, char *src_dir,
+                              char *target_out,
+                              char *mountpoint,
+                              struct selinux_opt *seopts,
+                              unsigned int nopt,
+                              char *fs_config_file, time_t fixed_time);
+
+# endif
+#endif /* !ANDROID_PERMS_H */
diff --git a/debugfs/Android.bp b/debugfs/Android.bp
new file mode 100644 (file)
index 0000000..7dfc7d3
--- /dev/null
@@ -0,0 +1,72 @@
+// Copyright 2017 The Android Open Source Project
+
+//########################
+// Build the debugfs binary
+
+cc_defaults {
+    name: "debugfs-defaults",
+    srcs: [
+        "debug_cmds.c",
+        "debugfs.c",
+        "util.c",
+        "ncheck.c",
+        "icheck.c",
+        "ls.c",
+        "lsdel.c",
+        "dump.c",
+        "set_fields.c",
+        "logdump.c",
+        "htree.c",
+        "unused.c",
+        "e2freefrag.c",
+        "filefrag.c",
+        "extent_cmds.c",
+        "extent_inode.c",
+        "zap.c",
+        "quota.c",
+        "xattrs.c",
+        "journal.c",
+        "revoke.c",
+        "recovery.c",
+        "do_journal.c",
+    ],
+    cflags: [
+        "-W",
+        "-Wall",
+        "-Wno-macro-redefined",
+        "-fno-strict-aliasing",
+        "-DDEBUGFS",
+    ],
+    include_dirs: [
+        "external/e2fsprogs/misc",
+        "external/e2fsprogs/e2fsck"
+    ],
+}
+
+debugfs_libs = [
+    "libext2_misc",
+    "libext2fs",
+    "libext2_blkid",
+    "libext2_uuid",
+    "libext2_ss",
+    "libext2_quota",
+    "libext2_com_err",
+    "libext2_e2p",
+]
+
+cc_binary {
+    name: "debugfs",
+    host_supported: true,
+    defaults: ["debugfs-defaults"],
+
+    shared_libs: debugfs_libs,
+    system_shared_libs: ["libc"],
+}
+
+cc_binary {
+    name: "debugfs_static",
+    static_executable: true,
+    defaults: ["debugfs-defaults"],
+
+    static_libs: debugfs_libs + ["libc"],
+}
diff --git a/debugfs/Android.mk b/debugfs/Android.mk
deleted file mode 100644 (file)
index 91dc8c3..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#########################
-# Build the debugfs binary
-
-debugfs_src_files :=  \
-       debug_cmds.c \
-       debugfs.c \
-       util.c \
-       ncheck.c\
-       icheck.c \
-       ls.c \
-       lsdel.c \
-       dump.c \
-       set_fields.c \
-       logdump.c \
-       htree.c \
-       unused.c \
-       e2freefrag.c \
-       filefrag.c \
-       extent_cmds.c \
-       extent_inode.c \
-       zap.c \
-       create_inode.c \
-       quota.c \
-       xattrs.c \
-       journal.c \
-       revoke.c \
-       recovery.c \
-       do_journal.c
-
-debugfs_shared_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_uuid \
-       libext2_ss \
-       libext2_quota \
-       libext2_com_err \
-       libext2_e2p
-
-debugfs_system_shared_libraries := libc
-
-debugfs_static_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_uuid_static \
-       libext2_ss \
-       libext2_quota \
-       libext2_com_err \
-       libext2_e2p
-
-debugfs_system_static_libraries := libc
-
-debugfs_c_includes := \
-       external/e2fsprogs/e2fsck \
-       external/e2fsprogs/misc \
-       external/e2fsprogs/lib
-
-debugfs_cflags := -O2 -g -W -Wall -fno-strict-aliasing -DDEBUGFS
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(debugfs_src_files)
-LOCAL_C_INCLUDES := $(debugfs_c_includes)
-LOCAL_CFLAGS := $(debugfs_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(debugfs_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(debugfs_shared_libraries)
-LOCAL_MODULE := debugfs
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(debugfs_src_files)
-LOCAL_C_INCLUDES := $(debugfs_c_includes)
-LOCAL_CFLAGS := $(debugfs_cflags)
-LOCAL_STATIC_LIBRARIES := $(debugfs_static_libraries) $(debugfs_system_static_libraries)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := debugfs_static
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(debugfs_src_files)
-LOCAL_C_INCLUDES := $(debugfs_c_includes)
-LOCAL_CFLAGS := $(debugfs_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(debugfs_shared_libraries))
-LOCAL_MODULE := debugfs_host
-LOCAL_MODULE_STEM := debugfs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
index 3ac80d9..408a323 100644 (file)
@@ -164,7 +164,7 @@ tst_set_fields: set_fields.c util.c
        $(Q) $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(SYSLIBS) -DUNITTEST \
                -o tst_set_fields $(srcdir)/set_fields.c $(srcdir)/util.c $(LIBS)
 
-check:: tst_set_fields
+fullcheck check:: tst_set_fields
        $(TESTENV) ./tst_set_fields
 
 # +++ Dependency line eater +++
index 453f5b5..cef4ec2 100644 (file)
@@ -861,16 +861,15 @@ void internal_dump_inode(FILE *out, const char *prefix,
                fprintf(out, "%d\n", inode->i_size);
        if (os == EXT2_OS_HURD)
                fprintf(out,
-                       "%sFile ACL: %d    Directory ACL: %d Translator: %d\n",
+                       "%sFile ACL: %d Translator: %d\n",
                        prefix,
-                       inode->i_file_acl, LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0,
+                       inode->i_file_acl,
                        inode->osd1.hurd1.h_i_translator);
        else
-               fprintf(out, "%sFile ACL: %llu    Directory ACL: %d\n",
+               fprintf(out, "%sFile ACL: %llu\n",
                        prefix,
                        inode->i_file_acl | ((long long)
-                               (inode->osd2.linux2.l_i_file_acl_high) << 32),
-                       LINUX_S_ISDIR(inode->i_mode) ? inode->i_dir_acl : 0);
+                               (inode->osd2.linux2.l_i_file_acl_high) << 32));
        if (os != EXT2_OS_HURD)
                fprintf(out, "%sLinks: %d   Blockcount: %llu\n",
                        prefix, inode->i_links_count,
@@ -1367,10 +1366,9 @@ void do_modify_inode(int argc, char *argv[])
        modify_u32(argv[0], "Reserved1", decimal_format, &inode.i_reserved1);
 #endif
        modify_u32(argv[0], "File acl", decimal_format, &inode.i_file_acl);
-       if (LINUX_S_ISDIR(inode.i_mode))
-               modify_u32(argv[0], "Directory acl", decimal_format, &inode.i_dir_acl);
-       else
-               modify_u32(argv[0], "High 32bits of size", decimal_format, &inode.i_size_high);
+
+       modify_u32(argv[0], "High 32bits of size", decimal_format,
+                  &inode.i_size_high);
 
        if (os == EXT2_OS_HURD)
                modify_u32(argv[0], "Translator Block",
index 54e55e2..8c18666 100644 (file)
@@ -287,7 +287,8 @@ void do_htree_dump(int argc, char *argv[])
        fprintf(pager, "\t Indirect levels: %d\n", rootnode->indirect_levels);
        fprintf(pager, "\t Flags: %d\n", rootnode->unused_flags);
 
-       ent = (struct ext2_dx_entry *) (buf + 24 + rootnode->info_length);
+       ent = (struct ext2_dx_entry *)
+               ((char *)rootnode + rootnode->info_length);
 
        htree_dump_int_node(current_fs, ino, &inode, rootnode, ent,
                            buf + current_fs->blocksize,
index ff9b7b6..ca68862 100644 (file)
@@ -212,7 +212,6 @@ static struct field_set_info inode_fields[] = {
        /* Special case: i_file_acl_high is 2 bytes */
        { "file_acl", &set_inode.i_file_acl, 
                &set_inode.osd2.linux2.l_i_file_acl_high, 6, parse_uint },
-       { "dir_acl", &set_inode.i_dir_acl, NULL, 4, parse_uint, FLAG_ALIAS },
        { "faddr", &set_inode.i_faddr, NULL, 4, parse_uint },
        { "frag", &set_inode.osd2.hurd2.h_i_frag, NULL, 1, parse_uint, FLAG_ALIAS },
        { "fsize", &set_inode.osd2.hurd2.h_i_fsize, NULL, 1, parse_uint },
diff --git a/e2fsck/Android.bp b/e2fsck/Android.bp
new file mode 100644 (file)
index 0000000..1cabe86
--- /dev/null
@@ -0,0 +1,64 @@
+// Copyright 2017 The Android Open Source Project
+
+//########################
+// Build the e2fsck binary
+
+cc_defaults {
+    name: "e2fsck-defaults",
+    srcs: [
+        "e2fsck.c",
+        "super.c",
+        "pass1.c",
+        "pass1b.c",
+        "pass2.c",
+        "pass3.c",
+        "pass4.c",
+        "pass5.c",
+        "logfile.c",
+        "journal.c",
+        "recovery.c",
+        "revoke.c",
+        "badblocks.c",
+        "util.c",
+        "unix.c",
+        "dirinfo.c",
+        "dx_dirinfo.c",
+        "ehandler.c",
+        "problem.c",
+        "message.c",
+        "ea_refcount.c",
+        "quota.c",
+        "rehash.c",
+        "region.c",
+        "sigcatcher.c",
+        "readahead.c",
+        "extents.c",
+    ],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined", "-fno-strict-aliasing"],
+}
+
+e2fsck_libs = [
+    "libext2fs",
+    "libext2_blkid",
+    "libext2_uuid",
+    "libext2_quota",
+    "libext2_com_err",
+    "libext2_e2p",
+]
+
+cc_binary {
+    name: "e2fsck",
+    host_supported: true,
+    defaults: ["e2fsck-defaults"],
+
+    shared_libs: e2fsck_libs,
+    system_shared_libs: ["libc"],
+}
+
+cc_binary {
+    name: "e2fsck_static",
+    static_executable: true,
+    defaults: ["e2fsck-defaults"],
+
+    static_libs: e2fsck_libs + ["libc"],
+}
diff --git a/e2fsck/Android.mk b/e2fsck/Android.mk
deleted file mode 100644 (file)
index 604eaa1..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#########################
-# Build the e2fsck binary
-
-e2fsck_src_files :=  \
-       e2fsck.c \
-       super.c \
-       pass1.c \
-       pass1b.c \
-       pass2.c \
-       pass3.c \
-       pass4.c \
-       pass5.c \
-       logfile.c \
-       journal.c \
-       recovery.c \
-       revoke.c \
-       badblocks.c \
-       util.c \
-       unix.c \
-       dirinfo.c \
-       dx_dirinfo.c \
-       ehandler.c \
-       problem.c \
-       message.c \
-       ea_refcount.c \
-       quota.c \
-       rehash.c \
-       region.c \
-       sigcatcher.c \
-       readahead.c \
-       extents.c
-
-e2fsck_shared_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_uuid \
-       libext2_quota \
-       libext2_com_err \
-       libext2_e2p
-
-e2fsck_system_shared_libraries := libc
-
-e2fsck_static_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_uuid_static \
-       libext2_quota \
-       libext2_com_err \
-       libext2_e2p
-
-e2fsck_system_static_libraries := libc
-
-e2fsck_c_includes :=
-
-e2fsck_cflags := -O2 -g -W -Wall -fno-strict-aliasing
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e2fsck_src_files)
-LOCAL_C_INCLUDES := $(e2fsck_c_includes)
-LOCAL_CFLAGS := $(e2fsck_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(e2fsck_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(e2fsck_shared_libraries)
-LOCAL_MODULE := e2fsck
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e2fsck_src_files)
-LOCAL_C_INCLUDES := $(e2fsck_c_includes)
-LOCAL_CFLAGS := $(e2fsck_cflags)
-LOCAL_STATIC_LIBRARIES := $(e2fsck_static_libraries) $(e2fsck_system_static_libraries)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := e2fsck_static
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e2fsck_src_files)
-LOCAL_C_INCLUDES := $(e2fsck_c_includes)
-LOCAL_CFLAGS := $(e2fsck_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(e2fsck_shared_libraries))
-LOCAL_MODULE := e2fsck_host
-LOCAL_MODULE_STEM := e2fsck
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
index cee6a42..e43d340 100644 (file)
@@ -150,7 +150,7 @@ tst_region: region.c $(DEPLIBCOM_ERR)
                $(ALL_CFLAGS) $(ALL_LDFLAGS) -DTEST_PROGRAM \
                $(LIBCOM_ERR) $(SYSLIBS)
 
-check:: tst_refcount tst_region tst_problem
+fullcheck check:: tst_refcount tst_region tst_problem
        $(TESTENV) ./tst_refcount
        $(TESTENV) ./tst_region
        $(TESTENV) ./tst_problem
index 6ab4f9c..fd12024 100644 (file)
@@ -122,6 +122,7 @@ struct dx_dirblock_info {
        blk64_t         phys;
        int             flags;
        blk64_t         parent;
+       blk64_t         previous;
        ext2_dirhash_t  min_hash;
        ext2_dirhash_t  max_hash;
        ext2_dirhash_t  node_min_hash;
@@ -647,4 +648,7 @@ unsigned long long get_memory_size(void);
 extern void e2fsck_clear_progbar(e2fsck_t ctx);
 extern int e2fsck_simple_progress(e2fsck_t ctx, const char *label,
                                  float percent, unsigned int dpynum);
+
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
 #endif /* _E2FSCK_H */
index 1c3fcd8..34201a3 100644 (file)
@@ -32,7 +32,7 @@
  *     %IM     <inode> -> i_mtime
  *     %IF     <inode> -> i_faddr
  *     %If     <inode> -> i_file_acl
- *     %Id     <inode> -> i_dir_acl
+ *     %Id     <inode> -> i_size_high
  *     %Iu     <inode> -> i_uid
  *     %Ig     <inode> -> i_gid
  *     %It     <inode type>
@@ -320,7 +320,7 @@ static _INLINE_ void expand_inode_expression(FILE *f, ext2_filsys fs, char ch,
                break;
        case 'd':
                fprintf(f, "%u", (LINUX_S_ISDIR(inode->i_mode) ?
-                                 inode->i_dir_acl : 0));
+                       inode->i_size_high : 0));
                break;
        case 'u':
                fprintf(f, "%d", inode_uid(*inode));
index 7983ffd..422a3d6 100644 (file)
@@ -1715,7 +1715,8 @@ void e2fsck_pass1(e2fsck_t ctx)
                }
 
                if (inode->i_faddr || frag || fsize ||
-                   (LINUX_S_ISDIR(inode->i_mode) && inode->i_dir_acl))
+                   (!ext2fs_has_feature_largedir(fs->super) &&
+                   (LINUX_S_ISDIR(inode->i_mode) && inode->i_size_high)))
                        mark_inode_bad(ctx, ino);
                if ((fs->super->s_creator_os != EXT2_OS_HURD) &&
                    !ext2fs_has_feature_64bit(fs->super) &&
@@ -2154,14 +2155,20 @@ static _INLINE_ void mark_block_used(e2fsck_t ctx, blk64_t block)
        }
 }
 
+/*
+ * When cluster size is greater than one block, it is caller's responsibility
+ * to make sure block parameter starts at a cluster boundary.
+ */
 static _INLINE_ void mark_blocks_used(e2fsck_t ctx, blk64_t block,
                                      unsigned int num)
 {
        if (ext2fs_test_block_bitmap_range2(ctx->block_found_map, block, num))
                ext2fs_mark_block_bitmap_range2(ctx->block_found_map, block, num);
-       else
-               while (num--)
-                       mark_block_used(ctx, block++);
+       else {
+               int i;
+               for (i = 0; i < num; i += EXT2FS_CLUSTER_RATIO(ctx->fs))
+                       mark_block_used(ctx, block + i);
+       }
 }
 
 /*
@@ -2473,7 +2480,7 @@ static int handle_htree(e2fsck_t ctx, struct problem_context *pctx,
                return 1;
 
        pctx->num = root->indirect_levels;
-       if ((root->indirect_levels > 1) &&
+       if ((root->indirect_levels > ext2_dir_htree_level(fs)) &&
            fix_problem(ctx, PR_1_HTREE_DEPTH, pctx))
                return 1;
 
@@ -2561,8 +2568,7 @@ static void scan_extent_node(e2fsck_t ctx, struct problem_context *pctx,
 {
        struct ext2fs_extent    extent;
        blk64_t                 blk, last_lblk;
-       e2_blkcnt_t             blockcnt;
-       unsigned int            i;
+       unsigned int            i, n;
        int                     is_dir, is_leaf;
        problem_t               problem;
        struct ext2_extent_info info;
@@ -2827,50 +2833,29 @@ report_problem:
                        }
                }
 alloc_later:
-               while (is_dir && (++pb->last_db_block <
-                                 (e2_blkcnt_t) extent.e_lblk)) {
-                       pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist,
-                                                             pb->ino, 0,
-                                                             pb->last_db_block);
-                       if (pctx->errcode) {
-                               pctx->blk = 0;
-                               pctx->num = pb->last_db_block;
-                               goto failed_add_dir_block;
-                       }
-               }
-               if (!ctx->fs->cluster_ratio_bits) {
-                       mark_blocks_used(ctx, extent.e_pblk, extent.e_len);
-                       pb->num_blocks += extent.e_len;
-               }
-               for (blk = extent.e_pblk, blockcnt = extent.e_lblk, i = 0;
-                    i < extent.e_len;
-                    blk++, blockcnt++, i++) {
-                       if (ctx->fs->cluster_ratio_bits &&
-                           !(pb->previous_block &&
-                             (EXT2FS_B2C(ctx->fs, blk) ==
-                              EXT2FS_B2C(ctx->fs, pb->previous_block)) &&
-                             (blk & EXT2FS_CLUSTER_MASK(ctx->fs)) ==
-                             ((unsigned) blockcnt & EXT2FS_CLUSTER_MASK(ctx->fs)))) {
-                               mark_block_used(ctx, blk);
-                               pb->num_blocks++;
-                       }
-                       if (has_unaligned_cluster_map(ctx, pb->previous_block,
-                                                     pb->last_block, blk,
-                                                     blockcnt)) {
-                               pctx->blk = blockcnt;
-                               pctx->blk2 = blk;
-                               fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
-                               mark_block_used(ctx, blk);
-                               mark_block_used(ctx, blk);
+               if (is_dir) {
+                       while (++pb->last_db_block <
+                              (e2_blkcnt_t) extent.e_lblk) {
+                               pctx->errcode = ext2fs_add_dir_block2(
+                                                       ctx->fs->dblist,
+                                                       pb->ino, 0,
+                                                       pb->last_db_block);
+                               if (pctx->errcode) {
+                                       pctx->blk = 0;
+                                       pctx->num = pb->last_db_block;
+                                       goto failed_add_dir_block;
+                               }
                        }
-                       pb->last_block = blockcnt;
-                       pb->previous_block = blk;
 
-                       if (is_dir) {
-                               pctx->errcode = ext2fs_add_dir_block2(ctx->fs->dblist, pctx->ino, blk, blockcnt);
+                       for (i = 0; i < extent.e_len; i++) {
+                               pctx->errcode = ext2fs_add_dir_block2(
+                                                       ctx->fs->dblist,
+                                                       pctx->ino,
+                                                       extent.e_pblk + i,
+                                                       extent.e_lblk + i);
                                if (pctx->errcode) {
-                                       pctx->blk = blk;
-                                       pctx->num = blockcnt;
+                                       pctx->blk = extent.e_pblk + i;
+                                       pctx->num = extent.e_lblk + i;
                                failed_add_dir_block:
                                        fix_problem(ctx, PR_1_ADD_DBLOCK, pctx);
                                        /* Should never get here */
@@ -2878,9 +2863,46 @@ alloc_later:
                                        return;
                                }
                        }
+                       if (extent.e_len > 0)
+                               pb->last_db_block = extent.e_lblk + extent.e_len - 1;
+               }
+               if (has_unaligned_cluster_map(ctx, pb->previous_block,
+                                             pb->last_block,
+                                             extent.e_pblk,
+                                             extent.e_lblk)) {
+                       for (i = 0; i < extent.e_len; i++) {
+                               pctx->blk = extent.e_lblk + i;
+                               pctx->blk2 = extent.e_pblk + i;
+                               fix_problem(ctx, PR_1_MISALIGNED_CLUSTER, pctx);
+                               mark_block_used(ctx, extent.e_pblk + i);
+                               mark_block_used(ctx, extent.e_pblk + i);
+                       }
+               }
+
+               /*
+                * Check whether first cluster got marked in previous iteration.
+                */
+               if (ctx->fs->cluster_ratio_bits &&
+                   pb->previous_block &&
+                   (EXT2FS_B2C(ctx->fs, extent.e_pblk) ==
+                    EXT2FS_B2C(ctx->fs, pb->previous_block)))
+                       /* Set blk to the beginning of next cluster. */
+                       blk = EXT2FS_C2B(
+                               ctx->fs,
+                               EXT2FS_B2C(ctx->fs, extent.e_pblk) + 1);
+               else
+                       /* Set blk to the beginning of current cluster. */
+                       blk = EXT2FS_C2B(ctx->fs,
+                                        EXT2FS_B2C(ctx->fs, extent.e_pblk));
+
+               if (blk < extent.e_pblk + extent.e_len) {
+                       mark_blocks_used(ctx, blk,
+                                        extent.e_pblk + extent.e_len - blk);
+                       n = DIV_ROUND_UP(extent.e_pblk + extent.e_len - blk,
+                                        EXT2FS_CLUSTER_RATIO(ctx->fs));
+                       pb->num_blocks += n;
                }
-               if (is_dir && extent.e_len > 0)
-                       pb->last_db_block = blockcnt - 1;
+               pb->last_block = extent.e_lblk + extent.e_len - 1;
                pb->previous_block = extent.e_pblk + extent.e_len - 1;
                start_block = pb->last_block = last_lblk;
                if (is_leaf && !is_dir &&
index 170878c..09b79c3 100644 (file)
@@ -85,6 +85,39 @@ struct check_dir_struct {
        unsigned long long next_ra_off;
 };
 
+static void update_parents(struct dx_dir_info *dx_dir, int type)
+{
+       struct dx_dirblock_info *dx_db, *dx_parent, *dx_previous;
+       int b;
+
+       for (b = 0, dx_db = dx_dir->dx_block;
+            b < dx_dir->numblocks;
+            b++, dx_db++) {
+               dx_parent = &dx_dir->dx_block[dx_db->parent];
+               if (dx_db->type != type)
+                       continue;
+
+               /*
+                * XXX Make sure dx_parent->min_hash > dx_db->min_hash
+               */
+               if (dx_db->flags & DX_FLAG_FIRST) {
+                       dx_parent->min_hash = dx_db->min_hash;
+                       if (dx_parent->previous) {
+                               dx_previous =
+                                       &dx_dir->dx_block[dx_parent->previous];
+                               dx_previous->node_max_hash =
+                                       dx_parent->min_hash;
+                       }
+               }
+               /*
+                * XXX Make sure dx_parent->max_hash < dx_db->max_hash
+                */
+               if (dx_db->flags & DX_FLAG_LAST) {
+                       dx_parent->max_hash = dx_db->max_hash;
+               }
+       }
+}
+
 void e2fsck_pass2(e2fsck_t ctx)
 {
        struct ext2_super_block *sb = ctx->fs->super;
@@ -182,24 +215,11 @@ void e2fsck_pass2(e2fsck_t ctx)
                 * Find all of the first and last leaf blocks, and
                 * update their parent's min and max hash values
                 */
-               for (b=0, dx_db = dx_dir->dx_block;
-                    b < dx_dir->numblocks;
-                    b++, dx_db++) {
-                       if ((dx_db->type != DX_DIRBLOCK_LEAF) ||
-                           !(dx_db->flags & (DX_FLAG_FIRST | DX_FLAG_LAST)))
-                               continue;
-                       dx_parent = &dx_dir->dx_block[dx_db->parent];
-                       /*
-                        * XXX Make sure dx_parent->min_hash > dx_db->min_hash
-                        */
-                       if (dx_db->flags & DX_FLAG_FIRST)
-                               dx_parent->min_hash = dx_db->min_hash;
-                       /*
-                        * XXX Make sure dx_parent->max_hash < dx_db->max_hash
-                        */
-                       if (dx_db->flags & DX_FLAG_LAST)
-                               dx_parent->max_hash = dx_db->max_hash;
-               }
+               update_parents(dx_dir, DX_DIRBLOCK_LEAF);
+
+               /* for 3 level htree: update 2 level parent's min
+                * and max hash values */
+               update_parents(dx_dir, DX_DIRBLOCK_NODE);
 
                for (b=0, dx_db = dx_dir->dx_block;
                     b < dx_dir->numblocks;
@@ -642,6 +662,10 @@ static void parse_int_node(ext2_filsys fs,
                        dx_db->flags |= DX_FLAG_REFERENCED;
                        dx_db->parent = db->blockcnt;
                }
+
+               dx_db->previous =
+                       i ? ext2fs_le32_to_cpu(ent[i-1].block & 0x0ffffff) : 0;
+
                if (hash < min_hash)
                        min_hash = hash;
                if (hash > max_hash)
@@ -949,6 +973,14 @@ static int check_dir_block(ext2_filsys fs,
                        return DIRENT_ABORT;
        }
 
+       /* This will allow (at some point in the future) to punch out empty
+        * directory blocks and reduce the space used by a directory that grows
+        * very large and then the files are deleted. For now, all that is
+        * needed is to avoid e2fsck filling in these holes as part of
+        * feature flag. */
+       if (db->blk == 0 && ext2fs_has_feature_largedir(fs->super))
+               return 0;
+
        if (db->blk == 0 && !inline_data_size) {
                if (allocate_dir_block(ctx, db, buf, &cd->pctx))
                        return 0;
@@ -1058,7 +1090,8 @@ inline_read_fail:
                        dx_db->flags |= DX_FLAG_FIRST | DX_FLAG_LAST;
                        if ((root->reserved_zero ||
                             root->info_length < 8 ||
-                            root->indirect_levels > 1) &&
+                            root->indirect_levels >=
+                            ext2_dir_htree_level(fs)) &&
                            fix_problem(ctx, PR_2_HTREE_BAD_ROOT, &cd->pctx)) {
                                clear_htree(ctx, ino);
                                dx_dir->numblocks = 0;
@@ -1811,10 +1844,10 @@ int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                } else
                        not_fixed++;
        }
-       if (inode.i_dir_acl &&
+       if (inode.i_size_high && !ext2fs_has_feature_largedir(fs->super) &&
            LINUX_S_ISDIR(inode.i_mode)) {
-               if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
-                       inode.i_dir_acl = 0;
+               if (fix_problem(ctx, PR_2_DIR_SIZE_HIGH_ZERO, &pctx)) {
+                       inode.i_size_high = 0;
                        inode_modified++;
                } else
                        not_fixed++;
index fb55b7e..ab73649 100644 (file)
@@ -21,8 +21,6 @@
 #include "e2fsck.h"
 #include "problem.h"
 
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
 static void check_block_bitmaps(e2fsck_t ctx);
 static void check_inode_bitmaps(e2fsck_t ctx);
 static void check_inode_end(e2fsck_t ctx);
index c3e4f6a..206a8a0 100644 (file)
@@ -1361,9 +1361,9 @@ static struct e2fsck_problem problem_table[] = {
          N_("i_file_acl @F %If, @s zero.\n"),
          PROMPT_CLEAR, 0 },
 
-       /* i_dir_acl should be zero */
-       { PR_2_DIR_ACL_ZERO,
-         N_("i_dir_acl @F %Id, @s zero.\n"),
+       /* i_size_high should be zero */
+       { PR_2_DIR_SIZE_HIGH_ZERO,
+         N_("i_size_high @F %Id, @s zero.\n"),
          PROMPT_CLEAR, 0 },
 
        /* i_frag should be zero */
index d291e26..f8650b9 100644 (file)
@@ -813,8 +813,8 @@ struct problem_context {
 /* i_file_acl should be zero */
 #define PR_2_FILE_ACL_ZERO     0x02000E
 
-/* i_dir_acl should be zero */
-#define PR_2_DIR_ACL_ZERO      0x02000F
+/* i_size_high should be zero */
+#define PR_2_DIR_SIZE_HIGH_ZERO        0x02000F
 
 /* i_frag should be zero */
 #define PR_2_FRAG_ZERO         0x020010
index 22a58f3..7dcb386 100644 (file)
@@ -603,6 +603,43 @@ static struct ext2_dx_entry *set_int_node(ext2_filsys fs, char *buf)
        return (struct ext2_dx_entry *) limits;
 }
 
+static int alloc_blocks(ext2_filsys fs,
+                       struct ext2_dx_countlimit **limit,
+                       struct ext2_dx_entry **prev_ent,
+                       struct ext2_dx_entry **next_ent,
+                       int *prev_offset, int *next_offset,
+                       struct out_dir *outdir, int i,
+                       int *prev_count, int *next_count)
+{
+       errcode_t       retval;
+       char            *block_start;
+
+       if (*limit)
+               (*limit)->limit = (*limit)->count =
+                       ext2fs_cpu_to_le16((*limit)->limit);
+       *prev_ent = (struct ext2_dx_entry *) (outdir->buf + *prev_offset);
+       (*prev_ent)->block = ext2fs_cpu_to_le32(outdir->num);
+
+       if (i != 1)
+               (*prev_ent)->hash =
+                       ext2fs_cpu_to_le32(outdir->hashes[i]);
+
+       retval = get_next_block(fs, outdir, &block_start);
+       if (retval)
+               return retval;
+
+       *next_ent = set_int_node(fs, block_start);
+       *limit = (struct ext2_dx_countlimit *)(*next_ent);
+       if (next_offset)
+               *next_offset = ((char *) *next_ent - outdir->buf);
+
+       *next_count = (*limit)->limit;
+       (*prev_offset) += sizeof(struct ext2_dx_entry);
+       (*prev_count)--;
+
+       return 0;
+}
+
 /*
  * This function takes the leaf nodes which have been written in
  * outdir, and populates the root node and any necessary interior nodes.
@@ -612,13 +649,13 @@ static errcode_t calculate_tree(ext2_filsys fs,
                                ext2_ino_t ino,
                                ext2_ino_t parent)
 {
-       struct ext2_dx_root_info        *root_info;
-       struct ext2_dx_entry            *root, *dx_ent = 0;
-       struct ext2_dx_countlimit       *root_limit, *limit;
+       struct ext2_dx_root_info        *root_info;
+       struct ext2_dx_entry            *root, *int_ent, *dx_ent = 0;
+       struct ext2_dx_countlimit       *root_limit, *int_limit, *limit;
        errcode_t                       retval;
        char                            * block_start;
-       int                             i, c1, c2, nblks;
-       int                             limit_offset, root_offset;
+       int                             i, c1, c2, c3, nblks;
+       int                             limit_offset, int_offset, root_offset;
 
        root_info = set_root_node(fs, outdir->buf, ino, parent);
        root_offset = limit_offset = ((char *) root_info - outdir->buf) +
@@ -628,7 +665,7 @@ static errcode_t calculate_tree(ext2_filsys fs,
        nblks = outdir->num;
 
        /* Write out the pointer blocks */
-       if (nblks-1 <= c1) {
+       if (nblks - 1 <= c1) {
                /* Just write out the root block, and we're done */
                root = (struct ext2_dx_entry *) (outdir->buf + root_offset);
                for (i=1; i < nblks; i++) {
@@ -639,31 +676,20 @@ static errcode_t calculate_tree(ext2_filsys fs,
                        root++;
                        c1--;
                }
-       } else {
+       } else if (nblks - 1 <= ext2fs_htree_intnode_maxrecs(fs, c1)) {
                c2 = 0;
-               limit = 0;
+               limit = NULL;
                root_info->indirect_levels = 1;
                for (i=1; i < nblks; i++) {
-                       if (c1 == 0)
+                       if (c2 == 0 && c1 == 0)
                                return ENOSPC;
                        if (c2 == 0) {
-                               if (limit)
-                                       limit->limit = limit->count =
-               ext2fs_cpu_to_le16(limit->limit);
-                               root = (struct ext2_dx_entry *)
-                                       (outdir->buf + root_offset);
-                               root->block = ext2fs_cpu_to_le32(outdir->num);
-                               if (i != 1)
-                                       root->hash =
-                       ext2fs_cpu_to_le32(outdir->hashes[i]);
-                               if ((retval =  get_next_block(fs, outdir,
-                                                             &block_start)))
+                               retval = alloc_blocks(fs, &limit, &root,
+                                                     &dx_ent, &root_offset,
+                                                     NULL, outdir, i, &c1,
+                                                     &c2);
+                               if (retval)
                                        return retval;
-                               dx_ent = set_int_node(fs, block_start);
-                               limit = (struct ext2_dx_countlimit *) dx_ent;
-                               c2 = limit->limit;
-                               root_offset += sizeof(struct ext2_dx_entry);
-                               c1--;
                        }
                        dx_ent->block = ext2fs_cpu_to_le32(i);
                        if (c2 != limit->limit)
@@ -674,6 +700,45 @@ static errcode_t calculate_tree(ext2_filsys fs,
                }
                limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
                limit->limit = ext2fs_cpu_to_le16(limit->limit);
+       } else {
+               c2 = 0;
+               c3 = 0;
+               limit = NULL;
+               int_limit = 0;
+               root_info->indirect_levels = 2;
+               for (i = 1; i < nblks; i++) {
+                       if (c3 == 0 && c2 == 0 && c1 == 0)
+                               return ENOSPC;
+                       if (c3 == 0 && c2 == 0) {
+                               retval = alloc_blocks(fs, &int_limit, &root,
+                                                     &int_ent, &root_offset,
+                                                     &int_offset, outdir, i,
+                                                     &c1, &c2);
+                               if (retval)
+                                       return retval;
+                       }
+                       if (c3 == 0) {
+                               retval = alloc_blocks(fs, &limit, &int_ent,
+                                                     &dx_ent, &int_offset,
+                                                     NULL, outdir, i, &c2,
+                                                     &c3);
+                               if (retval)
+                                       return retval;
+
+                       }
+                       dx_ent->block = ext2fs_cpu_to_le32(i);
+                       if (c3 != limit->limit)
+                               dx_ent->hash =
+                                       ext2fs_cpu_to_le32(outdir->hashes[i]);
+                       dx_ent++;
+                       c3--;
+               }
+               int_limit->count = ext2fs_cpu_to_le16(limit->limit - c2);
+               int_limit->limit = ext2fs_cpu_to_le16(limit->limit);
+
+               limit->count = ext2fs_cpu_to_le16(limit->limit - c3);
+               limit->limit = ext2fs_cpu_to_le16(limit->limit);
+
        }
        root_limit = (struct ext2_dx_countlimit *) (outdir->buf + limit_offset);
        root_limit->count = ext2fs_cpu_to_le16(root_limit->limit - c1);
index ad2df96..7841358 100644 (file)
@@ -2726,7 +2726,7 @@ struct ext2_inode {
        __u32   i_block[EXT2_N_BLOCKS]; /* Pointers to blocks */
        __u32   i_version;              /* File version (for NFS) */
        __u32   i_file_acl;             /* File ACL */
-       __u32   i_dir_acl;              /* Directory ACL */
+       __u32   i_size_high;            /* High 32bits of size */
        __u32   i_faddr;                /* Fragment address */
        union {
                struct {
index a6ebf5a..900c393 100644 (file)
@@ -487,7 +487,7 @@ struct ext2_inode {
        __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
        __u32   i_version;      /* File version (for NFS) */
        __u32   i_file_acl;     /* File ACL */
-       __u32   i_dir_acl;      /* Directory ACL */
+       __u32   i_size_high;    /* High 32bits of size */
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
index bf927b0..b1ac4c4 100644 (file)
@@ -102,7 +102,7 @@ struct ext2_inode {
        __u32  i_block[14]; /* Pointers to blocks */
        __u32  i_version;       /* File version (for NFS) */
        __u32  i_file_acl;      /* File ACL */
-       __u32  i_dir_acl;       /* Directory ACL */
+       __u32  i_size_high;     /* High 32bits of size */
        __u32  i_faddr;         /* Fragment address */
        __u8   l_i_frag;        /* Fragment number */
        __u8   l_i_fsize;       /* Fragment size */
index 8e5bc90..eb87011 100644 (file)
@@ -1,10 +1,11 @@
 #ifndef _LINUX_TYPES_H
 #define _LINUX_TYPES_H
 
-#ifndef _MSC_VER
-#error  _MSC_VER not defined
-#endif
+//#ifndef _MSC_VER
+//#error  _MSC_VER not defined
+//#endif
 
+#include <sys/types.h>
 
 typedef unsigned __int8 __u8;
 typedef signed __int8 __s8;
@@ -22,7 +23,11 @@ typedef      signed   __int64        __s64;
 typedef        unsigned __int64        __u64;
 
 
-typedef __u32 ino_t;
+//typedef __u32 ino_t;
+typedef __u32 dev_t;
+typedef __u32 uid_t;
+typedef __u32 gid_t;
 
+#include <stdint.h>
 
 #endif /* LINUX_TYPES_H */
index db6d7d7..66d7512 100644 (file)
@@ -293,7 +293,7 @@ charset.alias: $(srcdir)/config.charset
        $(Q) $(SHELL) $(srcdir)/config.charset '@host@' > t-$@
        $(Q) mv t-$@ $@
 
-check: all
+fullcheck check: all
 
 # We must not install the libintl.h/libintl.a files if we are on a
 # system which has the GNU gettext() function in its C library or in a
diff --git a/lib/Android.bp b/lib/Android.bp
new file mode 100644 (file)
index 0000000..b38d8b1
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2017 The Android Open Source Project
+
+// All the libraries under this directory export their headers as relative
+// paths to this directory (external/e2fsprogs/lib). This is a helper headers
+// only library to allow exporting
+cc_library_headers {
+    name: "libext2-headers",
+    host_supported: true,
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
+    export_include_dirs: ["."],
+}
+
+
+subdirs = [
+    "*",
+]
diff --git a/lib/Android.mk b/lib/Android.mk
deleted file mode 100644 (file)
index 5053e7d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-include $(call all-subdir-makefiles)
diff --git a/lib/blkid/Android.bp b/lib/blkid/Android.bp
new file mode 100644 (file)
index 0000000..9b385f9
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_blkid",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "cache.c",
+        "dev.c",
+        "devname.c",
+        "devno.c",
+        "getsize.c",
+        "llseek.c",
+        "probe.c",
+        "read.c",
+        "resolve.c",
+        "save.c",
+        "tag.c",
+        "version.c",
+    ],
+    shared_libs: ["libext2_uuid"],
+
+    cflags: [
+        "-W",
+        "-Wall",
+        "-fno-strict-aliasing",
+        "-Wno-macro-redefined",
+    ],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/blkid/Android.mk b/lib/blkid/Android.mk
deleted file mode 100644 (file)
index 857c4f9..0000000
+++ /dev/null
@@ -1,62 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_blkid_src_files := \
-       cache.c \
-       dev.c \
-       devname.c \
-       devno.c \
-       getsize.c \
-       llseek.c \
-       probe.c \
-       read.c \
-       resolve.c \
-       save.c \
-       tag.c \
-       version.c \
-
-
-libext2_blkid_shared_libraries := libext2_uuid
-
-libext2_blkid_system_shared_libraries := libc
-
-libext2_blkid_static_libraries := libext2_uuid_static
-
-libext2_blkid_system_static_libraries := libc
-
-libext2_blkid_c_includes := external/e2fsprogs/lib
-
-libext2_blkid_cflags := -O2 -g -W -Wall -fno-strict-aliasing
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_blkid_src_files)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_blkid_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(libext2_blkid_shared_libraries)
-LOCAL_C_INCLUDES := $(libext2_blkid_c_includes)
-LOCAL_CFLAGS := $(libext2_blkid_cflags)
-LOCAL_MODULE := libext2_blkid
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_blkid_src_files)
-LOCAL_STATIC_LIBRARIES := $(libext2_blkid_static_libraries) $(libext2_blkid_system_static_libraries)
-LOCAL_C_INCLUDES := $(libext2_blkid_c_includes)
-LOCAL_CFLAGS := $(libext2_blkid_cflags) $(libext2_blkid_cflags_linux) -fno-strict-aliasing
-LOCAL_MODULE := libext2_blkid
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_blkid_src_files)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(libext2_blkid_shared_libraries))
-LOCAL_C_INCLUDES := $(libext2_blkid_c_includes)
-LOCAL_CFLAGS := $(libext2_blkid_cflags)
-LOCAL_MODULE := libext2_blkid-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index 7f38452..0be2da5 100644 (file)
@@ -135,8 +135,9 @@ test_probe: test_probe.in Makefile
        $(Q) cat $(srcdir)/test_probe.in >> test_probe
        $(Q) chmod +x test_probe
 
-check:: all tst_cache tst_dev tst_devname tst_devno tst_getsize tst_probe \
- tst_read tst_resolve tst_save tst_tag test_probe tst_types
+fullcheck check:: all tst_cache tst_dev tst_devname tst_devno \
+ tst_getsize tst_probe tst_read tst_resolve tst_save tst_tag \
+ test_probe tst_types
        ./test_probe
        ./tst_types
 
index 671e781..444afdc 100644 (file)
@@ -397,7 +397,7 @@ static int probe_all(blkid_cache cache, int only_if_new)
 {
        FILE *proc;
        char line[1024];
-       char ptname0[128], ptname1[128], *ptname = 0;
+       char ptname0[129], ptname1[129], *ptname = 0;
        char *ptnames[2];
        dev_t devs[2];
        int ma, mi;
diff --git a/lib/e2p/Android.bp b/lib/e2p/Android.bp
new file mode 100644 (file)
index 0000000..db51670
--- /dev/null
@@ -0,0 +1,41 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_e2p",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "feature.c",
+        "fgetflags.c",
+        "fsetflags.c",
+        "fgetproject.c",
+        "fsetproject.c",
+        "fgetversion.c",
+        "fsetversion.c",
+        "getflags.c",
+        "getversion.c",
+        "hashstr.c",
+        "iod.c",
+        "ls.c",
+        "mntopts.c",
+        "parse_num.c",
+        "pe.c",
+        "pf.c",
+        "ps.c",
+        "setflags.c",
+        "setversion.c",
+        "uuid.c",
+        "ostype.c",
+        "percent.c",
+    ],
+
+    cflags: [
+        "-W",
+        "-Wall",
+        "-Wno-macro-redefined",
+    ],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/e2p/Android.mk b/lib/e2p/Android.mk
deleted file mode 100644 (file)
index 8a732c3..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_e2p_src_files := \
-       feature.c \
-       fgetflags.c \
-       fsetflags.c \
-       fgetproject.c \
-       fsetproject.c \
-       fgetversion.c \
-       fsetversion.c \
-       getflags.c \
-       getversion.c \
-       hashstr.c \
-       iod.c \
-       ls.c \
-       mntopts.c \
-       parse_num.c \
-       pe.c \
-       pf.c \
-       ps.c \
-       setflags.c \
-       setversion.c \
-       uuid.c \
-       ostype.c \
-       percent.c
-
-libext2_e2p_c_includes := external/e2fsprogs/lib
-
-libext2_e2p_cflags := -O2 -g -W -Wall
-
-libext2_e2p_system_shared_libraries := libc
-
-libext2_e2p_system_static_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_e2p_src_files)
-LOCAL_C_INCLUDES := $(libext2_e2p_c_includes)
-LOCAL_CFLAGS := $(libext2_e2p_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_e2p_system_shared_libraries)
-LOCAL_MODULE := libext2_e2p
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_e2p_src_files)
-LOCAL_C_INCLUDES := $(libext2_e2p_c_includes)
-LOCAL_CFLAGS := $(libext2_e2p_cflags)
-LOCAL_STATIC_LIBRARIES := $(libext2_e2p_system_static_libraries)
-LOCAL_MODULE := libext2_e2p
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_e2p_src_files)
-LOCAL_C_INCLUDES := $(libext2_e2p_c_includes)
-LOCAL_CFLAGS := $(libext2_e2p_cflags)
-LOCAL_MODULE := libext2_e2p-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index 6fd2cec..d266d68 100644 (file)
@@ -75,7 +75,7 @@ tst_feature: $(srcdir)/feature.c
        $(Q) $(CC) -DTEST_PROGRAM -I$(top_srcdir)/lib -o tst_feature \
                $(srcdir)/feature.c $(ALL_CFLAGS) $(ALL_LDFLAGS)
 
-check::        tst_ostype tst_feature
+fullcheck check::      tst_ostype tst_feature
        ./tst_ostype
        ./tst_feature
 
diff --git a/lib/et/Android.bp b/lib/et/Android.bp
new file mode 100644 (file)
index 0000000..f6ad416
--- /dev/null
@@ -0,0 +1,28 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_com_err",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "error_message.c",
+        "et_name.c",
+        "init_et.c",
+        "com_err.c",
+        "com_right.c",
+    ],
+
+    cflags: [
+        "-W",
+        "-Wall",
+    ],
+    target: {
+        windows: {
+            enabled: true,
+        },
+    },
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/et/Android.mk b/lib/et/Android.mk
deleted file mode 100644 (file)
index 8704f4c..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_com_err_src_files := \
-       error_message.c \
-       et_name.c \
-       init_et.c \
-       com_err.c \
-       com_right.c
-
-libext2_com_err_c_includes := external/e2fsprogs/lib
-
-libext2_com_err_cflags := -O2 -g -W -Wall
-
-libext2_com_err_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_com_err_src_files)
-LOCAL_C_INCLUDES := $(libext2_com_err_c_includes)
-LOCAL_CFLAGS := $(libext2_com_err_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := libc
-LOCAL_MODULE := libext2_com_err
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_com_err_src_files)
-LOCAL_C_INCLUDES := $(libext2_com_err_c_includes)
-LOCAL_CFLAGS := $(libext2_com_err_cflags)
-LOCAL_STATIC_LIBRARIES := libc
-LOCAL_MODULE := libext2_com_err
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_com_err_src_files)
-LOCAL_C_INCLUDES := $(libext2_com_err_c_includes)
-LOCAL_CFLAGS := $(libext2_com_err_cflags)
-LOCAL_MODULE := libext2_com_err-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index 476f189..0344679 100644 (file)
@@ -137,7 +137,7 @@ uninstall::
                $(DESTDIR)$(pkgconfigdir)/com_err.pc
        $(RM) -rf $(DESTDIR)$(includedir)/et $(DESTDIR)$(datadir)/et
 
-check:: compile_et
+fullcheck check:: compile_et
        for i in $(srcdir)/test_cases/*.et ; do \
                t=`basename $$i | sed -e 's/.et//'`; \
                _ET_DIR_OVERRIDE=$(srcdir) ./compile_et $$i ; \
index fe79122..5dd8aa6 100644 (file)
@@ -35,7 +35,9 @@
 #if HAVE_UNISTD_H
 #include <unistd.h>
 #endif
+#if HAVE_FCNTL
 #include <fcntl.h>
+#endif
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
@@ -196,8 +198,10 @@ oops:
  */
 static char *safe_getenv(const char *arg)
 {
+#if !defined(_WIN32)
        if ((getuid() != geteuid()) || (getgid() != getegid()))
                return NULL;
+#endif
 #if HAVE_PRCTL
        if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
                return NULL;
@@ -249,11 +253,13 @@ static void init_debug(void)
                debug_f = fopen("/dev/tty", "a");
        if (debug_f) {
                fd = fileno(debug_f);
+#if defined(HAVE_FCNTL)
                if (fd >= 0) {
                        flags = fcntl(fd, F_GETFD);
                        if (flags >= 0)
                                fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
                }
+#endif
        } else
                debug_mask = DEBUG_INIT;
 
diff --git a/lib/ext2fs/Android.bp b/lib/ext2fs/Android.bp
new file mode 100644 (file)
index 0000000..df07a9b
--- /dev/null
@@ -0,0 +1,134 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2fs",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "ext2_err.c",
+        "alloc.c",
+        "alloc_sb.c",
+        "alloc_stats.c",
+        "alloc_tables.c",
+        "atexit.c",
+        "badblocks.c",
+        "bb_inode.c",
+        "bitmaps.c",
+        "bitops.c",
+        "blkmap64_ba.c",
+        "blkmap64_rb.c",
+        "blknum.c",
+        "block.c",
+        "bmap.c",
+        "check_desc.c",
+        "crc16.c",
+        "crc32c.c",
+        "csum.c",
+        "closefs.c",
+        "dblist.c",
+        "dblist_dir.c",
+        "digest_encode.c",
+        "dirblock.c",
+        "dirhash.c",
+        "dir_iterate.c",
+        "dupfs.c",
+        "expanddir.c",
+        "ext_attr.c",
+        "extent.c",
+        "fallocate.c",
+        "fileio.c",
+        "finddev.c",
+        "flushb.c",
+        "freefs.c",
+        "gen_bitmap.c",
+        "gen_bitmap64.c",
+        "get_num_dirs.c",
+        "get_pathname.c",
+        "getsize.c",
+        "getsectsize.c",
+        "i_block.c",
+        "icount.c",
+        "imager.c",
+        "ind_block.c",
+        "initialize.c",
+        "inline.c",
+        "inline_data.c",
+        "inode.c",
+        "io_manager.c",
+        "ismounted.c",
+        "link.c",
+        "llseek.c",
+        "lookup.c",
+        "mmp.c",
+        "mkdir.c",
+        "mkjournal.c",
+        "namei.c",
+        "native.c",
+        "newdir.c",
+        "openfs.c",
+        "progress.c",
+        "punch.c",
+        "qcow2.c",
+        "rbtree.c",
+        "read_bb.c",
+        "read_bb_file.c",
+        "res_gdt.c",
+        "rw_bitmaps.c",
+        "sha256.c",
+        "sha512.c",
+        "swapfs.c",
+        "symlink.c",
+        "undo_io.c",
+        "unix_io.c",
+        "sparse_io.c",
+        "unlink.c",
+        "valid_blk.c",
+        "version.c",
+        // get rid of this?!
+        "test_io.c",
+    ],
+    shared_libs: [
+        "libsparse",
+    ],
+    whole_static_libs: [
+        "libext2_com_err"
+    ],
+    cflags: [
+        "-W",
+        "-Wall",
+        "-Wno-unused-parameter",
+        "-Wno-macro-redefined",
+    ],
+    target: {
+        host: {
+            shared_libs: ["libz-host"],
+            // Consider removing this library as a whole for the host. It is not
+            // in the android side.
+            whole_static_libs: ["libext2_com_err"],
+        },
+        android: {
+            shared_libs: [
+                "libext2_com_err",
+                "libext2_uuid",
+                "libz"
+            ],
+        },
+        windows: {
+            // include/nonunix is used as an overlay on top of the system
+            // include directory. Some empty header files in include/nonunix
+            // hide the ones in the system include path. This setup doesn't work
+            // unless we pass the include/nonunix as an -isystem flag.
+            // TODO(deymo): Enable windows
+            enabled: false,
+            cflags: [
+                "-Wno-format",
+            //    "-isystem external/e2fsprogs/include/nonunix",
+            ],
+            host_ldlibs: ["-lws2_32"],
+        },
+    },
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/ext2fs/Android.mk b/lib/ext2fs/Android.mk
deleted file mode 100644 (file)
index 356232f..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2fs_src_files := \
-       ext2_err.c \
-       alloc.c \
-       alloc_sb.c \
-       alloc_stats.c \
-       alloc_tables.c \
-       atexit.c \
-       badblocks.c \
-       bb_inode.c \
-       bitmaps.c \
-       bitops.c \
-       blkmap64_ba.c \
-       blkmap64_rb.c \
-       blknum.c \
-       block.c \
-       bmap.c \
-       check_desc.c \
-       crc16.c \
-       crc32c.c \
-       csum.c \
-       closefs.c \
-       dblist.c \
-       dblist_dir.c \
-       digest_encode.c \
-       dirblock.c \
-       dirhash.c \
-       dir_iterate.c \
-       dupfs.c \
-       expanddir.c \
-       ext_attr.c \
-       extent.c \
-       fallocate.c \
-       fileio.c \
-       finddev.c \
-       flushb.c \
-       freefs.c \
-       gen_bitmap.c \
-       gen_bitmap64.c \
-       get_num_dirs.c \
-       get_pathname.c \
-       getsize.c \
-       getsectsize.c \
-       i_block.c \
-       icount.c \
-       imager.c \
-       ind_block.c \
-       initialize.c \
-       inline.c \
-       inline_data.c \
-       inode.c \
-       io_manager.c \
-       ismounted.c \
-       link.c \
-       llseek.c \
-       lookup.c \
-       mmp.c \
-       mkdir.c \
-       mkjournal.c \
-       namei.c \
-       native.c \
-       newdir.c \
-       openfs.c \
-       progress.c \
-       punch.c \
-       qcow2.c \
-       rbtree.c \
-       read_bb.c \
-       read_bb_file.c \
-       res_gdt.c \
-       rw_bitmaps.c \
-       sha256.c \
-       sha512.c \
-       swapfs.c \
-       symlink.c \
-       undo_io.c \
-       unix_io.c \
-       unlink.c \
-       valid_blk.c \
-       version.c
-
-# get rid of this?!
-libext2fs_src_files += test_io.c
-
-libext2fs_shared_libraries := \
-       libext2_com_err \
-       libext2_uuid \
-       libext2_blkid \
-       libext2_e2p
-
-libext2fs_system_shared_libraries := libc
-
-libext2fs_static_libraries := \
-       libext2_com_err \
-       libext2_uuid_static \
-       libext2_blkid \
-       libext2_e2p
-
-libext2fs_system_static_libraries := libc
-
-libext2fs_c_includes := external/e2fsprogs/lib
-
-libext2fs_cflags := -O2 -g -W -Wall
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2fs_src_files)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2fs_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(libext2fs_shared_libraries)
-LOCAL_C_INCLUDES := $(libext2fs_c_includes)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(libext2fs_c_includes)
-LOCAL_CFLAGS := $(libext2fs_cflags)
-LOCAL_MODULE := libext2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2fs_src_files)
-LOCAL_STATIC_LIBRARIES := $(libext2fs_static_libraries) $(libext2fs_system_static_libraries)
-LOCAL_C_INCLUDES := $(libext2fs_c_includes)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(libext2fs_c_includes)
-LOCAL_CFLAGS := $(libext2fs_cflags) $(libext2fs_cflags_linux)
-LOCAL_MODULE := libext2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2fs_src_files)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(libext2fs_shared_libraries))
-LOCAL_C_INCLUDES := $(libext2fs_c_includes)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(libext2fs_c_includes)
-LOCAL_CFLAGS := $(libext2fs_cflags)
-LOCAL_MODULE := libext2fs-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index 425b856..b6b0f85 100644 (file)
@@ -125,6 +125,7 @@ OBJS= $(DEBUGFS_LIB_OBJS) $(RESIZE_LIB_OBJS) $(E2IMAGE_LIB_OBJS) \
        $(TDB_OBJ) \
        undo_io.o \
        unix_io.o \
+       sparse_io.o \
        unlink.o \
        valid_blk.o \
        version.o \
@@ -212,6 +213,7 @@ SRCS= ext2_err.c \
        $(srcdir)/tst_iscan.c \
        $(srcdir)/undo_io.c \
        $(srcdir)/unix_io.c \
+       $(srcdir)/sparse_io.c \
        $(srcdir)/unlink.c \
        $(srcdir)/valid_blk.c \
        $(srcdir)/version.c \
@@ -521,7 +523,7 @@ mkjournal: mkjournal.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
        $(Q) $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG \
                $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS) $(SYSLIBS)
 
-check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
+fullcheck check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
     tst_super_size tst_types tst_inode_size tst_csum tst_crc32c tst_bitmaps \
     tst_inline tst_inline_data tst_libext2fs tst_sha256 tst_sha512 \
     tst_digest_encode tst_getsize tst_getsectsize
@@ -1108,6 +1110,12 @@ unix_io.o: $(srcdir)/unix_io.c $(top_builddir)/lib/config.h \
  $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+sparse_io.o: $(srcdir)/sparse_io.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
+ $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
+ $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
 unlink.o: $(srcdir)/unlink.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
index f96ac4b..af21410 100644 (file)
@@ -144,27 +144,38 @@ errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir,
  * Stupid algorithm --- we now just search forward starting from the
  * goal.  Should put in a smarter one someday....
  */
-errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
-                          ext2fs_block_bitmap map, blk64_t *ret)
+errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal,
+                           ext2fs_block_bitmap map, blk64_t *ret,
+                           struct blk_alloc_ctx *ctx)
 {
        errcode_t retval;
        blk64_t b = 0;
        errcode_t (*gab)(ext2_filsys fs, blk64_t goal, blk64_t *ret);
+       errcode_t (*gab2)(ext2_filsys, blk64_t, blk64_t *,
+                         struct blk_alloc_ctx *);
 
        EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
-       if (!map && fs->get_alloc_block) {
+       if (!map) {
                /*
                 * In case there are clients out there whose get_alloc_block
                 * handlers call ext2fs_new_block2 with a NULL block map,
                 * temporarily swap out the function pointer so that we don't
                 * end up in an infinite loop.
                 */
-               gab = fs->get_alloc_block;
-               fs->get_alloc_block = NULL;
-               retval = gab(fs, goal, &b);
-               fs->get_alloc_block = gab;
-               goto allocated;
+               if (fs->get_alloc_block2) {
+                       gab2 = fs->get_alloc_block2;
+                       fs->get_alloc_block2 = NULL;
+                       retval = gab2(fs, goal, &b, ctx);
+                       fs->get_alloc_block2 = gab2;
+                       goto allocated;
+               } else if (fs->get_alloc_block) {
+                       gab = fs->get_alloc_block;
+                       fs->get_alloc_block = NULL;
+                       retval = gab(fs, goal, &b);
+                       fs->get_alloc_block = gab;
+                       goto allocated;
+               }
        }
        if (!map)
                map = fs->block_map;
@@ -190,6 +201,12 @@ allocated:
        return 0;
 }
 
+errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
+                          ext2fs_block_bitmap map, blk64_t *ret)
+{
+       return ext2fs_new_block3(fs, goal, map, ret, NULL);
+}
+
 errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
                           ext2fs_block_bitmap map, blk_t *ret)
 {
@@ -205,13 +222,17 @@ errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
  * This function zeros out the allocated block, and updates all of the
  * appropriate filesystem records.
  */
-errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
-                            char *block_buf, blk64_t *ret)
+errcode_t ext2fs_alloc_block3(ext2_filsys fs, blk64_t goal, char *block_buf,
+                             blk64_t *ret, struct blk_alloc_ctx *ctx)
 {
        errcode_t       retval;
        blk64_t         block;
 
-       if (fs->get_alloc_block) {
+       if (fs->get_alloc_block2) {
+               retval = (fs->get_alloc_block2)(fs, goal, &block, ctx);
+               if (retval)
+                       goto fail;
+       } else if (fs->get_alloc_block) {
                retval = (fs->get_alloc_block)(fs, goal, &block);
                if (retval)
                        goto fail;
@@ -222,7 +243,7 @@ errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
                                goto fail;
                }
 
-               retval = ext2fs_new_block2(fs, goal, 0, &block);
+               retval = ext2fs_new_block3(fs, goal, 0, &block, ctx);
                if (retval)
                        goto fail;
        }
@@ -242,15 +263,21 @@ fail:
        return retval;
 }
 
+errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
+                            char *block_buf, blk64_t *ret)
+{
+       return ext2fs_alloc_block3(fs, goal, block_buf, ret, NULL);
+}
+
 errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
                             char *block_buf, blk_t *ret)
 {
        errcode_t retval;
-       blk64_t val;
-       retval = ext2fs_alloc_block2(fs, goal, block_buf, &val);
+       blk64_t ret64, goal64 = goal;
+       retval = ext2fs_alloc_block3(fs, goal64, block_buf, &ret64, NULL);
        if (!retval)
-               *ret = (blk_t) val;
-       return retval;
+               *ret = (blk_t)ret64;
+        return retval;
 }
 
 errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
index bc59608..505b3c9 100644 (file)
@@ -108,7 +108,7 @@ extern void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap,
 extern int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
                                          blk_t block, int num);
 extern int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
-                                         ino_t inode, int num);
+                                         ext2_ino_t inode, int num);
 extern int ext2fs_mark_generic_bitmap(ext2fs_generic_bitmap bitmap,
                                         __u32 bitno);
 extern int ext2fs_unmark_generic_bitmap(ext2fs_generic_bitmap bitmap,
index 7e7e29d..8d5ddd3 100644 (file)
@@ -9,6 +9,7 @@
  * %End-Header%
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <string.h>
 #if HAVE_UNISTD_H
@@ -22,6 +23,9 @@
 #if HAVE_SYS_TYPES_H
 #include <sys/types.h>
 #endif
+#if HAVE_LINUX_TYPES_H
+#include <linux/types.h>
+#endif
 
 #include "ext2_fs.h"
 #include "ext2fsP.h"
index 29da4ef..1ed98aa 100644 (file)
@@ -207,6 +207,7 @@ static errcode_t extent_bmap(ext2_filsys fs, ext2_ino_t ino,
                             int *ret_flags, int *blocks_alloc,
                             blk64_t *phys_blk)
 {
+       struct blk_alloc_ctx    alloc_ctx;
        struct ext2fs_extent    extent;
        unsigned int            offset;
        errcode_t               retval = 0;
@@ -246,8 +247,12 @@ got_block:
                                     0, block-1, 0, blocks_alloc, &blk64);
                if (retval)
                        blk64 = ext2fs_find_inode_goal(fs, ino, inode, block);
-               retval = ext2fs_alloc_block2(fs, blk64, block_buf,
-                                            &blk64);
+               alloc_ctx.ino = ino;
+               alloc_ctx.inode = inode;
+               alloc_ctx.lblk = extent.e_lblk;
+               alloc_ctx.flags = BLOCK_ALLOC_DATA;
+               retval = ext2fs_alloc_block3(fs, blk64, block_buf, &blk64,
+                                            &alloc_ctx);
                if (retval)
                        return retval;
                blk64 &= ~EXT2FS_CLUSTER_MASK(fs);
@@ -300,9 +305,16 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
        ext2_extent_handle_t handle = 0;
        blk_t addr_per_block;
        blk_t   b, blk32;
+       blk64_t b64;
        char    *buf = 0;
        errcode_t       retval = 0;
        int             blocks_alloc = 0, inode_dirty = 0;
+       struct blk_alloc_ctx alloc_ctx = {
+               .ino    = ino,
+               .inode  = inode,
+               .lblk   = 0,
+               .flags  = BLOCK_ALLOC_DATA,
+       };
 
        if (!(bmap_flags & BMAP_SET))
                *phys_blk = 0;
@@ -359,7 +371,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
                            ext2fs_find_inode_goal(fs, ino, inode, block);
 
                if ((*phys_blk == 0) && (bmap_flags & BMAP_ALLOC)) {
-                       retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+                       b64 = b;
+                       retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64,
+                                                    &alloc_ctx);
+                       b = b64;
                        if (retval)
                                goto done;
                        inode_bmap(inode, block) = b;
@@ -382,7 +397,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
                        }
 
                        b = inode_bmap(inode, EXT2_IND_BLOCK-1);
-                       retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+                       b64 = b;
+                       retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64,
+                                                    &alloc_ctx);
+                       b = b64;
                        if (retval)
                                goto done;
                        inode_bmap(inode, EXT2_IND_BLOCK) = b;
@@ -407,7 +425,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
                        }
 
                        b = inode_bmap(inode, EXT2_IND_BLOCK);
-                       retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+                       b64 = b;
+                       retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64,
+                                                    &alloc_ctx);
+                       b = b64;
                        if (retval)
                                goto done;
                        inode_bmap(inode, EXT2_DIND_BLOCK) = b;
@@ -431,7 +452,10 @@ errcode_t ext2fs_bmap2(ext2_filsys fs, ext2_ino_t ino, struct ext2_inode *inode,
                }
 
                b = inode_bmap(inode, EXT2_DIND_BLOCK);
-               retval = ext2fs_alloc_block(fs, b, block_buf, &b);
+               b64 = b;
+               retval = ext2fs_alloc_block3(fs, b64, block_buf, &b64,
+                                            &alloc_ctx);
+               b = b64;
                if (retval)
                        goto done;
                inode_bmap(inode, EXT2_TIND_BLOCK) = b;
index 27a7d3a..66b7058 100644 (file)
@@ -398,7 +398,7 @@ struct ext2_inode {
        __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
        __u32   i_generation;   /* File version (for NFS) */
        __u32   i_file_acl;     /* File ACL */
-       __u32   i_size_high;    /* Formerly i_dir_acl, directory ACL */
+       __u32   i_size_high;
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
@@ -446,7 +446,7 @@ struct ext2_inode_large {
        __u32   i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
        __u32   i_generation;   /* File version (for NFS) */
        __u32   i_file_acl;     /* File ACL */
-       __u32   i_size_high;    /* Formerly i_dir_acl, directory ACL */
+       __u32   i_size_high;
        __u32   i_faddr;        /* Fragment address */
        union {
                struct {
@@ -484,8 +484,6 @@ struct ext2_inode_large {
 #define EXT4_EPOCH_BITS 2
 #define EXT4_EPOCH_MASK ((1 << EXT4_EPOCH_BITS) - 1)
 
-#define i_dir_acl      i_size_high
-
 #define i_checksum_lo  osd2.linux2.l_i_checksum_lo
 
 #define inode_includes(size, field)                    \
@@ -923,7 +921,8 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt,                4, ENCRYPT)
 
 #define EXT2_FEATURE_COMPAT_SUPP       0
 #define EXT2_FEATURE_INCOMPAT_SUPP    (EXT2_FEATURE_INCOMPAT_FILETYPE| \
-                                      EXT4_FEATURE_INCOMPAT_MMP)
+                                      EXT4_FEATURE_INCOMPAT_MMP| \
+                                      EXT4_FEATURE_INCOMPAT_LARGEDIR)
 #define EXT2_FEATURE_RO_COMPAT_SUPP    (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \
                                         EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \
                                         EXT4_FEATURE_RO_COMPAT_DIR_NLINK| \
index 6b7e977..5540900 100644 (file)
@@ -12,6 +12,8 @@
 #ifndef _EXT2FS_EXT2_IO_H
 #define _EXT2FS_EXT2_IO_H
 
+#include <ext2fs/ext2_types.h>
+
 /*
  * ext2_loff_t is defined here since unix_io.c needs it.
  */
@@ -141,6 +143,10 @@ extern errcode_t io_channel_cache_readahead(io_channel io,
 extern io_manager unix_io_manager;
 extern io_manager unixfd_io_manager;
 
+/* sparse_io.c */
+extern io_manager sparse_io_manager;
+extern io_manager sparsefd_io_manager;
+
 /* undo_io.c */
 extern io_manager undo_io_manager;
 extern errcode_t set_undo_io_backing_manager(io_manager manager);
index 8ff49ca..c18ea5f 100644 (file)
@@ -209,6 +209,7 @@ typedef struct ext2_file *ext2_file_t;
 #define EXT2_MKJOURNAL_LAZYINIT        0x0000002 /* don't zero journal inode before use*/
 #define EXT2_MKJOURNAL_NO_MNT_CHECK 0x0000004 /* don't check mount status */
 
+struct blk_alloc_ctx;
 struct opaque_ext2_group_desc;
 
 struct struct_ext2_filsys {
@@ -264,6 +265,8 @@ struct struct_ext2_filsys {
         */
        errcode_t (*get_alloc_block)(ext2_filsys fs, blk64_t goal,
                                     blk64_t *ret);
+       errcode_t (*get_alloc_block2)(ext2_filsys fs, blk64_t goal,
+                                     blk64_t *ret, struct blk_alloc_ctx *ctx);
        void (*block_alloc_stats)(ext2_filsys fs, blk64_t blk, int inuse);
 
        /*
@@ -355,6 +358,17 @@ struct struct_ext2_filsys {
 #define BLOCK_COUNT_TIND       (-3)
 #define BLOCK_COUNT_TRANSLATOR (-4)
 
+#define BLOCK_ALLOC_UNKNOWN    0
+#define BLOCK_ALLOC_DATA       1
+#define BLOCK_ALLOC_METADATA   2
+
+struct blk_alloc_ctx {
+       ext2_ino_t              ino;
+       struct ext2_inode       *inode;
+       blk64_t                 lblk;
+       int                     flags;
+};
+
 #if 0
 /*
  * Flags for ext2fs_move_blocks
@@ -588,7 +602,8 @@ typedef struct ext2_icount *ext2_icount_t;
                                         EXT4_FEATURE_INCOMPAT_64BIT|\
                                         EXT4_FEATURE_INCOMPAT_INLINE_DATA|\
                                         EXT4_FEATURE_INCOMPAT_ENCRYPT|\
-                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED)
+                                        EXT4_FEATURE_INCOMPAT_CSUM_SEED|\
+                                        EXT4_FEATURE_INCOMPAT_LARGEDIR)
 
 #define EXT2_LIB_FEATURE_RO_COMPAT_SUPP        (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER|\
                                         EXT4_FEATURE_RO_COMPAT_HUGE_FILE|\
@@ -662,6 +677,9 @@ extern errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
                                  ext2fs_block_bitmap map, blk_t *ret);
 extern errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
                                   ext2fs_block_bitmap map, blk64_t *ret);
+extern errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal,
+                                  ext2fs_block_bitmap map, blk64_t *ret,
+                                  struct blk_alloc_ctx *ctx);
 extern errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start,
                                        blk_t finish, int num,
                                        ext2fs_block_bitmap map,
@@ -674,6 +692,10 @@ extern errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
                                    char *block_buf, blk_t *ret);
 extern errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
                                     char *block_buf, blk64_t *ret);
+extern errcode_t ext2fs_alloc_block3(ext2_filsys fs, blk64_t goal,
+                                    char *block_buf, blk64_t *ret,
+                                    struct blk_alloc_ctx *ctx);
+
 extern void ext2fs_set_alloc_block_callback(ext2_filsys fs,
                                            errcode_t (*func)(ext2_filsys fs,
                                                              blk64_t goal,
@@ -1927,6 +1949,23 @@ _INLINE_ blk_t ext2fs_inode_data_blocks(ext2_filsys fs,
        return (blk_t) ext2fs_inode_data_blocks2(fs, inode);
 }
 
+/* htree levels for ext4 */
+#define EXT4_HTREE_LEVEL_COMPAT 2
+#define EXT4_HTREE_LEVEL       3
+
+static inline unsigned int ext2_dir_htree_level(ext2_filsys fs)
+{
+       if (ext2fs_has_feature_largedir(fs->super))
+               return EXT4_HTREE_LEVEL;
+
+       return EXT4_HTREE_LEVEL_COMPAT;
+}
+
+_INLINE_ int ext2fs_htree_intnode_maxrecs(ext2_filsys fs, int blocks)
+{
+       return blocks * ((fs->blocksize - 8) / sizeof(struct ext2_dx_entry));
+}
+
 /*
  * This is an efficient, overflow safe way of calculating ceil((1.0 * a) / b)
  */
index 98821fc..fe1d3e7 100644 (file)
@@ -58,8 +58,10 @@ errcode_t ext2fs_sync_device(int fd, int flushb)
         * still is a race condition for those kernels, but this
         * reduces it greatly.)
         */
+#if defined(HAVE_FSYNC)
        if (fsync (fd) == -1)
                return errno;
+#endif
 
        if (flushb) {
 
index 6cd6fe6..d0061b8 100644 (file)
@@ -564,7 +564,7 @@ int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
 }
 
 int ext2fs_test_inode_bitmap_range(ext2fs_inode_bitmap bitmap,
-                                  ino_t inode, int num)
+                                  ext2_ino_t inode, int num)
 {
        EXT2_CHECK_MAGIC(bitmap, EXT2_ET_MAGIC_INODE_BITMAP);
        if ((inode < bitmap->start) || (inode+num-1 > bitmap->real_end)) {
index 75a0596..9137367 100644 (file)
@@ -7,7 +7,11 @@
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
 #endif
+#ifdef HAVE_WINSOCK_H
+#include <winsock.h>
+#else
 #include <arpa/inet.h>
+#endif
 
 #define printk printf
 #define KERN_ERR ""
diff --git a/lib/ext2fs/sparse_io.c b/lib/ext2fs/sparse_io.c
new file mode 100644 (file)
index 0000000..a307859
--- /dev/null
@@ -0,0 +1,541 @@
+#include "config.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdint.h>
+#include "ext2_fs.h"
+#include "ext2fs.h"
+
+#if !defined(ENABLE_LIBSPARSE)
+static errcode_t sparse_open(const char *name EXT2FS_ATTR((unused)),
+                            int flags EXT2FS_ATTR((unused)),
+                            io_channel *channel EXT2FS_ATTR((unused)))
+{
+       return EXT2_ET_UNIMPLEMENTED;
+}
+static errcode_t sparse_close(io_channel channel EXT2FS_ATTR((unused)))
+{
+       return EXT2_ET_UNIMPLEMENTED;
+}
+static struct struct_io_manager struct_sparse_manager = {
+       .magic                  = EXT2_ET_MAGIC_IO_MANAGER,
+       .name                   = "Android sparse I/O Manager",
+       .open                   = sparse_open,
+       .close                  = sparse_close,
+};
+static struct struct_io_manager struct_sparsefd_manager = {
+       .magic                  = EXT2_ET_MAGIC_IO_MANAGER,
+       .name                   = "Android sparse fd I/O Manager",
+       .open                   = sparse_open,
+       .close                  = sparse_close,
+};
+#else
+#include <sparse/sparse.h>
+
+struct sparse_map {
+       int                     fd;
+       char                    **blocks;
+       int                     block_size;
+       uint64_t                blocks_count;
+       char                    *file;
+       struct sparse_file      *sparse_file;
+       io_channel              channel;
+};
+
+struct sparse_io_params {
+       int                     fd;
+       char                    *file;
+       uint64_t                blocks_count;
+       unsigned int            block_size;
+};
+
+static errcode_t sparse_write_blk(io_channel channel, unsigned long block,
+                                 int count, const void *buf);
+
+static void free_sparse_blocks(struct sparse_map *sm)
+{
+       uint64_t i;
+
+       for (i = 0; i < sm->blocks_count; ++i)
+               free(sm->blocks[i]);
+       free(sm->blocks);
+       sm->blocks = NULL;
+}
+
+static int sparse_import_segment(void *priv, const void *data, int len,
+                                unsigned int block, unsigned int nr_blocks)
+{
+       struct sparse_map *sm = priv;
+
+       /* Ignore chunk headers, only write the data */
+       if (!nr_blocks || len % sm->block_size)
+               return 0;
+
+       return sparse_write_blk(sm->channel, block, nr_blocks, data);
+}
+
+static errcode_t io_manager_import_sparse(struct sparse_io_params *params,
+                                         struct sparse_map *sm, io_channel io)
+{
+       int fd;
+       errcode_t retval;
+       struct sparse_file *sparse_file;
+
+       if (params->fd < 0) {
+               fd = open(params->file, O_RDONLY);
+               if (fd < 0) {
+                       retval = -1;
+                       goto err_open;
+               }
+       } else
+               fd = params->fd;
+       sparse_file = sparse_file_import(fd, false, false);
+       if (!sparse_file) {
+               retval = -1;
+               goto err_sparse;
+       }
+
+       sm->block_size = sparse_file_block_size(sparse_file);
+       sm->blocks_count = (sparse_file_len(sparse_file, 0, 0) - 1)
+                               / sm->block_size + 1;
+       sm->blocks = calloc(sm->blocks_count, sizeof(char*));
+       if (!sm->blocks) {
+               retval = -1;
+               goto err_alloc;
+       }
+       io->block_size = sm->block_size;
+
+       retval = sparse_file_foreach_chunk(sparse_file, true, false,
+                                          sparse_import_segment, sm);
+
+       if (retval)
+               free_sparse_blocks(sm);
+err_alloc:
+       sparse_file_destroy(sparse_file);
+err_sparse:
+       close(fd);
+err_open:
+       return retval;
+}
+
+static errcode_t io_manager_configure(struct sparse_io_params *params,
+                                     int flags, io_channel io)
+{
+       errcode_t retval;
+       uint64_t img_size;
+       struct sparse_map *sm = calloc(1, sizeof(*sm));
+       if (!sm)
+               return EXT2_ET_NO_MEMORY;
+
+       sm->file = params->file;
+       sm->channel = io;
+       io->private_data = sm;
+       retval = io_manager_import_sparse(params, sm, io);
+       if (retval) {
+               if (!params->block_size || !params->blocks_count) {
+                       retval = -EINVAL;
+                       goto err_params;
+               }
+               sm->block_size = params->block_size;
+               sm->blocks_count = params->blocks_count;
+               sm->blocks = calloc(params->blocks_count, sizeof(void*));
+               if (!sm->blocks) {
+                       retval = EXT2_ET_NO_MEMORY;
+                       goto err_alloc;
+               }
+       }
+       io->block_size = sm->block_size;
+       img_size = (uint64_t)sm->block_size * sm->blocks_count;
+
+       if (flags & IO_FLAG_RW) {
+               sm->sparse_file = sparse_file_new(sm->block_size, img_size);
+               if (!sm->sparse_file) {
+                       retval = EXT2_ET_NO_MEMORY;
+                       goto err_alloc;
+               }
+               if (params->fd < 0) {
+                       sm->fd = open(params->file, O_CREAT | O_RDWR | O_TRUNC,
+                                     0644);
+                       if (sm->fd < 0) {
+                               retval = errno;
+                               goto err_open;
+                       }
+               } else
+                       sm->fd = params->fd;
+       } else {
+               sm->fd = -1;
+               sm->sparse_file = NULL;
+       }
+       return 0;
+
+err_open:
+       sparse_file_destroy(sm->sparse_file);
+err_alloc:
+       free_sparse_blocks(sm);
+err_params:
+       free(sm);
+       return retval;
+}
+
+static errcode_t sparse_open_channel(struct sparse_io_params *sparse_params,
+                                    int flags, io_channel *channel)
+{
+       io_channel io;
+
+       io = calloc(1, sizeof(struct struct_io_channel));
+       io->magic = EXT2_ET_MAGIC_IO_CHANNEL;
+       io->block_size = 0;
+       io->refcount = 1;
+       *channel = io;
+       return io_manager_configure(sparse_params, flags, io);
+}
+
+static errcode_t read_sparse_argv(const char *name, bool is_fd,
+                                 struct sparse_io_params *sparse_params)
+{
+       int ret;
+       sparse_params->fd = -1;
+       sparse_params->block_size = 0;
+       sparse_params->blocks_count = 0;
+
+       sparse_params->file = malloc(strlen(name) + 1);
+       if (!sparse_params->file) {
+               fprintf(stderr, "failed to alloc %zu\n", strlen(name) + 1);
+               return EXT2_ET_NO_MEMORY;
+       }
+
+       if (is_fd) {
+               ret = sscanf(name, "%d:%llu:%u", &sparse_params->fd,
+                            (unsigned long long *)&sparse_params->blocks_count,
+                            &sparse_params->block_size);
+       } else {
+               ret = sscanf(name, "%[^:]%*[:]%llu%*[:]%u", sparse_params->file,
+                            (unsigned long long *)&sparse_params->blocks_count,
+                            &sparse_params->block_size);
+       }
+
+       if (ret < 1) {
+               free(sparse_params->file);
+               return -EINVAL;
+       }
+       return 0;
+}
+
+static errcode_t sparse_open(const char *name, int flags, io_channel *channel)
+{
+       errcode_t retval;
+       struct sparse_io_params sparse_params;
+
+       retval = read_sparse_argv(name, false, &sparse_params);
+       if (retval)
+               return EXT2_ET_BAD_DEVICE_NAME;
+
+       retval = sparse_open_channel(&sparse_params, flags, channel);
+       if (retval)
+               return retval;
+       (*channel)->manager = sparse_io_manager;
+
+       return retval;
+}
+
+static errcode_t sparsefd_open(const char *name, int flags, io_channel *channel)
+{
+       errcode_t retval;
+       struct sparse_io_params sparse_params;
+
+       retval = read_sparse_argv(name, true, &sparse_params);
+       if (retval)
+               return EXT2_ET_BAD_DEVICE_NAME;
+
+       retval = sparse_open_channel(&sparse_params, flags, channel);
+       if (retval)
+               return retval;
+       (*channel)->manager = sparsefd_io_manager;
+
+       return retval;
+}
+
+static errcode_t sparse_merge_blocks(struct sparse_map *sm, uint64_t start,
+                                       uint64_t num)
+{
+       char *buf;
+       uint64_t i;
+       unsigned int block_size = sm->block_size;
+       errcode_t retval = 0;
+
+       buf = calloc(num, block_size);
+       if (!buf) {
+               fprintf(stderr, "failed to alloc %lu\n", num * block_size);
+               return EXT2_ET_NO_MEMORY;
+       }
+
+       for (i = 0; i < num; i++) {
+               memcpy(buf + i * block_size, sm->blocks[start + i] , block_size);
+               free(sm->blocks[start + i]);
+               sm->blocks[start + i] = NULL;
+       }
+
+       /* free_sparse_blocks will release this buf. */
+       sm->blocks[start] = buf;
+
+       retval = sparse_file_add_data(sm->sparse_file, sm->blocks[start],
+                                       block_size * num, start);
+
+       return retval;
+}
+
+static errcode_t sparse_close_channel(io_channel channel)
+{
+       uint64_t i;
+       errcode_t retval = 0;
+       struct sparse_map *sm = channel->private_data;
+
+       if (sm->sparse_file) {
+               int64_t chunk_start = (sm->blocks[0] == NULL) ? -1 : 0;
+               for (i = 0; i < sm->blocks_count; ++i) {
+                       if (!sm->blocks[i] && chunk_start != -1) {
+                               retval = sparse_merge_blocks(sm, chunk_start, i - chunk_start);
+                               chunk_start = -1;
+                       } else if (sm->blocks[i] && chunk_start == -1) {
+                               chunk_start = i;
+                       }
+                       if (retval)
+                               goto ret;
+               }
+               if (chunk_start != -1) {
+                       retval = sparse_merge_blocks(sm, chunk_start,
+                                                       sm->blocks_count - chunk_start);
+                       if (retval)
+                               goto ret;
+               }
+               retval = sparse_file_write(sm->sparse_file, sm->fd,
+                                          /*gzip*/0, /*sparse*/1, /*crc*/0);
+       }
+
+ret:
+       if (sm->sparse_file)
+               sparse_file_destroy(sm->sparse_file);
+       free_sparse_blocks(sm);
+       free(sm->file);
+       free(sm);
+       free(channel);
+       return retval;
+}
+
+static errcode_t sparse_close(io_channel channel)
+{
+       errcode_t retval;
+       struct sparse_map *sm = channel->private_data;
+       int fd = sm->fd;
+
+       retval = sparse_close_channel(channel);
+       if (fd >= 0)
+               close(fd);
+
+       return retval;
+}
+
+static errcode_t sparse_set_blksize(io_channel channel, int blksize)
+{
+       channel->block_size = blksize;
+       return 0;
+}
+
+static blk64_t block_to_sparse_block(blk64_t block, blk64_t *offset,
+                              io_channel channel, struct sparse_map *sm)
+{
+       int ratio;
+       blk64_t ret = block;
+
+       ratio = sm->block_size / channel->block_size;
+       ret /= ratio;
+       *offset = (block % ratio) * channel->block_size;
+
+       return ret;
+}
+
+static errcode_t check_block_size(io_channel channel, struct sparse_map *sm)
+{
+       if (sm->block_size >= channel->block_size)
+               return 0;
+       return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
+}
+
+static errcode_t sparse_read_blk64(io_channel channel, blk64_t block,
+                                  int count, void *buf)
+{
+       int i;
+       char *out = buf;
+       blk64_t offset = 0, cur_block;
+       struct sparse_map *sm = channel->private_data;
+
+       if (check_block_size(channel, sm))
+               return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
+
+       if (count < 0) { //partial read
+               count = -count;
+               cur_block = block_to_sparse_block(block, &offset, channel, sm);
+               if (sm->blocks[cur_block])
+                       memcpy(out, (sm->blocks[cur_block]) + offset, count);
+               else
+                       memset(out, 0, count);
+       } else {
+               for (i = 0; i < count; ++i) {
+                       cur_block = block_to_sparse_block(block + i, &offset,
+                                                   channel, sm);
+                       if (sm->blocks[cur_block])
+                               memcpy(out + (i * channel->block_size),
+                                      sm->blocks[cur_block] + offset,
+                                      channel->block_size);
+                       else if (sm->blocks)
+                               memset(out + (i * channel->block_size), 0,
+                                      channel->block_size);
+               }
+       }
+       return 0;
+}
+
+static errcode_t sparse_read_blk(io_channel channel, unsigned long block,
+                                int count, void *buf)
+{
+       return sparse_read_blk64(channel, block, count, buf);
+}
+
+static errcode_t sparse_write_blk64(io_channel channel, blk64_t block,
+                                   int count, const void *buf)
+{
+       int i;
+       blk64_t offset = 0, cur_block;
+       const char *in = buf;
+       struct sparse_map *sm = channel->private_data;
+
+       if (check_block_size(channel, sm))
+               return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
+
+       if (count < 0) { //partial write
+               count = -count;
+               cur_block = block_to_sparse_block(block, &offset, channel,
+                                                 sm);
+               if (!sm->blocks[cur_block]) {
+                       sm->blocks[cur_block] = calloc(1, sm->block_size);
+                       if (!sm->blocks[cur_block])
+                               return EXT2_ET_NO_MEMORY;
+               }
+               memcpy(sm->blocks[cur_block] + offset, in, count);
+       } else {
+               for (i = 0; i < count; ++i) {
+                       if (block + i >= sm->blocks_count)
+                               return 0;
+                       cur_block = block_to_sparse_block(block + i, &offset,
+                                                   channel, sm);
+                       if (!sm->blocks[cur_block]) {
+                               sm->blocks[cur_block] =
+                                       calloc(1, sm->block_size);
+                               if (!sm->blocks[cur_block])
+                                       return EXT2_ET_NO_MEMORY;
+                       }
+                       memcpy(sm->blocks[cur_block] + offset,
+                              in + (i * channel->block_size),
+                              channel->block_size);
+               }
+       }
+       return 0;
+}
+
+static errcode_t sparse_write_blk(io_channel channel, unsigned long block,
+                                 int count, const void *buf)
+{
+       return sparse_write_blk64(channel, block, count, buf);
+}
+
+static errcode_t sparse_discard(io_channel channel __attribute__((unused)),
+                               blk64_t blk, unsigned long long count)
+{
+       blk64_t cur_block, offset;
+       struct sparse_map *sm = channel->private_data;
+
+       if (check_block_size(channel, sm))
+               return EXT2_ET_UNEXPECTED_BLOCK_SIZE;
+
+       for (unsigned long long i = 0; i < count; ++i) {
+               if (blk + i >= sm->blocks_count)
+                       return 0;
+               cur_block = block_to_sparse_block(blk + i, &offset, channel,
+                                                 sm);
+               if (!sm->blocks[cur_block])
+                       continue;
+               free(sm->blocks[cur_block]);
+               sm->blocks[cur_block] = NULL;
+       }
+       return 0;
+}
+
+static errcode_t sparse_zeroout(io_channel channel, blk64_t blk,
+                               unsigned long long count)
+{
+       return sparse_discard(channel, blk, count);
+}
+
+static errcode_t sparse_flush(io_channel channel __attribute__((unused)))
+{
+       return 0;
+}
+
+static errcode_t sparse_set_option(io_channel channel __attribute__((unused)),
+                                   const char *option __attribute__((unused)),
+                                   const char *arg __attribute__((unused)))
+{
+       return 0;
+}
+
+static errcode_t sparse_cache_readahead(
+                       io_channel channel __attribute__((unused)),
+                       blk64_t blk __attribute__((unused)),
+                       unsigned long long count __attribute__((unused)))
+{
+       return 0;
+}
+
+static struct struct_io_manager struct_sparse_manager = {
+       .magic                  = EXT2_ET_MAGIC_IO_MANAGER,
+       .name                   = "Android sparse I/O Manager",
+       .open                   = sparse_open,
+       .close                  = sparse_close,
+       .set_blksize            = sparse_set_blksize,
+       .read_blk               = sparse_read_blk,
+       .write_blk              = sparse_write_blk,
+       .flush                  = sparse_flush,
+       .write_byte             = NULL,
+       .set_option             = sparse_set_option,
+       .get_stats              = NULL,
+       .read_blk64             = sparse_read_blk64,
+       .write_blk64            = sparse_write_blk64,
+       .discard                = sparse_discard,
+       .cache_readahead        = sparse_cache_readahead,
+       .zeroout                = sparse_zeroout,
+};
+
+static struct struct_io_manager struct_sparsefd_manager = {
+       .magic                  = EXT2_ET_MAGIC_IO_MANAGER,
+       .name                   = "Android sparse fd I/O Manager",
+       .open                   = sparsefd_open,
+       .close                  = sparse_close,
+       .set_blksize            = sparse_set_blksize,
+       .read_blk               = sparse_read_blk,
+       .write_blk              = sparse_write_blk,
+       .flush                  = sparse_flush,
+       .write_byte             = NULL,
+       .set_option             = sparse_set_option,
+       .get_stats              = NULL,
+       .read_blk64             = sparse_read_blk64,
+       .write_blk64            = sparse_write_blk64,
+       .discard                = sparse_discard,
+       .cache_readahead        = sparse_cache_readahead,
+       .zeroout                = sparse_zeroout,
+};
+
+#endif
+
+io_manager sparse_io_manager = &struct_sparse_manager;
+io_manager sparsefd_io_manager = &struct_sparsefd_manager;
index d63fc55..2d05ee7 100644 (file)
@@ -247,7 +247,7 @@ void ext2fs_swap_inode_full(ext2_filsys fs, struct ext2_inode_large *t,
                has_extents = 1;
        if (!hostorder && (t->i_flags & EXT4_INLINE_DATA_FL))
                has_inline_data = 1;
-       t->i_dir_acl = ext2fs_swab32(f->i_dir_acl);
+       t->i_size_high = ext2fs_swab32(f->i_size_high);
        /*
         * Extent data and inline data are swapped on access, not here
         */
index f7c50d1..ee828be 100644 (file)
@@ -146,8 +146,10 @@ static void test_abort(io_channel channel, unsigned long block)
 
 static char *safe_getenv(const char *arg)
 {
+#if !defined(_WIN32)
        if ((getuid() != geteuid()) || (getgid() != getegid()))
                return NULL;
+#endif
 #if HAVE_PRCTL
        if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
                return NULL;
index f4e6148..dc2a2e9 100644 (file)
@@ -718,6 +718,7 @@ static errcode_t unixfd_open(const char *str_fd, int flags,
        int fd_flags;
 
        fd = atoi(str_fd);
+#if defined(HAVE_FCNTL)
        fd_flags = fcntl(fd, F_GETFD);
        if (fd_flags == -1)
                return -EBADF;
@@ -731,6 +732,7 @@ static errcode_t unixfd_open(const char *str_fd, int flags,
        if (fd_flags & O_DIRECT)
                flags |= IO_FLAG_DIRECT_IO;
 #endif
+#endif  /* HAVE_FCNTL */
 
        return unix_open_channel(str_fd, fd, flags, channel, unixfd_io_manager);
 }
@@ -1030,8 +1032,10 @@ static errcode_t unix_flush(io_channel channel)
 #ifndef NO_IO_CACHE
        retval = flush_cached_blocks(channel, data, 0);
 #endif
+#ifdef HAVE_FSYNC
        if (!retval && fsync(data->dev) != 0)
                return errno;
+#endif
        return retval;
 }
 
diff --git a/lib/ss/Android.bp b/lib/ss/Android.bp
new file mode 100644 (file)
index 0000000..06925d7
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_ss",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "ss_err.c",
+        "std_rqs.c",
+        "invocation.c",
+        "help.c",
+        "execute_cmd.c",
+        "listen.c",
+        "parse.c",
+        "error.c",
+        "prompt.c",
+        "request_tbl.c",
+        "list_rqs.c",
+        "pager.c",
+        "requests.c",
+        "data.c",
+        "get_readline.c",
+    ],
+    shared_libs: ["libext2_com_err"],
+    cflags: [
+        "-W",
+        "-Wall",
+    ],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/ss/Android.mk b/lib/ss/Android.mk
deleted file mode 100644 (file)
index c19accc..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_ss_src_files := \
-       ss_err.c \
-       std_rqs.c \
-       invocation.c help.c \
-       execute_cmd.c \
-       listen.c \
-       parse.c \
-       error.c \
-       prompt.c \
-       request_tbl.c \
-       list_rqs.c \
-       pager.c \
-       requests.c \
-       data.c \
-       get_readline.c
-
-libext2_ss_c_includes := external/e2fsprogs/lib
-
-libext2_ss_cflags := -O2 -g -W -Wall
-
-libext2_ss_shared_libraries := \
-       libext2_com_err
-
-libext2_ss_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_ss_src_files)
-LOCAL_C_INCLUDES := $(libext2_ss_c_includes)
-LOCAL_CFLAGS := $(libext2_ss_cflags)
-LOCAL_SHARED_LIBRARIES := $(libext2_ss_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_ss_system_shared_libraries)
-LOCAL_MODULE := libext2_ss
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_ss_src_files)
-LOCAL_C_INCLUDES := $(libext2_ss_c_includes)
-LOCAL_CFLAGS := $(libext2_ss_cflags)
-LOCAL_STATIC_LIBRARIES := libc
-LOCAL_MODULE := libext2_ss
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_ss_src_files)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(libext2_ss_shared_libraries))
-LOCAL_C_INCLUDES := $(libext2_ss_c_includes)
-LOCAL_CFLAGS := $(libext2_ss_cflags)
-LOCAL_MODULE := libext2_ss-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index f4953f0..ee18dc8 100644 (file)
@@ -163,7 +163,7 @@ test_ss: test_ss.o test_cmd.o $(DEPLIBSS) $(DEPLIBCOM_ERR)
        $(Q) $(CC) -o $@ test_ss.o test_cmd.o $(ALL_CFLAGS) $(ALL_LDFLAGS) \
                $(LIBSS) $(LIBCOM_ERR) $(SYSLIBS)
 
-check:: all test_ss
+fullcheck check:: all test_ss
        $(E) "  RUN TEST test_ss"
        -@($(TESTENV) ./test_ss -f $(srcdir)/test_script > test_out 2>&1; exit 0)
        $(Q) if diff test_out $(srcdir)/test_script_expected > test.diff; then \
diff --git a/lib/support/Android.bp b/lib/support/Android.bp
new file mode 100644 (file)
index 0000000..24414a4
--- /dev/null
@@ -0,0 +1,54 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_quota",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "dict.c",
+        "mkquota.c",
+        "parse_qtype.c",
+        "plausible.c",
+        "profile.c",
+        "profile_helpers.c",
+        "prof_err.c",
+        "quotaio.c",
+        "quotaio_tree.c",
+        "quotaio_v2.c",
+    ],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+        "libext2_blkid",
+    ],
+
+    cflags: [
+        "-W",
+        "-Wall",
+        "-Wno-macro-redefined",
+    ],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
+
+cc_library_shared {
+    name: "libext2_profile",
+    host_supported: true,
+    unique_host_soname: true,
+
+    srcs: [
+        "prof_err.c",
+        "profile.c",
+    ],
+    cflags = [
+        "-W",
+        "-Wall",
+    ],
+    shared_libs: ["libext2_com_err"],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/support/Android.mk b/lib/support/Android.mk
deleted file mode 100644 (file)
index fefd058..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_quota_src_files := \
-       dict.c \
-       mkquota.c \
-       parse_qtype.c \
-       plausible.c \
-       profile.c \
-       profile_helpers.c \
-       prof_err.c \
-       quotaio.c \
-       quotaio_tree.c \
-       quotaio_v2.c
-
-libext2_quota_c_includes := external/e2fsprogs/lib
-
-libext2_quota_cflags := -O2 -g -W -Wall
-
-libext2_quota_shared_libraries := libext2fs libext2_com_err libext2_blkid
-
-libext2_quota_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_quota_src_files)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_quota_system_shared_libraries)
-LOCAL_C_INCLUDES := $(libext2_quota_c_includes)
-LOCAL_CFLAGS := $(libext2_quota_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := libc $(libext2_quota_shared_libraries)
-LOCAL_MODULE := libext2_quota
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-libext2_quota_static_libraries := libext2fs libext2_com_err
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_quota_src_files)
-LOCAL_C_INCLUDES := $(libext2_quota_c_includes)
-LOCAL_CFLAGS := $(libext2_quota_cflags)
-LOCAL_STATIC_LIBRARIES := libc $(libext2_quota_static_libraries)
-LOCAL_MODULE := libext2_quota
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_quota_src_files)
-LOCAL_C_INCLUDES := $(libext2_quota_c_includes)
-LOCAL_CFLAGS := $(libext2_quota_cflags)
-LOCAL_MODULE := libext2_quota-host
-LOCAL_MODULE_TAGS := optional
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(libext2_quota_shared_libraries))
-
-include $(BUILD_HOST_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-libext2_profile_src_files :=  \
-       prof_err.c \
-       profile.c
-
-libext2_profile_shared_libraries := \
-       libext2_com_err
-
-libext2_profile_system_shared_libraries := libc
-
-libext2_profile_c_includes := external/e2fsprogs/lib
-
-libext2_profile_cflags := -O2 -g -W -Wall
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_profile_src_files)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_profile_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(libext2_profile_shared_libraries)
-LOCAL_C_INCLUDES := $(libext2_profile_c_includes)
-LOCAL_CFLAGS := $(libext2_profile_cflags)
-LOCAL_MODULE := libext2_profile
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_profile_src_files)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(libext2_profile_shared_libraries))
-LOCAL_C_INCLUDES := $(libext2_profile_c_includes)
-LOCAL_CFLAGS := $(libext2_profile_cflags)
-LOCAL_MODULE := libext2_profile-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
index d5a6f26..40206b7 100644 (file)
@@ -79,7 +79,7 @@ clean::
                ../libsupport.a ../libsupport_p.a $(SMANPAGES) \
                prof_err.c prof_err.h test_profile test_cstring
 
-#check:: tst_uuid
+#fullcheck check:: tst_uuid
 #      LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_uuid
 
 mostlyclean:: clean
diff --git a/lib/uuid/Android.bp b/lib/uuid/Android.bp
new file mode 100644 (file)
index 0000000..d173788
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_library {
+    name: "libext2_uuid",
+    host_supported: true,
+    unique_host_soname: true,
+    srcs: [
+        "clear.c",
+        "compare.c",
+        "copy.c",
+        "gen_uuid.c",
+        "isnull.c",
+        "pack.c",
+        "parse.c",
+        "unpack.c",
+        "unparse.c",
+        "uuid_time.c",
+    ],
+    cflags: [
+        "-W",
+        "-Wall",
+        "-Wno-unused-function",
+        "-Wno-unused-parameter",
+    ],
+
+    header_libs: ["libext2-headers"],
+    export_include_dirs: ["."],
+    export_header_lib_headers: ["libext2-headers"],
+}
diff --git a/lib/uuid/Android.mk b/lib/uuid/Android.mk
deleted file mode 100644 (file)
index 91d6836..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-libext2_uuid_src_files := \
-       clear.c \
-       compare.c \
-       copy.c \
-       gen_uuid.c \
-       isnull.c \
-       pack.c \
-       parse.c \
-       unpack.c \
-       unparse.c \
-       uuid_time.c
-
-
-libext2_uuid_c_includes := external/e2fsprogs/lib
-
-libext2_uuid_cflags := -O2 -g -W -Wall \
-       -Wno-unused-function \
-       -Wno-unused-parameter
-
-libext2_uuid_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_uuid_src_files)
-LOCAL_C_INCLUDES := $(libext2_uuid_c_includes)
-LOCAL_CFLAGS := $(libext2_uuid_cflags)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH) $(LOCAL_PATH)/..
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(libext2_uuid_system_shared_libraries)
-LOCAL_MODULE := libext2_uuid
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_uuid_src_files)
-LOCAL_C_INCLUDES := $(libext2_uuid_c_includes)
-LOCAL_CFLAGS := $(libext2_uuid_cflags)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_MODULE := libext2_uuid-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_SHARED_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_uuid_src_files)
-LOCAL_C_INCLUDES := $(libext2_uuid_c_includes)
-LOCAL_CFLAGS := $(libext2_uuid_cflags)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_STATIC_LIBRARIES := libc
-LOCAL_MODULE := libext2_uuid_static
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(libext2_uuid_src_files)
-LOCAL_C_INCLUDES := $(libext2_uuid_c_includes)
-LOCAL_CFLAGS := $(libext2_uuid_cflags)
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)
-LOCAL_MODULE := libext2_uuid-host
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_STATIC_LIBRARY)
index a298144..4b44418 100644 (file)
@@ -171,7 +171,7 @@ clean::
                ../libuuid.a ../libuuid_p.a tst_uuid uuid_time \
                uuid.pc uuid_types.h $(SMANPAGES)
 
-check:: tst_uuid
+fullcheck check:: tst_uuid
        LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_uuid
 
 mostlyclean:: clean
diff --git a/misc/Android.bp b/misc/Android.bp
new file mode 100644 (file)
index 0000000..ae7d9b6
--- /dev/null
@@ -0,0 +1,221 @@
+// Copyright 2017 The Android Open Source Project
+
+// Library used to export files from this directory to other programs in this
+// project.
+cc_library {
+    name: "libext2_misc",
+    host_supported: true,
+
+    srcs: [
+        "create_inode.c",
+    ],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2_quota",
+        "libext2fs",
+    ],
+    system_shared_libs: ["libc"],
+    export_include_dirs: ["."],
+}
+
+//########################################################################
+// Build mke2fs
+
+cc_binary {
+    name: "mke2fs",
+    host_supported: true,
+
+    srcs: [
+        "mke2fs.c",
+        "util.c",
+        "mk_hugefiles.c",
+        "default_profile.c",
+    ],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_blkid",
+        "libext2_misc",
+        "libext2_uuid",
+        "libext2_quota",
+        "libext2_com_err",
+        "libext2_e2p",
+    ],
+    system_shared_libs: ["libc"],
+    include_dirs: ["external/e2fsprogs/e2fsck"],
+}
+
+//##########################################################################
+// Build tune2fs
+
+cc_defaults {
+    name: "tune2fs-defaults",
+    srcs: [
+        "tune2fs.c",
+        "util.c",
+    ],
+    cflags: [
+        "-W",
+        "-Wall",
+        "-DNO_RECOVERY",
+        "-Wno-macro-redefined",
+    ],
+    include_dirs: ["external/e2fsprogs/e2fsck"],
+}
+
+tune2fs_libs = [
+    "libext2_com_err",
+    "libext2_blkid",
+    "libext2_quota",
+    "libext2_uuid",
+    "libext2_e2p",
+    "libext2fs",
+]
+
+cc_binary {
+    name: "tune2fs",
+    host_supported: true,
+    defaults: ["tune2fs-defaults"],
+
+    shared_libs: tune2fs_libs,
+    system_shared_libs: ["libc"],
+}
+
+cc_binary {
+    name: "tune2fs_static",
+    static_executable: true,
+    defaults: ["tune2fs-defaults"],
+
+    static_libs: tune2fs_libs + ["libc"],
+}
+
+cc_library_static {
+    name: "libtune2fs",
+    defaults: ["tune2fs-defaults"],
+
+    cflags: ["-DBUILD_AS_LIB"],
+    static_libs: tune2fs_libs,
+}
+
+//########################################################################
+// Build badblocks
+
+cc_binary {
+    name: "badblocks",
+    host_supported: true,
+
+    srcs: ["badblocks.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+        "libext2_uuid",
+        "libext2_blkid",
+        "libext2_e2p",
+    ],
+    system_shared_libs: ["libc"],
+}
+
+//########################################################################
+// Build chattr
+
+cc_binary {
+    name: "chattr",
+    host_supported: true,
+
+    srcs: ["chattr.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2_com_err",
+        "libext2_e2p",
+    ],
+    system_shared_libs: ["libc"],
+}
+
+//########################################################################
+// Build lsattr
+
+cc_defaults {
+    name: "lsattr-defaults",
+    srcs: ["lsattr.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+}
+
+lsattr_libs = [
+    "libext2_com_err",
+    "libext2_e2p",
+]
+
+cc_binary {
+    name: "lsattr",
+    host_supported: true,
+    defaults: ["lsattr-defaults"],
+
+    shared_libs: lsattr_libs,
+    system_shared_libs: ["libc"],
+}
+
+cc_binary {
+    name: "lsattr_static",
+    static_executable: true,
+    defaults: ["lsattr-defaults"],
+
+    static_libs: lsattr_libs + ["libc"],
+}
+
+//########################################################################
+// Build blkid
+
+cc_binary {
+    name: "blkid",
+
+    srcs: ["blkid.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_blkid",
+        "libext2_com_err",
+        "libext2_e2p",
+    ],
+    system_shared_libs: ["libc"],
+}
+
+//########################################################################
+// Build e4crypt
+
+cc_binary {
+    name: "e4crypt",
+    host_supported: true,
+
+    srcs: ["e4crypt.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_uuid",
+    ],
+    system_shared_libs: ["libc"],
+
+    target: {
+        darwin: {
+            enabled: false,
+        },
+    },
+}
+
+//##########################################################################
+// Build e2image
+
+cc_binary {
+    name: "e2image",
+    host_supported: true,
+
+    srcs: ["e2image.c"],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_blkid",
+        "libext2_com_err",
+        "libext2_quota",
+    ],
+    system_shared_libs: ["libc"],
+}
diff --git a/misc/Android.mk b/misc/Android.mk
deleted file mode 100644 (file)
index d960737..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-#########################################################################
-# Build mke2fs
-mke2fs_src_files := \
-       mke2fs.c \
-       util.c \
-       mk_hugefiles.c \
-       default_profile.c \
-       create_inode.c
-
-mke2fs_c_includes := \
-       external/e2fsprogs/e2fsck
-
-mke2fs_cflags := -O2 -g -W -Wall
-
-mke2fs_shared_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_uuid \
-       libext2_quota \
-       libext2_com_err \
-       libext2_e2p
-
-mke2fs_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(mke2fs_src_files)
-LOCAL_C_INCLUDES := $(mke2fs_c_includes)
-LOCAL_CFLAGS := $(mke2fs_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(mke2fs_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(mke2fs_shared_libraries)
-LOCAL_MODULE := mke2fs
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(mke2fs_src_files)
-LOCAL_C_INCLUDES := $(mke2fs_c_includes)
-LOCAL_CFLAGS := $(mke2fs_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(mke2fs_shared_libraries))
-LOCAL_MODULE := mke2fs_host
-LOCAL_MODULE_STEM := mke2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-###########################################################################
-# Build tune2fs
-#
-tune2fs_src_files := \
-       tune2fs.c \
-       util.c
-
-tune2fs_c_includes := \
-       external/e2fsprogs/e2fsck
-
-tune2fs_cflags := -O2 -g -W -Wall -DNO_RECOVERY
-
-tune2fs_shared_libraries := \
-       libext2fs \
-       libext2_com_err \
-       libext2_blkid \
-       libext2_quota \
-       libext2_uuid \
-       libext2_e2p
-
-tune2fs_system_shared_libraries := libc
-
-
-tune2fs_static_libraries := \
-       libext2_com_err \
-       libext2_blkid \
-       libext2_quota \
-       libext2_uuid_static \
-       libext2_e2p \
-       libext2fs
-
-tune2fs_system_static_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(tune2fs_src_files)
-LOCAL_C_INCLUDES := $(tune2fs_c_includes)
-LOCAL_CFLAGS := $(tune2fs_cflags)
-LOCAL_SHARED_LIBRARIES := $(tune2fs_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(tune2fs_system_shared_libraries)
-LOCAL_MODULE := tune2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(tune2fs_src_files)
-LOCAL_C_INCLUDES := $(tune2fs_c_includes)
-LOCAL_CFLAGS := $(tune2fs_cflags)
-LOCAL_STATIC_LIBRARIES := $(tune2fs_static_libraries) $(tune2fs_system_static_libraries)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := tune2fs_static
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(tune2fs_src_files)
-LOCAL_C_INCLUDES := $(tune2fs_c_includes)
-LOCAL_CFLAGS := $(tune2fs_cflags) -DBUILD_AS_LIB
-LOCAL_STATIC_LIBRARIES := $(tune2fs_static_libraries) $(tune2fs_system_static_libraries)
-LOCAL_MODULE := libtune2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_LIBRARY)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(tune2fs_src_files)
-LOCAL_C_INCLUDES := $(tune2fs_c_includes)
-LOCAL_CFLAGS := $(tune2fs_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(tune2fs_shared_libraries))
-LOCAL_MODULE := tune2fs_host
-LOCAL_MODULE_STEM := tune2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#########################################################################
-# Build badblocks
-#
-include $(CLEAR_VARS)
-
-badblocks_src_files := \
-       badblocks.c
-
-badblocks_c_includes :=
-
-badblocks_cflags := -O2 -g -W -Wall
-
-badblocks_shared_libraries := \
-       libext2fs \
-       libext2_com_err \
-       libext2_uuid \
-       libext2_blkid \
-       libext2_e2p
-
-badblocks_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(badblocks_src_files)
-LOCAL_C_INCLUDES := $(badblocks_c_includes)
-LOCAL_CFLAGS := $(badblocks_cflags)
-LOCAL_SHARED_LIBRARIES := $(badblocks_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(badblocks_system_shared_libraries)
-LOCAL_MODULE := badblocks
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(badblocks_src_files)
-LOCAL_C_INCLUDES := $(badblocks_c_includes)
-LOCAL_CFLAGS := $(badblocks_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(badblocks_shared_libraries))
-LOCAL_MODULE := badblocks_host
-LOCAL_MODULE_STEM := badblocks
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#########################################################################
-# Build chattr
-#
-include $(CLEAR_VARS)
-
-chattr_src_files := \
-       chattr.c
-
-chattr_c_includes := \
-       external/e2fsprogs/lib
-
-chattr_cflags := -O2 -g -W -Wall
-
-chattr_shared_libraries := \
-       libext2_com_err \
-       libext2_e2p
-
-chattr_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(chattr_src_files)
-LOCAL_C_INCLUDES := $(chattr_c_includes)
-LOCAL_CFLAGS := $(chattr_cflags)
-LOCAL_SHARED_LIBRARIES := $(chattr_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(chattr_system_shared_libraries)
-LOCAL_MODULE := chattr
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(chattr_src_files)
-LOCAL_C_INCLUDES := $(chattr_c_includes)
-LOCAL_CFLAGS := $(chattr_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(chattr_shared_libraries))
-LOCAL_MODULE := chattr_host
-LOCAL_MODULE_STEM := chattr
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#########################################################################
-# Build lsattr
-#
-include $(CLEAR_VARS)
-
-lsattr_src_files := \
-       lsattr.c
-
-lsattr_c_includes := \
-       external/e2fsprogs/lib
-
-lsattr_cflags := -O2 -g -W -Wall
-
-lsattr_shared_libraries := \
-       libext2_com_err \
-       libext2_e2p
-
-lsattr_system_shared_libraries := libc
-
-lsattr_static_libraries := \
-       libext2_com_err \
-       libext2_e2p
-
-lsattr_system_static_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(lsattr_src_files)
-LOCAL_C_INCLUDES := $(lsattr_c_includes)
-LOCAL_CFLAGS := $(lsattr_cflags)
-LOCAL_SHARED_LIBRARIES := $(lsattr_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(lsattr_system_shared_libraries)
-LOCAL_MODULE := lsattr
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(lsattr_src_files)
-LOCAL_C_INCLUDES := $(lsattr_c_includes)
-LOCAL_CFLAGS := $(lsattr_cflags)
-LOCAL_STATIC_LIBRARIES := $(lsattr_static_libraries) $(lsattr_system_static_libraries)
-LOCAL_FORCE_STATIC_EXECUTABLE := true
-LOCAL_MODULE := lsattr_static
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(lsattr_src_files)
-LOCAL_C_INCLUDES := $(lsattr_c_includes)
-LOCAL_CFLAGS := $(lsattr_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(lsattr_shared_libraries))
-LOCAL_MODULE := lsattr_host
-LOCAL_MODULE_STEM := lsattr
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
-#########################################################################
-# Build blkid
-#
-include $(CLEAR_VARS)
-
-blkid_src_files := \
-    blkid.c
-
-blkid_c_includes :=
-
-blkid_cflags := -O2 -g -W -Wall
-
-blkid_shared_libraries := \
-    libext2fs \
-    libext2_blkid \
-    libext2_com_err \
-    libext2_e2p
-
-blkid_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(blkid_src_files)
-LOCAL_C_INCLUDES := $(blkid_c_includes)
-LOCAL_CFLAGS := $(blkid_cflags)
-LOCAL_SHARED_LIBRARIES := $(blkid_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(blkid_system_shared_libraries)
-LOCAL_MODULE := blkid
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-#########################################################################
-# Build e4crypt
-e4crypt_src_files := e4crypt.c
-
-e4crypt_c_includes := \
-       external/e2fsprogs/lib
-
-e4crypt_cflags := -O2 -g -W -Wall
-
-e4crypt_shared_libraries := libext2fs libext2_uuid
-
-e4crypt_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e4crypt_src_files)
-LOCAL_C_INCLUDES := $(e4crypt_c_includes)
-LOCAL_CFLAGS := $(e4crypt_cflags)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(e4crypt_system_shared_libraries)
-LOCAL_SHARED_LIBRARIES := $(e4crypt_shared_libraries)
-LOCAL_MODULE := e4crypt
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e4crypt_src_files)
-LOCAL_C_INCLUDES := $(e4crypt_c_includes)
-LOCAL_CFLAGS := $(e4crypt_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(e4crypt_shared_libraries))
-LOCAL_MODULE := e4crypt_host
-LOCAL_MODULE_STEM := e4crypt
-LOCAL_MODULE_TAGS := optional
-LOCAL_MODULE_HOST_OS := linux
-
-include $(BUILD_HOST_EXECUTABLE)
-
-###########################################################################
-# Build e2image
-#
-e2image_src_files := \
-       e2image.c
-
-e2image_c_includes := \
-       external/e2fsprogs/lib
-
-e2image_cflags := -O2 -g -W -Wall
-
-e2image_shared_libraries := \
-       libext2fs \
-       libext2_blkid \
-       libext2_com_err \
-       libext2_quota
-
-e2image_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e2image_src_files)
-LOCAL_C_INCLUDES := $(e2image_c_includes)
-mke2fs_c_includesLOCAL_CFLAGS := $(e2image_cflags)
-LOCAL_SHARED_LIBRARIES := $(e2image_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(e2image_system_shared_libraries)
-LOCAL_MODULE := e2image
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(e2image_src_files)
-LOCAL_C_INCLUDES := $(e2image_c_includes)
-LOCAL_CFLAGS := $(e2image_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(e2image_shared_libraries))
-LOCAL_MODULE := e2image_host
-LOCAL_MODULE_STEM := e2image
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
-
index 467c15d..d08859d 100644 (file)
@@ -252,7 +252,7 @@ base_device: base_device.c
        $(Q) $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(srcdir)/base_device.c \
                -DDEBUG -o base_device $(SYSLIBS)
 
-check:: base_device
+fullcheck check:: base_device
        ./base_device < $(srcdir)/base_device.tst > base_device.out
        cmp $(srcdir)/base_device.tst base_device.out
 
index 8ce3faf..8f7445d 100644 (file)
@@ -683,10 +683,31 @@ out:
        return retval;
 }
 
+struct file_info {
+       char *path;
+       size_t path_len;
+       size_t path_max_len;
+};
+
+static errcode_t path_append(struct file_info *target, const char *file)
+{
+       if (strlen(file) + target->path_len + 1 > target->path_max_len) {
+               target->path_max_len *= 2;
+               target->path = realloc(target->path, target->path_max_len);
+               if (!target->path)
+                       return EXT2_ET_NO_MEMORY;
+       }
+       target->path_len += sprintf(target->path + target->path_len, "/%s",
+                                   file);
+       return 0;
+}
+
 /* Copy files from source_dir to fs */
 static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
                               const char *source_dir, ext2_ino_t root,
-                              struct hdlinks_s *hdlinks)
+                              struct hdlinks_s *hdlinks,
+                              struct file_info *target,
+                              struct fs_ops_callbacks *fs_callbacks)
 {
        const char      *name;
        DIR             *dh;
@@ -698,6 +719,7 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
        errcode_t       retval = 0;
        int             read_cnt;
        int             hdlink;
+       size_t          cur_dir_path_len;
 
        if (chdir(source_dir) < 0) {
                retval = errno;
@@ -745,6 +767,19 @@ static errcode_t __populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
                                save_inode = 1;
                }
 
+               cur_dir_path_len = target->path_len;
+               retval = path_append(target, name);
+               if (retval)
+                       return retval;
+
+               if (fs_callbacks && fs_callbacks->create_new_inode) {
+                       retval = fs_callbacks->create_new_inode(fs,
+                               target->path, name, parent_ino, root,
+                               st.st_mode & S_IFMT);
+                       if (retval)
+                               goto out;
+               }
+
                switch(st.st_mode & S_IFMT) {
                case S_IFCHR:
                case S_IFBLK:
@@ -822,7 +857,8 @@ find_lnf:
                                        goto out;
                        }
                        /* Populate the dir recursively*/
-                       retval = __populate_fs(fs, ino, name, root, hdlinks);
+                       retval = __populate_fs(fs, ino, name, root, hdlinks,
+                                              target, fs_callbacks);
                        if (retval)
                                goto out;
                        if (chdir("..")) {
@@ -858,6 +894,14 @@ find_lnf:
                        goto out;
                }
 
+               if (fs_callbacks && fs_callbacks->end_create_new_inode) {
+                       retval = fs_callbacks->end_create_new_inode(fs,
+                               target->path, name, parent_ino, root,
+                               st.st_mode & S_IFMT);
+                       if (retval)
+                               goto out;
+               }
+
                /* Save the hardlink ino */
                if (save_inode) {
                        /*
@@ -883,6 +927,8 @@ find_lnf:
                        hdlinks->hdl[hdlinks->count].dst_ino = ino;
                        hdlinks->count++;
                }
+               target->path_len = cur_dir_path_len;
+               target->path[target->path_len] = 0;
        }
 
 out:
@@ -890,9 +936,11 @@ out:
        return retval;
 }
 
-errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
-                     const char *source_dir, ext2_ino_t root)
+errcode_t populate_fs2(ext2_filsys fs, ext2_ino_t parent_ino,
+                      const char *source_dir, ext2_ino_t root,
+                      struct fs_ops_callbacks *fs_callbacks)
 {
+       struct file_info file_info;
        struct hdlinks_s hdlinks;
        errcode_t retval;
 
@@ -910,8 +958,20 @@ errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
                return retval;
        }
 
-       retval = __populate_fs(fs, parent_ino, source_dir, root, &hdlinks);
+       file_info.path_len = 0;
+       file_info.path_max_len = 255;
+       file_info.path = calloc(file_info.path_max_len, 1);
 
+       retval = __populate_fs(fs, parent_ino, source_dir, root, &hdlinks,
+                              &file_info, fs_callbacks);
+
+       free(file_info.path);
        free(hdlinks.hdl);
        return retval;
 }
+
+errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
+                     const char *source_dir, ext2_ino_t root)
+{
+       return populate_fs2(fs, parent_ino, source_dir, root, NULL);
+}
index cf49df2..17309c6 100644 (file)
@@ -24,9 +24,21 @@ struct hdlinks_s
 
 #define HDLINK_CNT     (4)
 
+struct fs_ops_callbacks {
+       errcode_t (* create_new_inode)(ext2_filsys fs, const char *target_path,
+               const char *name, ext2_ino_t parent_ino, ext2_ino_t root,
+               mode_t mode);
+       errcode_t (* end_create_new_inode)(ext2_filsys fs,
+               const char *target_path, const char *name,
+               ext2_ino_t parent_ino, ext2_ino_t root, mode_t mode);
+};
+
 /* For populating the filesystem */
 extern errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
                             const char *source_dir, ext2_ino_t root);
+extern errcode_t populate_fs2(ext2_filsys fs, ext2_ino_t parent_ino,
+                             const char *source_dir, ext2_ino_t root,
+                             struct fs_ops_callbacks *fs_callbacks);
 extern errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd,
                                   const char *name, struct stat *st);
 extern errcode_t do_symlink_internal(ext2_filsys fs, ext2_ino_t cwd,
index b8d078a..6cbba33 100644 (file)
@@ -113,6 +113,9 @@ char **fs_types;
 const char *src_root_dir;  /* Copy files from the specified directory */
 static char *undo_file;
 
+static int android_sparse_file; /* -E android_sparse */
+static char *android_sparse_params;
+
 static profile_t       profile;
 
 static int sys_page_size = 4096;
@@ -553,7 +556,7 @@ static void zap_sector(ext2_filsys fs, int sect, int nsect)
        int retval;
        unsigned int *magic;
 
-       buf = malloc(512*nsect);
+       buf = calloc(512, nsect);
        if (!buf) {
                printf(_("Out of memory erasing sectors %d-%d\n"),
                       sect, sect + nsect - 1);
@@ -1026,6 +1029,8 @@ static void parse_extended_opts(struct ext2_super_block *param,
                                badopt = token;
                                continue;
                        }
+               } else if (!strcmp(token, "android_sparse")) {
+                       android_sparse_file = 1;
                } else {
                        r_usage++;
                        badopt = token;
@@ -1081,7 +1086,8 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_64BIT|
                EXT4_FEATURE_INCOMPAT_INLINE_DATA|
                EXT4_FEATURE_INCOMPAT_ENCRYPT |
-               EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+               EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+               EXT4_FEATURE_INCOMPAT_LARGEDIR,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE|
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
@@ -2827,7 +2833,21 @@ int main (int argc, char *argv[])
         */
        if (!quiet)
                flags |= EXT2_FLAG_PRINT_PROGRESS;
-       retval = ext2fs_initialize(device_name, flags, &fs_param, io_ptr, &fs);
+       if (android_sparse_file) {
+               android_sparse_params = malloc(PATH_MAX + 32);
+               if (!android_sparse_params) {
+                       com_err(program_name, ENOMEM, "%s",
+                               _("in malloc for android_sparse_params"));
+                       exit(1);
+               }
+               snprintf(android_sparse_params, PATH_MAX + 32, "%s:%u:%u",
+                        device_name, fs_param.s_blocks_count,
+                        1024 << fs_param.s_log_block_size);
+               retval = ext2fs_initialize(android_sparse_params, flags,
+                                          &fs_param, sparse_io_manager, &fs);
+       } else
+               retval = ext2fs_initialize(device_name, flags, &fs_param,
+                                          io_ptr, &fs);
        if (retval) {
                com_err(device_name, retval, "%s",
                        _("while setting up superblock"));
index 8543567..dc58729 100644 (file)
@@ -156,7 +156,8 @@ static __u32 ok_features[3] = {
                EXT4_FEATURE_INCOMPAT_MMP |
                EXT4_FEATURE_INCOMPAT_64BIT |
                EXT4_FEATURE_INCOMPAT_ENCRYPT |
-               EXT4_FEATURE_INCOMPAT_CSUM_SEED,
+               EXT4_FEATURE_INCOMPAT_CSUM_SEED |
+               EXT4_FEATURE_INCOMPAT_LARGEDIR,
        /* R/O compat */
        EXT2_FEATURE_RO_COMPAT_LARGE_FILE |
                EXT4_FEATURE_RO_COMPAT_HUGE_FILE|
index 2ae2f2a..eff37d3 100644 (file)
@@ -270,7 +270,7 @@ uninstall-data-yes:
          done; \
        done
 
-check: all
+fullcheck check: all
 
 info dvi ps pdf html tags TAGS ctags CTAGS ID:
 
index bc1a744..47e4ebd 100644 (file)
@@ -45,7 +45,7 @@ my @translator_help = (
  "#.   %IM     <inode> -> i_mtime\n",
  "#.   %IF     <inode> -> i_faddr\n",
  "#.   %If     <inode> -> i_file_acl\n",
- "#.   %Id     <inode> -> i_dir_acl\n",
+ "#.   %Id     <inode> -> i_size_high\n",
  "#.   %Iu     <inode> -> i_uid\n",
  "#.   %Ig     <inode> -> i_gid\n",
  "#.   %It     <str>                   file type\n",
diff --git a/resize/Android.bp b/resize/Android.bp
new file mode 100644 (file)
index 0000000..6d3d321
--- /dev/null
@@ -0,0 +1,24 @@
+// Copyright 2017 The Android Open Source Project
+
+cc_binary {
+    name: "resize2fs",
+    host_supported: true,
+
+    srcs: [
+        "extent.c",
+        "resize2fs.c",
+        "main.c",
+        "online.c",
+        "sim_progress.c",
+        "resource_track.c",
+    ],
+    cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
+    shared_libs: [
+        "libext2fs",
+        "libext2_com_err",
+        "libext2_e2p",
+        "libext2_uuid",
+        "libext2_blkid",
+    ],
+    system_shared_libs: ["libc"],
+}
diff --git a/resize/Android.mk b/resize/Android.mk
deleted file mode 100644 (file)
index 12d6ab5..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-resize2fs_src_files := \
-       extent.c \
-       resize2fs.c \
-       main.c \
-       online.c \
-       sim_progress.c \
-       resource_track.c
-
-resize2fs_c_includes := external/e2fsprogs/lib
-
-resize2fs_cflags := -O2 -g -W -Wall
-
-resize2fs_shared_libraries := \
-       libext2fs \
-       libext2_com_err \
-       libext2_e2p \
-       libext2_uuid \
-       libext2_blkid
-
-resize2fs_system_shared_libraries := libc
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(resize2fs_src_files)
-LOCAL_C_INCLUDES := $(resize2fs_c_includes)
-LOCAL_CFLAGS := $(resize2fs_cflags)
-LOCAL_SHARED_LIBRARIES := $(resize2fs_shared_libraries)
-LOCAL_SYSTEM_SHARED_LIBRARIES := $(resize2fs_system_shared_libraries)
-LOCAL_MODULE := resize2fs
-LOCAL_MODULE_TAGS := optional
-include $(BUILD_EXECUTABLE)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(resize2fs_src_files)
-LOCAL_C_INCLUDES := $(resize2fs_c_includes)
-LOCAL_CFLAGS := $(resize2fs_cflags)
-LOCAL_SHARED_LIBRARIES := $(addsuffix -host, $(resize2fs_shared_libraries))
-LOCAL_MODULE := resize2fs_host
-LOCAL_MODULE_STEM := resize2fs
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_HOST_EXECUTABLE)
index 6014bdd..cb9f553 100644 (file)
@@ -94,7 +94,7 @@ uninstall:
 test_extent.out: test_extent $(srcdir)/test_extent.in
        $(TESTENV) ./test_extent < $(srcdir)/test_extent.in > test_extent.out
 
-check:: test_extent.out
+fullcheck check:: test_extent.out
        $(Q) if cmp -s test_extent.out $(srcdir)/test_extent.in ; then \
                echo "Test succeeded." ; \
        else \
index c130f4a..57117ac 100644 (file)
@@ -41,8 +41,10 @@ always_run:
 @ifGNUmake@TESTS=$(wildcard $(srcdir)/[a-z]_*)
 @ifNotGNUmake@TESTS != echo $(srcdir)/[a-z]_*
 
+SKIP_SLOW_TESTS=--skip-slow-tests
+
 $(TESTS):: test_one always_run
-       @./test_one $@
+       @./test_one $(SKIP_SLOW_TESTS) $@
 
 foo:
        echo $(TESTS)
@@ -57,6 +59,9 @@ test_post: test_pre $(TESTS)
 
 check:: test_pre test_post test_script
 
+fullcheck::
+       $(MAKE) SKIP_SLOW_TESTS= check
+
 check-failed: $(basename $(wildcard *.failed))
        @$(srcdir)/test_post
 
index 8ce79ff..f588511 100644 (file)
@@ -18,7 +18,7 @@ debugfs: stat /a
 Inode: 12   Type: regular    Mode:  0666   Flags: 0x0
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 40960
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 82
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
@@ -30,7 +30,7 @@ debugfs: stat /b
 Inode: 13   Type: regular    Mode:  0666   Flags: 0x0
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 10240000
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 20082
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
index b685135..db9d522 100644 (file)
@@ -2,7 +2,7 @@
 Inode: 13   Type: regular    Mode:  0644   Flags: 0x10000000
 Generation: 3289262644    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 80
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec6b4:c72e3c00 -- Tue Jul 22 20:16:52 2014
@@ -18,7 +18,7 @@ Size of inline data: 80
 Inode: 18   Type: regular    Mode:  0644   Flags: 0x10000000
 Generation: 3842229473    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 20
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec6b4:cafecc00 -- Tue Jul 22 20:16:52 2014
@@ -35,7 +35,7 @@ Size of inline data: 60
 Inode: 16   Type: directory    Mode:  0755   Flags: 0x10000000
 Generation: 3842229469    Version: 0x00000000:00000004
 User:     0   Group:     0   Size: 132
-File ACL: 7    Directory ACL: 0
+File ACL: 7
 Links: 2   Blockcount: 8
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec6e3:27eac000 -- Tue Jul 22 20:17:39 2014
@@ -51,7 +51,7 @@ Size of inline data: 132
 Inode: 20   Type: directory    Mode:  0755   Flags: 0x10000000
 Generation: 3710818931    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 60
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 2   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec6b4:ca0aa800 -- Tue Jul 22 20:16:52 2014
@@ -68,7 +68,7 @@ Size of inline data: 60
 Inode: 12   Type: symlink    Mode:  0777   Flags: 0x10000000
 Generation: 3289262643    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 80
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec47f:724db800 -- Tue Jul 22 20:07:27 2014
@@ -83,7 +83,7 @@ Fast link dest: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
 Inode: 19   Type: symlink    Mode:  0777   Flags: 0x0
 Generation: 3842229474    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 20
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x53cec44c:a1fcc000 -- Tue Jul 22 20:06:36 2014
index f729b0f..c825932 100644 (file)
@@ -5,7 +5,7 @@ debugfs -R ''stat foo'' -w test.img
 Inode: 12   Type: symlink    Mode:  0777   Flags: 0x0
 Generation: 0    Version: 0x00000000
 User:     0   Group:     0   Size: 3
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x50f560e0 -- Tue Jan 15 14:00:00 2013
@@ -17,7 +17,7 @@ debugfs -R ''stat foo2'' -w test.img
 Inode: 13   Type: symlink    Mode:  0777   Flags: 0x0
 Generation: 0    Version: 0x00000000
 User:     0   Group:     0   Size: 80
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 2
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x50f560e0 -- Tue Jan 15 14:00:00 2013
@@ -42,7 +42,7 @@ debugfs -R ''stat pipe'' -w test.img
 Inode: 14   Type: FIFO    Mode:  0000   Flags: 0x0
 Generation: 0    Version: 0x00000000
 User:     0   Group:     0   Size: 0
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x50f560e0 -- Tue Jan 15 14:00:00 2013
@@ -55,7 +55,7 @@ debugfs -R ''stat sda'' -w test.img
 Inode: 15   Type: block special    Mode:  0000   Flags: 0x0
 Generation: 0    Version: 0x00000000
 User:     0   Group:     0   Size: 0
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x50f560e0 -- Tue Jan 15 14:00:00 2013
@@ -67,7 +67,7 @@ debugfs -R ''stat null'' -w test.img
 Inode: 16   Type: character special    Mode:  0000   Flags: 0x0
 Generation: 0    Version: 0x00000000
 User:     0   Group:     0   Size: 0
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x50f560e0 -- Tue Jan 15 14:00:00 2013
index 65a1641..b44e65d 100644 (file)
@@ -13,8 +13,6 @@ Inode 17 logical block 0 (physical block 1186) violates cluster allocation rules
 Will fix in pass 1B.
 Inode 17 logical block 2 (physical block 1184) violates cluster allocation rules.
 Will fix in pass 1B.
-Inode 17, i_blocks is 32, should be 64.  Fix? yes
-
 Inode 18 logical block 3 (physical block 1201) violates cluster allocation rules.
 Will fix in pass 1B.
 Inode 18, i_blocks is 32, should be 64.  Fix? yes
@@ -86,8 +84,6 @@ Inode 12, i_blocks is 64, should be 32.  Fix? yes
 
 Inode 16, i_blocks is 64, should be 32.  Fix? yes
 
-Inode 17, i_blocks is 64, should be 32.  Fix? yes
-
 Inode 18, i_blocks is 64, should be 32.  Fix? yes
 
 Pass 2: Checking directory structure
@@ -116,7 +112,7 @@ debugfs: stat /a
 Inode: 12   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152157    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -128,7 +124,7 @@ debugfs: stat /b
 Inode: 13   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152158    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -140,7 +136,7 @@ debugfs: stat /c
 Inode: 14   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152159    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -152,7 +148,7 @@ debugfs: stat /d
 Inode: 15   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152160    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -163,7 +159,7 @@ debugfs: stat /e
 Inode: 16   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152161    Version: 0x00000001
 User:     0   Group:     0   Size: 6144
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -175,7 +171,7 @@ debugfs: stat /f
 Inode: 17   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152162    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
@@ -187,7 +183,7 @@ debugfs: stat /g
 Inode: 18   Type: regular    Mode:  0644   Flags: 0x80000
 Generation: 1117152163    Version: 0x00000001
 User:     0   Group:     0   Size: 3072
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 32
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x539ff5b2 -- Tue Jun 17 08:00:50 2014
index c387962..716dbcb 100644 (file)
@@ -2,7 +2,7 @@ debugfs: stat /a
 Inode: 12   Type: regular    Mode:  0644   Flags: 0x0
 Generation: 1573716129    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 524288
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 1030
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x5457f87a:62ae2980 -- Mon Nov  3 21:49:46 2014
index c86c571..eafd64a 100644 (file)
@@ -2,7 +2,7 @@ debugfs: stat /a
 Inode: 12   Type: regular    Mode:  0644   Flags: 0x0
 Generation: 1573716129    Version: 0x00000000:00000001
 User:     0   Group:     0   Size: 524288
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 1030
 Fragment:  Address: 0    Number: 0    Size: 0
  ctime: 0x5457f87a:62ae2980 -- Mon Nov  3 21:49:46 2014
index 74a8034..095fb2b 100644 (file)
@@ -2,7 +2,7 @@ debugfs: stat /realmode.bin
 Inode: 12   Type: regular    Mode:  0775   Flags: 0x0
 Generation: 2022334337    Version: 0x00000001
 User:  1000   Group:  1000   Size: 21080
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 16
 Fragment:  Address: 0    Number: 0    Size: 0
 ctime: 0x5924849d -- Tue May 23 18:51:09 2017
index dca6e92..4409385 100644 (file)
@@ -20,7 +20,7 @@ debugfs -R "stat /l_30" test.img
 Inode: 12   Type: symlink    Mode:  0777   Flags: 0x0
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 31
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
@@ -29,7 +29,7 @@ debugfs -R "stat /l_70" test.img
 Inode: 13   Type: symlink    Mode:  0777   Flags: 0x10000000
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 71
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 0
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
@@ -40,7 +40,7 @@ debugfs -R "stat /l_500" test.img
 Inode: 14   Type: symlink    Mode:  0777   Flags: 0x80000
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 501
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 2
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
@@ -50,7 +50,7 @@ debugfs -R "stat /l_1023" test.img
 Inode: 15   Type: symlink    Mode:  0777   Flags: 0x80000
 Generation: 0    Version: 0x00000000:00000000
 User:     0   Group:     0   Project:     0   Size: 1024
-File ACL: 0    Directory ACL: 0
+File ACL: 0
 Links: 1   Blockcount: 2
 Fragment:  Address: 0    Number: 0    Size: 0
 Size of extra inode fields: 32
diff --git a/tests/f_large_dir/expect b/tests/f_large_dir/expect
new file mode 100644 (file)
index 0000000..b099460
--- /dev/null
@@ -0,0 +1,12 @@
+Pass 1: Checking inodes, blocks, and sizes
+Pass 2: Checking directory structure
+Pass 3: Checking directory connectivity
+Pass 3A: Optimizing directories
+Pass 4: Checking reference counts
+Inode 13 ref count is 1, should be 47245.  Fix? yes
+
+Pass 5: Checking group summary information
+
+test.img: ***** FILE SYSTEM WAS MODIFIED *****
+test.img: 13/115368 files (0.0% non-contiguous), 32817/460800 blocks
+Exit status is 1
diff --git a/tests/f_large_dir/is_slow_test b/tests/f_large_dir/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/f_large_dir/name b/tests/f_large_dir/name
new file mode 100644 (file)
index 0000000..4b96890
--- /dev/null
@@ -0,0 +1 @@
+optimize 3 level htree directories
diff --git a/tests/f_large_dir/script b/tests/f_large_dir/script
new file mode 100644 (file)
index 0000000..0b5fdff
--- /dev/null
@@ -0,0 +1,51 @@
+OUT=$test_name.log
+EXP=$test_dir/expect
+E2FSCK=../e2fsck/e2fsck
+
+NAMELEN=255
+DIRENT_SZ=8
+BLOCKSZ=1024
+DIRENT_PER_LEAF=$((BLOCKSZ / (NAMELEN + DIRENT_SZ)))
+HEADER=32
+INDEX_SZ=8
+INDEX_L1=$(((BLOCKSZ - HEADER) / INDEX_SZ))
+INDEX_L2=$(((BLOCKSZ - DIRENT_SZ) / INDEX_SZ))
+ENTRIES=$((INDEX_L1 * INDEX_L2 * DIRENT_PER_LEAF))
+
+cp /dev/null $OUT
+$MKE2FS -b 1024 -O large_dir,uninit_bg,dir_nlink -F $TMPFILE 460800 \
+       > /dev/null 2>&1
+{
+       echo "feature large_dir"
+       echo "mkdir /foo"
+       echo "cd /foo"
+       touch foofile
+       echo "write foofile foofile"
+       i=0
+       while test $i  -lt $ENTRIES ; do
+           if test $(( i % DIRENT_PER_LEAF )) -eq 0 ; then
+               echo "expand ./"
+           fi
+           if test $(( i % 5000 )) -eq 0 -a $i -gt 0 ; then
+               >&2 echo "$test_name: $i processed"
+           fi
+           printf "ln foofile %0255X\n" $i
+           i=$(($i + 1))
+       done
+} | $DEBUGFS -w -f /dev/stdin $TMPFILE > /dev/null 2>&1
+
+$E2FSCK -yfD $TMPFILE > $OUT.new 2>&1
+status=$?
+echo Exit status is $status >> $OUT.new
+sed -f $cmd_dir/filter.sed -e "s;$TMPFILE;test.img;" $OUT.new >> $OUT
+rm -f $OUT.new
+
+cmp -s $OUT $EXP
+RC=$?
+if [ $RC -eq 0 ]; then
+       echo "$test_name: $test_description: ok"
+       touch $test_name.ok
+else
+       echo "$test_name: $test_description: failed"
+       diff -u $EXP $OUT > $test_name.failed
+fi
diff --git a/tests/f_mmp/is_slow_test b/tests/f_mmp/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/f_mmp_garbage/is_slow_test b/tests/f_mmp_garbage/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
index 8ba81e6..d4f72a1 100644 (file)
@@ -3,7 +3,7 @@ Pass 2: Checking directory structure
 i_faddr for inode 15 (/test/quux) is 23, should be zero.
 Clear? yes
 
-i_dir_acl for inode 15 (/test/quux) is 12, should be zero.
+i_size_high for inode 15 (/test/quux) is 12, should be zero.
 Clear? yes
 
 i_file_acl for inode 13 (/test/???) is 12, should be zero.
diff --git a/tests/r_64bit_big_expand/is_slow_test b/tests/r_64bit_big_expand/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/tests/r_ext4_big_expand/is_slow_test b/tests/r_ext4_big_expand/is_slow_test
new file mode 100644 (file)
index 0000000..e69de29
index fb30e57..35465b6 100644 (file)
@@ -13,6 +13,10 @@ case "$1" in
        export USE_VALGRIND="valgrind --sim-hints=lax-ioctls --leak-check=full --show-reachable=yes --log-file=/tmp/valgrind-%p.log"
        shift;
        ;;
+    --skip-slow-tests)
+       SKIP_SLOW_TESTS=yes
+       shift;
+       ;;
 esac
 
 case "$1" in
@@ -49,6 +53,11 @@ else
        test_description=
 fi
 
+if [ -n "$SKIP_SLOW_TESTS" -a -f $test_dir/is_slow_test ]; then
+    echo "$test_name: $test_description: skipped (slow test)"
+    exit 0
+fi
+
 rm -f $test_name.ok $test_name.failed
 #echo -e -n "$test_name: $test_description:\r"
 
index b3c12a7..e6b25fa 100644 (file)
@@ -1,33 +1,23 @@
-/* work around bug in AndroidConfig.h */
-#ifdef HAVE_MALLOC_H
-#undef HAVE_MALLOC_H
+#ifndef __APPLE__
 #define HAVE_MALLOC_H 1
 #endif
 
 #define ROOT_SYSCONFDIR "/etc"
 
+#define ENABLE_LIBSPARSE 1
+
 #define DISABLE_BACKTRACE 1
 #define HAVE_DIRENT_H 1
 #define HAVE_ERRNO_H 1
-#define HAVE_EXT2_IOCTLS 1
-#define HAVE_FALLOCATE 1
 #define HAVE_GETOPT_H 1
-#define HAVE_GETPAGESIZE 1
 #define HAVE_GETPWUID_R 1
 #define HAVE_INTPTR_T 1
 #define HAVE_INTTYPES_H 1
-#define HAVE_LINUX_FD_H 1
-#define HAVE_LSEEK64 1
-#define HAVE_LSEEK64_PROTOTYPE 1
 #define HAVE_MMAP 1
-#define HAVE_NETINET_IN_H 1
-#define HAVE_NET_IF_H 1
-#define HAVE_POSIX_MEMALIGN 1
-#define HAVE_PREAD 1
-#define HAVE_PREAD64 1
-#define HAVE_PWRITE 1
-#define HAVE_PWRITE64 1
 #define HAVE_SETJMP_H 1
+#ifdef __linux__
+#define HAVE_SETMNTENT 1
+#endif
 #define HAVE_SNPRINTF 1
 #define HAVE_STDLIB_H 1
 #define HAVE_STRCASECMP 1
 #define HAVE_STRNLEN 1
 #define HAVE_STRPTIME 1
 #define HAVE_SYSCONF 1
-#define HAVE_SYS_IOCTL_H 1
-#define HAVE_SYS_MMAN_H 1
-#define HAVE_SYS_MOUNT_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_SYS_PRCTL_H 1
-#define HAVE_SYS_RESOURCE_H 1
-#define HAVE_SYS_SELECT_H 1
-#define HAVE_SYS_STAT_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_SYS_TYPES_H 1
-#define HAVE_SYS_WAIT_H 1
 #define HAVE_TYPE_SSIZE_T 1
 #define HAVE_UNISTD_H 1
 #define HAVE_UTIME_H 1
+
+#define HAVE_SYS_STAT_H 1
+#define HAVE_SYS_TIME_H 1
+#define HAVE_SYS_TYPES_H 1
+
+#if defined(_WIN32)
+# define HAVE_LINUX_TYPES_H 1
+# define HAVE_WINSOCK_H 1
+#endif
+#if defined(__APPLE__) || defined(__linux__)
+# define HAVE_FCNTL 1
+# define HAVE_FSYNC 1
+# define HAVE_GETPAGESIZE 1
+# define HAVE_NET_IF_H 1
+# define HAVE_NETINET_IN_H 1
+# define HAVE_PREAD 1
+# define HAVE_PWRITE 1
+# define HAVE_POSIX_MEMALIGN 1
+# define HAVE_SYS_IOCTL_H 1
+# define HAVE_SYS_MMAN_H 1
+# define HAVE_SYS_MOUNT_H 1
+# define HAVE_SYS_PARAM_H 1
+# define HAVE_SYS_RESOURCE_H 1
+# define HAVE_SYS_SELECT_H 1
+# define HAVE_SYS_WAIT_H 1
+#endif
+#if defined(__linux__)
+# define HAVE_EXT2_IOCTLS 1
+# define HAVE_FALLOCATE 1
+# define HAVE_LINUX_FD_H 1
+# define HAVE_LINUX_TYPES_H 1
+# define HAVE_LSEEK64 1
+# define HAVE_LSEEK64_PROTOTYPE 1
+# define HAVE_PREAD64 1
+# define HAVE_PWRITE64 1
+# define HAVE_SYS_PRCTL_H 1
+# define HAVE_SYS_SYSMACROS_H 1
+#endif
index ebd8778..937496b 100755 (executable)
@@ -7,7 +7,7 @@ ANDROID_GENERATED_FILES="lib/ext2fs/ext2_err.c lib/ext2fs/ext2_err.h \
        lib/ext2fs/ext2_types.h lib/config.h lib/blkid/blkid.h \
        lib/uuid/uuid.h lib/ext2fs/crc32c_table.h misc/default_profile.c \
        lib/ss/std_rqs.c debugfs/debug_cmds.c debugfs/ro_debug_cmds.c \
-       debugfs/extent_cmds.c debugfs/e2freefrag.c debugfs/create_inode.c \
+       debugfs/extent_cmds.c debugfs/e2freefrag.c \
        debugfs/recovery.c debugfs/revoke.c \
        MODULE_LICENSE_GPL README.version"
 
@@ -41,7 +41,7 @@ cp util/android_types.h lib/ext2fs/ext2_types.h
 cp util/android_types.h lib/blkid/blkid_types.h
 cp util/android_types.h lib/uuid/uuid_types.h
 cp util/android_config.h lib/config.h
-cp misc/e2freefrag.c misc/create_inode.c debugfs/
+cp misc/e2freefrag.c debugfs/
 cp e2fsck/recovery.c e2fsck/revoke.c debugfs/
 
 gcc -o gen_crc32ctable lib/ext2fs/gen_crc32ctable.c