/*
 * 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;
}

/* 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)
{
	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;

	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;
		}

		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);
			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;
		}

		/* 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++;
		}
	}

out:
	closedir(dh);
	return retval;
}

errcode_t populate_fs(ext2_filsys fs, ext2_ino_t parent_ino,
		      const char *source_dir, ext2_ino_t root)
{
	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;
	}

	retval = __populate_fs(fs, parent_ino, source_dir, root, &hdlinks);

	free(hdlinks.hdl);
	return retval;
}
