Merge "Define HAVE_SYS_SYSMACROS_H for Android." am: 9b9a786601 am: 656008e0d4 am: 4f8e794825
am: e58dc46380

Change-Id: I08d292ece8442f05749adce9b765fe2a1853ac7e
diff --git a/debugfs/Android.bp b/debugfs/Android.bp
index 49ce8e7..4a2da2e 100644
--- a/debugfs/Android.bp
+++ b/debugfs/Android.bp
@@ -23,7 +23,6 @@
         "extent_cmds.c",
         "extent_inode.c",
         "zap.c",
-        "create_inode.c",
         "quota.c",
         "xattrs.c",
         "journal.c",
@@ -45,6 +44,7 @@
 }
 
 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 dc36210..0000000
--- 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 181d917..5655c3b 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 ae84a5c..ad419e2 100644
--- a/misc/Android.bp
+++ b/misc/Android.bp
@@ -30,12 +30,12 @@
         "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 ebd8778..937496b 100755
--- a/util/gen-android-files
+++ b/util/gen-android-files
@@ -7,7 +7,7 @@
 	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/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