aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2017-05-24 00:33:47 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-05-24 00:33:47 +0000
commite58dc46380039e86b3e197e1c53ba6c1708db98f (patch)
tree4d35c4ae792e03fe6836b5b17eb8dd7745ab95a9
parent14a94052fdca4dd0e01386d7b62668fe9c702fb7 (diff)
parent4f8e794825fff729825c237bafb7cba7c714a35d (diff)
downloade2fsprogs-e58dc46380039e86b3e197e1c53ba6c1708db98f.tar.gz
Merge "Define HAVE_SYS_SYSMACROS_H for Android." am: 9b9a786601 am: 656008e0d4
am: 4f8e794825 Change-Id: I789466536d74d319b31549baafae0e06c798731e
-rw-r--r--debugfs/Android.bp2
-rw-r--r--debugfs/create_inode.c972
-rw-r--r--lib/config.h1
-rw-r--r--misc/Android.bp2
-rwxr-xr-xutil/gen-android-files4
5 files changed, 5 insertions, 976 deletions
diff --git a/debugfs/Android.bp b/debugfs/Android.bp
index 49ce8e72..4a2da2e7 100644
--- a/debugfs/Android.bp
+++ b/debugfs/Android.bp
@@ -23,7 +23,6 @@ cc_defaults {
"extent_cmds.c",
"extent_inode.c",
"zap.c",
- "create_inode.c",
"quota.c",
"xattrs.c",
"journal.c",
@@ -45,6 +44,7 @@ cc_defaults {
}
debugfs_libs = [
+ "libext2_misc",
"libext2fs",
"libext2_blkid",
"libext2_uuid",
diff --git a/debugfs/create_inode.c b/debugfs/create_inode.c
deleted file mode 100644
index dc362108..00000000
--- a/debugfs/create_inode.c
+++ /dev/null
@@ -1,972 +0,0 @@
-/*
- * create_inode.c --- create an inode
- *
- * Copyright (C) 2014 Robert Yang <liezhi.yang@windriver.com>
- *
- * %Begin-Header%
- * This file may be redistributed under the terms of the GNU library
- * General Public License, version 2.
- * %End-Header%
- */
-
-#define _FILE_OFFSET_BITS 64
-#define _LARGEFILE64_SOURCE 1
-#define _GNU_SOURCE 1
-
-#include "config.h"
-#include <time.h>
-#include <sys/types.h>
-#include <unistd.h>
-#include <limits.h> /* for PATH_MAX */
-#ifdef HAVE_ATTR_XATTR_H
-#include <attr/xattr.h>
-#endif
-#include <sys/ioctl.h>
-#include <ext2fs/ext2fs.h>
-#include <ext2fs/ext2_types.h>
-#include <ext2fs/fiemap.h>
-
-#include "create_inode.h"
-#include "support/nls-enable.h"
-
-/* 64KiB is the minimium blksize to best minimize system call overhead. */
-#define COPY_FILE_BUFLEN 65536
-
-static int ext2_file_type(unsigned int mode)
-{
- if (LINUX_S_ISREG(mode))
- return EXT2_FT_REG_FILE;
-
- if (LINUX_S_ISDIR(mode))
- return EXT2_FT_DIR;
-
- if (LINUX_S_ISCHR(mode))
- return EXT2_FT_CHRDEV;
-
- if (LINUX_S_ISBLK(mode))
- return EXT2_FT_BLKDEV;
-
- if (LINUX_S_ISLNK(mode))
- return EXT2_FT_SYMLINK;
-
- if (LINUX_S_ISFIFO(mode))
- return EXT2_FT_FIFO;
-
- if (LINUX_S_ISSOCK(mode))
- return EXT2_FT_SOCK;
-
- return 0;
-}
-
-/* Link an inode number to a directory */
-static errcode_t add_link(ext2_filsys fs, ext2_ino_t parent_ino,
- ext2_ino_t ino, const char *name)
-{
- struct ext2_inode inode;
- errcode_t retval;
-
- retval = ext2fs_read_inode(fs, ino, &inode);
- if (retval) {
- com_err(__func__, retval, _("while reading inode %u"), ino);
- return retval;
- }
-
- retval = ext2fs_link(fs, parent_ino, name, ino,
- ext2_file_type(inode.i_mode));
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(fs, parent_ino);
- if (retval) {
- com_err(__func__, retval,
- _("while expanding directory"));
- return retval;
- }
- retval = ext2fs_link(fs, parent_ino, name, ino,
- ext2_file_type(inode.i_mode));
- }
- if (retval) {
- com_err(__func__, retval, _("while linking \"%s\""), name);
- return retval;
- }
-
- inode.i_links_count++;
-
- retval = ext2fs_write_inode(fs, ino, &inode);
- if (retval)
- com_err(__func__, retval, _("while writing inode %u"), ino);
-
- return retval;
-}
-
-/* Set the uid, gid, mode and time for the inode */
-static errcode_t set_inode_extra(ext2_filsys fs, ext2_ino_t ino,
- struct stat *st)
-{
- errcode_t retval;
- struct ext2_inode inode;
-
- retval = ext2fs_read_inode(fs, ino, &inode);
- if (retval) {
- com_err(__func__, retval, _("while reading inode %u"), ino);
- return retval;
- }
-
- inode.i_uid = st->st_uid;
- inode.i_gid = st->st_gid;
- inode.i_mode |= st->st_mode;
- inode.i_atime = st->st_atime;
- inode.i_mtime = st->st_mtime;
- inode.i_ctime = st->st_ctime;
-
- retval = ext2fs_write_inode(fs, ino, &inode);
- if (retval)
- com_err(__func__, retval, _("while writing inode %u"), ino);
- return retval;
-}
-
-#ifdef HAVE_LLISTXATTR
-static errcode_t set_inode_xattr(ext2_filsys fs, ext2_ino_t ino,
- const char *filename)
-{
- errcode_t retval, close_retval;
- struct ext2_xattr_handle *handle;
- ssize_t size, value_size;
- char *list = NULL;
- int i;
-
- size = llistxattr(filename, NULL, 0);
- if (size == -1) {
- retval = errno;
- com_err(__func__, retval, _("while listing attributes of \"%s\""),
- filename);
- return retval;
- } else if (size == 0) {
- return 0;
- }
-
- retval = ext2fs_xattrs_open(fs, ino, &handle);
- if (retval) {
- if (retval == EXT2_ET_MISSING_EA_FEATURE)
- return 0;
- com_err(__func__, retval, _("while opening inode %u"), ino);
- return retval;
- }
-
- retval = ext2fs_get_mem(size, &list);
- if (retval) {
- com_err(__func__, retval, _("while allocating memory"));
- goto out;
- }
-
- size = llistxattr(filename, list, size);
- if (size == -1) {
- retval = errno;
- com_err(__func__, retval, _("while listing attributes of \"%s\""),
- filename);
- goto out;
- }
-
- for (i = 0; i < size; i += strlen(&list[i]) + 1) {
- const char *name = &list[i];
- char *value;
-
- value_size = lgetxattr(filename, name, NULL, 0);
- if (value_size == -1) {
- retval = errno;
- com_err(__func__, retval,
- _("while reading attribute \"%s\" of \"%s\""),
- name, filename);
- break;
- }
-
- retval = ext2fs_get_mem(value_size, &value);
- if (retval) {
- com_err(__func__, retval, _("while allocating memory"));
- break;
- }
-
- value_size = lgetxattr(filename, name, value, value_size);
- if (value_size == -1) {
- ext2fs_free_mem(&value);
- retval = errno;
- com_err(__func__, retval,
- _("while reading attribute \"%s\" of \"%s\""),
- name, filename);
- break;
- }
-
- retval = ext2fs_xattr_set(handle, name, value, value_size);
- ext2fs_free_mem(&value);
- if (retval) {
- com_err(__func__, retval,
- _("while writing attribute \"%s\" to inode %u"),
- name, ino);
- break;
- }
-
- }
- out:
- ext2fs_free_mem(&list);
- close_retval = ext2fs_xattrs_close(&handle);
- if (close_retval) {
- com_err(__func__, retval, _("while closing inode %u"), ino);
- retval = retval ? retval : close_retval;
- }
- return retval;
- return 0;
-}
-#else /* HAVE_LLISTXATTR */
-static errcode_t set_inode_xattr(ext2_filsys fs EXT2FS_ATTR((unused)),
- ext2_ino_t ino EXT2FS_ATTR((unused)),
- const char *filename EXT2FS_ATTR((unused)))
-{
- return 0;
-}
-#endif /* HAVE_LLISTXATTR */
-
-/* Make a special files (block and character devices), fifo's, and sockets */
-errcode_t do_mknod_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
- struct stat *st)
-{
- ext2_ino_t ino;
- errcode_t retval;
- struct ext2_inode inode;
- unsigned long devmajor, devminor, mode;
- int filetype;
-
- switch(st->st_mode & S_IFMT) {
- case S_IFCHR:
- mode = LINUX_S_IFCHR;
- filetype = EXT2_FT_CHRDEV;
- break;
- case S_IFBLK:
- mode = LINUX_S_IFBLK;
- filetype = EXT2_FT_BLKDEV;
- break;
- case S_IFIFO:
- mode = LINUX_S_IFIFO;
- filetype = EXT2_FT_FIFO;
- break;
- case S_IFSOCK:
- mode = LINUX_S_IFSOCK;
- filetype = EXT2_FT_SOCK;
- break;
- default:
- return EXT2_ET_INVALID_ARGUMENT;
- }
-
- retval = ext2fs_new_inode(fs, cwd, 010755, 0, &ino);
- if (retval) {
- com_err(__func__, retval, _("while allocating inode \"%s\""),
- name);
- return retval;
- }
-
-#ifdef DEBUGFS
- printf("Allocated inode: %u\n", ino);
-#endif
- retval = ext2fs_link(fs, cwd, name, ino, filetype);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(fs, cwd);
- if (retval) {
- com_err(__func__, retval,
- _("while expanding directory"));
- return retval;
- }
- retval = ext2fs_link(fs, cwd, name, ino, filetype);
- }
- if (retval) {
- com_err(name, retval, _("while creating inode \"%s\""), name);
- return retval;
- }
- if (ext2fs_test_inode_bitmap2(fs->inode_map, ino))
- com_err(__func__, 0, "Warning: inode already set");
- ext2fs_inode_alloc_stats2(fs, ino, +1, 0);
- memset(&inode, 0, sizeof(inode));
- inode.i_mode = mode;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
-
- if (filetype != S_IFIFO) {
- devmajor = major(st->st_rdev);
- devminor = minor(st->st_rdev);
-
- if ((devmajor < 256) && (devminor < 256)) {
- inode.i_block[0] = devmajor * 256 + devminor;
- inode.i_block[1] = 0;
- } else {
- inode.i_block[0] = 0;
- inode.i_block[1] = (devminor & 0xff) | (devmajor << 8) |
- ((devminor & ~0xff) << 12);
- }
- }
- inode.i_links_count = 1;
-
- retval = ext2fs_write_new_inode(fs, ino, &inode);
- if (retval)
- com_err(__func__, retval, _("while writing inode %u"), ino);
-
- return retval;
-}
-
-/* Make a symlink name -> target */
-errcode_t do_symlink_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
- char *target, ext2_ino_t root)
-{
- char *cp;
- ext2_ino_t parent_ino;
- errcode_t retval;
-
- cp = strrchr(name, '/');
- if (cp) {
- *cp = 0;
- retval = ext2fs_namei(fs, root, cwd, name, &parent_ino);
- if (retval) {
- com_err(name, retval, 0);
- return retval;
- }
- name = cp+1;
- } else
- parent_ino = cwd;
-
- retval = ext2fs_symlink(fs, parent_ino, 0, name, target);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(fs, parent_ino);
- if (retval) {
- com_err("do_symlink_internal", retval,
- _("while expanding directory"));
- return retval;
- }
- retval = ext2fs_symlink(fs, parent_ino, 0, name, target);
- }
- if (retval)
- com_err("ext2fs_symlink", retval,
- _("while creating symlink \"%s\""), name);
- return retval;
-}
-
-/* Make a directory in the fs */
-errcode_t do_mkdir_internal(ext2_filsys fs, ext2_ino_t cwd, const char *name,
- ext2_ino_t root)
-{
- char *cp;
- ext2_ino_t parent_ino;
- errcode_t retval;
-
-
- cp = strrchr(name, '/');
- if (cp) {
- *cp = 0;
- retval = ext2fs_namei(fs, root, cwd, name, &parent_ino);
- if (retval) {
- com_err(name, retval, _("while looking up \"%s\""),
- name);
- return retval;
- }
- name = cp+1;
- } else
- parent_ino = cwd;
-
- retval = ext2fs_mkdir(fs, parent_ino, 0, name);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(fs, parent_ino);
- if (retval) {
- com_err(__func__, retval,
- _("while expanding directory"));
- return retval;
- }
- retval = ext2fs_mkdir(fs, parent_ino, 0, name);
- }
- if (retval)
- com_err("ext2fs_mkdir", retval,
- _("while creating directory \"%s\""), name);
- return retval;
-}
-
-#if !defined HAVE_PREAD64 && !defined HAVE_PREAD
-static ssize_t my_pread(int fd, void *buf, size_t count, off_t offset)
-{
- if (lseek(fd, offset, SEEK_SET) < 0)
- return 0;
-
- return read(fd, buf, count);
-}
-#endif /* !defined HAVE_PREAD64 && !defined HAVE_PREAD */
-
-static errcode_t copy_file_range(ext2_filsys fs, int fd, ext2_file_t e2_file,
- off_t start, off_t end, char *buf,
- char *zerobuf)
-{
- off_t off, bpos;
- ssize_t got, blen;
- unsigned int written;
- char *ptr;
- errcode_t err = 0;
-
- for (off = start; off < end; off += COPY_FILE_BUFLEN) {
-#ifdef HAVE_PREAD64
- got = pread64(fd, buf, COPY_FILE_BUFLEN, off);
-#elif HAVE_PREAD
- got = pread(fd, buf, COPY_FILE_BUFLEN, off);
-#else
- got = my_pread(fd, buf, COPY_FILE_BUFLEN, off);
-#endif
- if (got < 0) {
- err = errno;
- goto fail;
- }
- for (bpos = 0, ptr = buf; bpos < got; bpos += fs->blocksize) {
- blen = fs->blocksize;
- if (blen > got - bpos)
- blen = got - bpos;
- if (memcmp(ptr, zerobuf, blen) == 0) {
- ptr += blen;
- continue;
- }
- err = ext2fs_file_lseek(e2_file, off + bpos,
- EXT2_SEEK_SET, NULL);
- if (err)
- goto fail;
- while (blen > 0) {
- err = ext2fs_file_write(e2_file, ptr, blen,
- &written);
- if (err)
- goto fail;
- if (written == 0) {
- err = EIO;
- goto fail;
- }
- blen -= written;
- ptr += written;
- }
- }
- }
-fail:
- return err;
-}
-
-#if defined(SEEK_DATA) && defined(SEEK_HOLE)
-static errcode_t try_lseek_copy(ext2_filsys fs, int fd, struct stat *statbuf,
- ext2_file_t e2_file, char *buf, char *zerobuf)
-{
- off_t data = 0, hole;
- off_t data_blk, hole_blk;
- errcode_t err = 0;
-
- /* Try to use SEEK_DATA and SEEK_HOLE */
- while (data < statbuf->st_size) {
- data = lseek(fd, data, SEEK_DATA);
- if (data < 0) {
- if (errno == ENXIO)
- break;
- return EXT2_ET_UNIMPLEMENTED;
- }
- hole = lseek(fd, data, SEEK_HOLE);
- if (hole < 0)
- return EXT2_ET_UNIMPLEMENTED;
-
- data_blk = data & ~(fs->blocksize - 1);
- hole_blk = (hole + (fs->blocksize - 1)) & ~(fs->blocksize - 1);
- err = copy_file_range(fs, fd, e2_file, data_blk, hole_blk, buf,
- zerobuf);
- if (err)
- return err;
-
- data = hole;
- }
-
- return err;
-}
-#endif /* SEEK_DATA and SEEK_HOLE */
-
-#if defined(FS_IOC_FIEMAP)
-static errcode_t try_fiemap_copy(ext2_filsys fs, int fd, ext2_file_t e2_file,
- char *buf, char *zerobuf)
-{
-#define EXTENT_MAX_COUNT 512
- struct fiemap *fiemap_buf;
- struct fiemap_extent *ext_buf, *ext;
- int ext_buf_size, fie_buf_size;
- off_t pos = 0;
- unsigned int i;
- errcode_t err;
-
- ext_buf_size = EXTENT_MAX_COUNT * sizeof(struct fiemap_extent);
- fie_buf_size = sizeof(struct fiemap) + ext_buf_size;
-
- err = ext2fs_get_memzero(fie_buf_size, &fiemap_buf);
- if (err)
- return err;
-
- ext_buf = fiemap_buf->fm_extents;
- memset(fiemap_buf, 0, fie_buf_size);
- fiemap_buf->fm_length = FIEMAP_MAX_OFFSET;
- fiemap_buf->fm_flags |= FIEMAP_FLAG_SYNC;
- fiemap_buf->fm_extent_count = EXTENT_MAX_COUNT;
-
- do {
- fiemap_buf->fm_start = pos;
- memset(ext_buf, 0, ext_buf_size);
- err = ioctl(fd, FS_IOC_FIEMAP, fiemap_buf);
- if (err < 0 && (errno == EOPNOTSUPP || errno == ENOTTY)) {
- err = EXT2_ET_UNIMPLEMENTED;
- goto out;
- } else if (err < 0 || fiemap_buf->fm_mapped_extents == 0) {
- err = errno;
- goto out;
- }
- for (i = 0, ext = ext_buf; i < fiemap_buf->fm_mapped_extents;
- i++, ext++) {
- err = copy_file_range(fs, fd, e2_file, ext->fe_logical,
- ext->fe_logical + ext->fe_length,
- buf, zerobuf);
- if (err)
- goto out;
- }
-
- ext--;
- /* Record file's logical offset this time */
- pos = ext->fe_logical + ext->fe_length;
- /*
- * If fm_extents array has been filled and
- * there are extents left, continue to cycle.
- */
- } while (fiemap_buf->fm_mapped_extents == EXTENT_MAX_COUNT &&
- !(ext->fe_flags & FIEMAP_EXTENT_LAST));
-out:
- ext2fs_free_mem(&fiemap_buf);
- return err;
-}
-#endif /* FS_IOC_FIEMAP */
-
-static errcode_t copy_file(ext2_filsys fs, int fd, struct stat *statbuf,
- ext2_ino_t ino)
-{
- ext2_file_t e2_file;
- char *buf = NULL, *zerobuf = NULL;
- errcode_t err, close_err;
-
- err = ext2fs_file_open(fs, ino, EXT2_FILE_WRITE, &e2_file);
- if (err)
- return err;
-
- err = ext2fs_get_mem(COPY_FILE_BUFLEN, &buf);
- if (err)
- goto out;
-
- err = ext2fs_get_memzero(fs->blocksize, &zerobuf);
- if (err)
- goto out;
-
-#if defined(SEEK_DATA) && defined(SEEK_HOLE)
- err = try_lseek_copy(fs, fd, statbuf, e2_file, buf, zerobuf);
- if (err != EXT2_ET_UNIMPLEMENTED)
- goto out;
-#endif
-
-#if defined(FS_IOC_FIEMAP)
- err = try_fiemap_copy(fs, fd, e2_file, buf, zerobuf);
- if (err != EXT2_ET_UNIMPLEMENTED)
- goto out;
-#endif
-
- err = copy_file_range(fs, fd, e2_file, 0, statbuf->st_size, buf,
- zerobuf);
-out:
- ext2fs_free_mem(&zerobuf);
- ext2fs_free_mem(&buf);
- close_err = ext2fs_file_close(e2_file);
- if (err == 0)
- err = close_err;
- return err;
-}
-
-static int is_hardlink(struct hdlinks_s *hdlinks, dev_t dev, ino_t ino)
-{
- int i;
-
- for (i = 0; i < hdlinks->count; i++) {
- if (hdlinks->hdl[i].src_dev == dev &&
- hdlinks->hdl[i].src_ino == ino)
- return i;
- }
- return -1;
-}
-
-/* Copy the native file to the fs */
-errcode_t do_write_internal(ext2_filsys fs, ext2_ino_t cwd, const char *src,
- const char *dest, ext2_ino_t root)
-{
- int fd;
- struct stat statbuf;
- ext2_ino_t newfile;
- errcode_t retval;
- struct ext2_inode inode;
-
- fd = ext2fs_open_file(src, O_RDONLY, 0);
- if (fd < 0) {
- retval = errno;
- com_err(__func__, retval, _("while opening \"%s\" to copy"),
- src);
- return retval;
- }
- if (fstat(fd, &statbuf) < 0) {
- retval = errno;
- goto out;
- }
-
- retval = ext2fs_namei(fs, root, cwd, dest, &newfile);
- if (retval == 0) {
- retval = EXT2_ET_FILE_EXISTS;
- goto out;
- }
-
- retval = ext2fs_new_inode(fs, cwd, 010755, 0, &newfile);
- if (retval)
- goto out;
-#ifdef DEBUGFS
- printf("Allocated inode: %u\n", newfile);
-#endif
- retval = ext2fs_link(fs, cwd, dest, newfile,
- EXT2_FT_REG_FILE);
- if (retval == EXT2_ET_DIR_NO_SPACE) {
- retval = ext2fs_expand_dir(fs, cwd);
- if (retval)
- goto out;
- retval = ext2fs_link(fs, cwd, dest, newfile,
- EXT2_FT_REG_FILE);
- }
- if (retval)
- goto out;
- if (ext2fs_test_inode_bitmap2(fs->inode_map, newfile))
- com_err(__func__, 0, "Warning: inode already set");
- ext2fs_inode_alloc_stats2(fs, newfile, +1, 0);
- memset(&inode, 0, sizeof(inode));
- inode.i_mode = (statbuf.st_mode & ~LINUX_S_IFMT) | LINUX_S_IFREG;
- inode.i_atime = inode.i_ctime = inode.i_mtime =
- fs->now ? fs->now : time(0);
- inode.i_links_count = 1;
- retval = ext2fs_inode_size_set(fs, &inode, statbuf.st_size);
- if (retval)
- goto out;
- if (ext2fs_has_feature_inline_data(fs->super)) {
- inode.i_flags |= EXT4_INLINE_DATA_FL;
- } else if (ext2fs_has_feature_extents(fs->super)) {
- ext2_extent_handle_t handle;
-
- inode.i_flags &= ~EXT4_EXTENTS_FL;
- retval = ext2fs_extent_open2(fs, newfile, &inode, &handle);
- if (retval)
- goto out;
- ext2fs_extent_free(handle);
- }
-
- retval = ext2fs_write_new_inode(fs, newfile, &inode);
- if (retval)
- goto out;
- if (inode.i_flags & EXT4_INLINE_DATA_FL) {
- retval = ext2fs_inline_data_init(fs, newfile);
- if (retval)
- goto out;
- }
- if (LINUX_S_ISREG(inode.i_mode)) {
- retval = copy_file(fs, fd, &statbuf, newfile);
- if (retval)
- goto out;
- }
-out:
- close(fd);
- 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 file_info *target,
- struct fs_ops_callbacks *fs_callbacks)
-{
- const char *name;
- DIR *dh;
- struct dirent *dent;
- struct stat st;
- char *ln_target = NULL;
- unsigned int save_inode;
- ext2_ino_t ino;
- errcode_t retval = 0;
- int read_cnt;
- int hdlink;
- size_t cur_dir_path_len;
-
- if (chdir(source_dir) < 0) {
- retval = errno;
- com_err(__func__, retval,
- _("while changing working directory to \"%s\""),
- source_dir);
- return retval;
- }
-
- if (!(dh = opendir("."))) {
- retval = errno;
- com_err(__func__, retval,
- _("while opening directory \"%s\""), source_dir);
- return retval;
- }
-
- while ((dent = readdir(dh))) {
- if ((!strcmp(dent->d_name, ".")) ||
- (!strcmp(dent->d_name, "..")))
- continue;
- if (lstat(dent->d_name, &st)) {
- retval = errno;
- com_err(__func__, retval, _("while lstat \"%s\""),
- dent->d_name);
- goto out;
- }
- name = dent->d_name;
-
- /* Check for hardlinks */
- save_inode = 0;
- if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) &&
- st.st_nlink > 1) {
- hdlink = is_hardlink(hdlinks, st.st_dev, st.st_ino);
- if (hdlink >= 0) {
- retval = add_link(fs, parent_ino,
- hdlinks->hdl[hdlink].dst_ino,
- name);
- if (retval) {
- com_err(__func__, retval,
- "while linking %s", name);
- goto out;
- }
- continue;
- } else
- 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:
- case S_IFIFO:
- case S_IFSOCK:
- retval = do_mknod_internal(fs, parent_ino, name, &st);
- if (retval) {
- com_err(__func__, retval,
- _("while creating special file "
- "\"%s\""), name);
- goto out;
- }
- break;
- case S_IFLNK:
- ln_target = malloc(st.st_size + 1);
- if (ln_target == NULL) {
- com_err(__func__, retval,
- _("malloc failed"));
- goto out;
- }
- read_cnt = readlink(name, ln_target,
- st.st_size + 1);
- if (read_cnt == -1) {
- retval = errno;
- com_err(__func__, retval,
- _("while trying to read link \"%s\""),
- name);
- free(ln_target);
- goto out;
- }
- if (read_cnt > st.st_size) {
- com_err(__func__, retval,
- _("symlink increased in size "
- "between lstat() and readlink()"));
- free(ln_target);
- goto out;
- }
- ln_target[read_cnt] = '\0';
- retval = do_symlink_internal(fs, parent_ino, name,
- ln_target, root);
- free(ln_target);
- if (retval) {
- com_err(__func__, retval,
- _("while writing symlink\"%s\""),
- name);
- goto out;
- }
- break;
- case S_IFREG:
- retval = do_write_internal(fs, parent_ino, name, name,
- root);
- if (retval) {
- com_err(__func__, retval,
- _("while writing file \"%s\""), name);
- goto out;
- }
- break;
- case S_IFDIR:
- /* Don't choke on /lost+found */
- if (parent_ino == EXT2_ROOT_INO &&
- strcmp(name, "lost+found") == 0)
- goto find_lnf;
- retval = do_mkdir_internal(fs, parent_ino, name,
- root);
- if (retval) {
- com_err(__func__, retval,
- _("while making dir \"%s\""), name);
- goto out;
- }
-find_lnf:
- retval = ext2fs_namei(fs, root, parent_ino,
- name, &ino);
- if (retval) {
- com_err(name, retval, 0);
- goto out;
- }
- /* Populate the dir recursively*/
- retval = __populate_fs(fs, ino, name, root, hdlinks,
- target, fs_callbacks);
- if (retval)
- goto out;
- if (chdir("..")) {
- retval = errno;
- com_err(__func__, retval,
- _("while changing directory"));
- goto out;
- }
- break;
- default:
- com_err(__func__, 0,
- _("ignoring entry \"%s\""), name);
- }
-
- retval = ext2fs_namei(fs, root, parent_ino, name, &ino);
- if (retval) {
- com_err(name, retval, _("while looking up \"%s\""),
- name);
- goto out;
- }
-
- retval = set_inode_extra(fs, ino, &st);
- if (retval) {
- com_err(__func__, retval,
- _("while setting inode for \"%s\""), name);
- goto out;
- }
-
- retval = set_inode_xattr(fs, ino, name);
- if (retval) {
- com_err(__func__, retval,
- _("while setting xattrs for \"%s\""), name);
- 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) {
- /*
- * Check whether need more memory, and we don't need
- * free() since the lifespan will be over after the fs
- * populated.
- */
- if (hdlinks->count == hdlinks->size) {
- void *p = realloc(hdlinks->hdl,
- (hdlinks->size + HDLINK_CNT) *
- sizeof(struct hdlink_s));
- if (p == NULL) {
- retval = EXT2_ET_NO_MEMORY;
- com_err(name, retval,
- _("while saving inode data"));
- goto out;
- }
- hdlinks->hdl = p;
- hdlinks->size += HDLINK_CNT;
- }
- hdlinks->hdl[hdlinks->count].src_dev = st.st_dev;
- hdlinks->hdl[hdlinks->count].src_ino = st.st_ino;
- hdlinks->hdl[hdlinks->count].dst_ino = ino;
- hdlinks->count++;
- }
- target->path_len = cur_dir_path_len;
- target->path[target->path_len] = 0;
- }
-
-out:
- closedir(dh);
- return retval;
-}
-
-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;
-
- if (!(fs->flags & EXT2_FLAG_RW)) {
- com_err(__func__, 0, "Filesystem opened readonly");
- return EROFS;
- }
-
- hdlinks.count = 0;
- hdlinks.size = HDLINK_CNT;
- hdlinks.hdl = realloc(NULL, hdlinks.size * sizeof(struct hdlink_s));
- if (hdlinks.hdl == NULL) {
- retval = errno;
- com_err(__func__, retval, _("while allocating memory"));
- return retval;
- }
-
- 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);
-}
diff --git a/lib/config.h b/lib/config.h
index 181d9177..5655c3ba 100644
--- a/lib/config.h
+++ b/lib/config.h
@@ -72,4 +72,5 @@
# define HAVE_PREAD64 1
# define HAVE_PWRITE64 1
# define HAVE_SYS_PRCTL_H 1
+# define HAVE_SYS_SYSMACROS_H 1
#endif
diff --git a/misc/Android.bp b/misc/Android.bp
index ae84a5c4..ad419e22 100644
--- a/misc/Android.bp
+++ b/misc/Android.bp
@@ -30,12 +30,12 @@ cc_binary {
"util.c",
"mk_hugefiles.c",
"default_profile.c",
- "create_inode.c",
],
cflags: ["-W", "-Wall", "-Wno-macro-redefined"],
shared_libs: [
"libext2fs",
"libext2_blkid",
+ "libext2_misc",
"libext2_uuid",
"libext2_quota",
"libext2_com_err",
diff --git a/util/gen-android-files b/util/gen-android-files
index ebd8778b..937496bc 100755
--- a/util/gen-android-files
+++ b/util/gen-android-files
@@ -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