linux-ext4.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory
@ 2013-12-23 12:09 Robert Yang
  2013-12-23 12:09 ` [PATCH 01/10] mke2fs.c: " Robert Yang
                   ` (10 more replies)
  0 siblings, 11 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

Hi Ted,

I'm very sorry for the late response, I've fixed the problems which you 
pointed out in the RFC patches, and now the "make check" works well.

* Changes from the RFC patches:
  - Move the common code of debugfs and mke2fs to misc/create_inode.c to
    avoid bloating the tune2fs binary
  - Fix the error of "make check"
  - Rebase to the up to date master branch

Merry Christmas and Happy New Year!

// Robert

Robert Yang (10):
  mke2fs.c: add an option: -d root-directory
  misc/create_inode.c: copy files recursively
  misc/create_inode.c: create special file
  misc/create_inode.c: create symlink
  misc/create_inode.c: copy regular file
  misc/create_inode.c: create directory
  misc/create_inode.c: set owner/mode/time for the inode
  misc/create_inode.c: handle hardlinks
  debugfs: use the functions in misc/create_inode.c
  mke2fs.8.in: update the manual for the -d option

 debugfs/Makefile.in |   17 +-
 debugfs/debugfs.c   |  305 ++-------------------------
 debugfs/debugfs.h   |    1 +
 misc/Makefile.in    |   13 +-
 misc/create_inode.c |  575 +++++++++++++++++++++++++++++++++++++++++++++++++++
 misc/create_inode.h |   35 ++++
 misc/mke2fs.8.in    |    7 +
 misc/mke2fs.c       |   43 +++-
 8 files changed, 691 insertions(+), 305 deletions(-)
 create mode 100644 misc/create_inode.c
 create mode 100644 misc/create_inode.h

-- 
1.7.10.4


^ permalink raw reply	[flat|nested] 20+ messages in thread

* [PATCH 01/10] mke2fs.c: add an option: -d root-directory
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 19:08   ` Darren Hart
  2013-12-23 12:09 ` [PATCH 02/10] misc/create_inode.c: copy files recursively Robert Yang
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

This option is used for adding the files from a given directory (the
root-directory) to the filesystem, it is similiar to genext2fs, but
genext2fs doesn't fully support ext4.

This commit describes the skeleton of the implementation:
* We already have the basic operations in debugfs:
  - Copy regular file
  - Create directory
  - Create symlink
  - Create special file

  We will move these operations into create_inode.h and create_inode.c,
  then let both mke2fs and debugfs use them.

* What we need to do are:
  - Copy the given directory recursively
  - Set the owner, mode and other informations
  - Handle the hard links

TODO:
  - The libext2fs can't create the socket file (S_IFSOCK), do we have a
    plan to support it ?

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/Makefile.in    |   13 +++++++++----
 misc/create_inode.c |   26 ++++++++++++++++++++++++++
 misc/create_inode.h |   17 +++++++++++++++++
 misc/mke2fs.c       |   32 +++++++++++++++++++++++---------
 4 files changed, 75 insertions(+), 13 deletions(-)
 create mode 100644 misc/create_inode.c
 create mode 100644 misc/create_inode.h

diff --git a/misc/Makefile.in b/misc/Makefile.in
index a798f96..da780fe 100644
--- a/misc/Makefile.in
+++ b/misc/Makefile.in
@@ -42,7 +42,7 @@ LPROGS=		@E2INITRD_PROG@
 
 TUNE2FS_OBJS=	tune2fs.o util.o
 MKLPF_OBJS=	mklost+found.o
-MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o
+MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o create_inode.o
 CHATTR_OBJS=	chattr.o
 LSATTR_OBJS=	lsattr.o
 UUIDGEN_OBJS=	uuidgen.o
@@ -60,7 +60,8 @@ E2FREEFRAG_OBJS= e2freefrag.o
 PROFILED_TUNE2FS_OBJS=	profiled/tune2fs.o profiled/util.o
 PROFILED_MKLPF_OBJS=	profiled/mklost+found.o
 PROFILED_MKE2FS_OBJS=	profiled/mke2fs.o profiled/util.o profiled/profile.o \
-			profiled/prof_err.o profiled/default_profile.o
+			profiled/prof_err.o profiled/default_profile.o \
+			profiled/create_inode.o
 PROFILED_CHATTR_OBJS=	profiled/chattr.o
 PROFILED_LSATTR_OBJS=	profiled/lsattr.o
 PROFILED_UUIDGEN_OBJS=	profiled/uuidgen.o
@@ -82,7 +83,7 @@ SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
 		$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
 		$(srcdir)/filefrag.c $(srcdir)/base_device.c \
 		$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
-		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c
+		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c
 
 LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
 DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
@@ -612,7 +613,7 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_builddir)/lib/config.h \
  $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
  $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
  $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
- $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h \
+ $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h $(srcdir)/create_inode.h\
  $(top_srcdir)/lib/quota/quotaio.h $(top_srcdir)/lib/quota/dqblk_v2.h \
  $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h
 chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
@@ -692,3 +693,7 @@ e2freefrag.o: $(srcdir)/e2freefrag.c $(top_builddir)/lib/config.h \
  $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
  $(srcdir)/e2freefrag.h
+create_inode.o: $(srcdir)/create_inode.h $(srcdir)/create_inode.c \
+ $(top_builddir)/lib/config.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
+ $(srcdir)/nls-enable.h
diff --git a/misc/create_inode.c b/misc/create_inode.c
new file mode 100644
index 0000000..46aaa60
--- /dev/null
+++ b/misc/create_inode.c
@@ -0,0 +1,26 @@
+#include "create_inode.h"
+
+/* Make a special file which is block, character and fifo */
+errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
+{
+}
+
+/* Make a symlink name -> target */
+errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target)
+{
+}
+
+/* Make a directory in the fs */
+errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
+{
+}
+
+/* Copy the native file to the fs */
+errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
+{
+}
+
+/* Copy files from source_dir to fs */
+errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
+{
+}
diff --git a/misc/create_inode.h b/misc/create_inode.h
new file mode 100644
index 0000000..9fc97fa
--- /dev/null
+++ b/misc/create_inode.h
@@ -0,0 +1,17 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "et/com_err.h"
+#include "e2p/e2p.h"
+#include "ext2fs/ext2fs.h"
+#include "nls-enable.h"
+
+ext2_filsys    current_fs;
+ext2_ino_t     root;
+
+/* For populating the filesystem */
+extern errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir);
+extern errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st);
+extern errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target);
+extern errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st);
+extern errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest);
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index 4075099..eab5463 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -22,7 +22,6 @@
 #include <stdio.h>
 #include <string.h>
 #include <strings.h>
-#include <fcntl.h>
 #include <ctype.h>
 #include <time.h>
 #ifdef __linux__
@@ -44,24 +43,19 @@ extern int optind;
 #include <errno.h>
 #endif
 #include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 #include <libgen.h>
 #include <limits.h>
 #include <blkid/blkid.h>
 
 #include "ext2fs/ext2_fs.h"
 #include "ext2fs/ext2fsP.h"
-#include "et/com_err.h"
 #include "uuid/uuid.h"
-#include "e2p/e2p.h"
-#include "ext2fs/ext2fs.h"
 #include "util.h"
 #include "profile.h"
 #include "prof_err.h"
 #include "../version.h"
-#include "nls-enable.h"
 #include "quota/mkquota.h"
+#include "create_inode.h"
 
 #define STRIDE_LENGTH 8
 
@@ -105,6 +99,7 @@ char *mount_dir;
 char *journal_device;
 int sync_kludge;	/* Set using the MKE2FS_SYNC env. option */
 char **fs_types;
+const char *root_dir;  /* Copy files from the specified directory */
 
 profile_t	profile;
 
@@ -116,7 +111,8 @@ static void usage(void)
 	fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
 	"[-C cluster-size]\n\t[-i bytes-per-inode] [-I inode-size] "
 	"[-J journal-options]\n"
-	"\t[-G flex-group-size] [-N number-of-inodes]\n"
+	"\t[-G flex-group-size] [-N number-of-inodes] "
+	"[-d root-directory]\n"
 	"\t[-m reserved-blocks-percentage] [-o creator-os]\n"
 	"\t[-g blocks-per-group] [-L volume-label] "
 	"[-M last-mounted-directory]\n\t[-O feature[,...]] "
@@ -1403,7 +1399,7 @@ profile_error:
 	}
 
 	while ((c = getopt (argc, argv,
-		    "b:cg:i:jl:m:no:qr:s:t:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
+		    "b:cg:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
 		switch (c) {
 		case 'b':
 			blocksize = parse_num_blocks2(optarg, -1);
@@ -1591,6 +1587,9 @@ profile_error:
 		case 'U':
 			fs_uuid = optarg;
 			break;
+		case 'd':
+			root_dir = optarg;
+			break;
 		case 'v':
 			verbose = 1;
 			break;
@@ -2798,6 +2797,21 @@ no_journal:
 				       EXT4_FEATURE_RO_COMPAT_QUOTA))
 		create_quota_inodes(fs);
 
+	/* Copy files from the specified directory */
+	if (root_dir) {
+		if (!quiet)
+			printf("%s", _("Copying files into the device: "));
+
+		current_fs = fs;
+		root = EXT2_ROOT_INO;
+		retval = populate_fs(root, root_dir);
+		if (retval)
+			fprintf(stderr, "%s",
+				_("\nError while populating %s"), root_dir);
+		else if (!quiet)
+			printf("%s", _("done\n"));
+	}
+
 	if (!quiet)
 		printf("%s", _("Writing superblocks and "
 		       "filesystem accounting information: "));
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 02/10] misc/create_inode.c: copy files recursively
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
  2013-12-23 12:09 ` [PATCH 01/10] mke2fs.c: " Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 12:09 ` [PATCH 03/10] misc/create_inode.c: create special file Robert Yang
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

Use opendir() and readdir() to read the native directory, then use
lstat() to identify the file type and call the corresponding function to
add the file to the filesystem, call the populate_fs() recursively if it
is a directory.

NOTE: the libext2fs can't create the socket file.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   90 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 90 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 46aaa60..275d3f0 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -23,4 +23,94 @@ errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
 /* Copy files from source_dir to fs */
 errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
 {
+	const char	*name;
+	DIR		*dh;
+	struct dirent	*dent;
+	struct stat	st;
+	char		ln_target[PATH_MAX];
+	char		*func_name = "populate_fs";
+	ext2_ino_t	ino;
+	errcode_t	retval;
+	int		read_cnt;
+
+	root = EXT2_ROOT_INO;
+
+	if (chdir(source_dir) < 0) {
+		com_err(func_name, errno,
+			_("while changing working directory to \"%s\""), source_dir);
+		return errno;
+	}
+
+	if (!(dh = opendir("."))) {
+		com_err(func_name, errno,
+			_("while openning directory \"%s\""), source_dir);
+		return errno;
+	}
+
+	while((dent = readdir(dh))) {
+		if((!strcmp(dent->d_name, ".")) || (!strcmp(dent->d_name, "..")))
+			continue;
+		lstat(dent->d_name, &st);
+		name = dent->d_name;
+
+		switch(st.st_mode & S_IFMT) {
+			case S_IFCHR:
+			case S_IFBLK:
+			case S_IFIFO:
+				if ((retval = do_mknod_internal(parent_ino, name, &st))) {
+					com_err(func_name, retval,
+						_("while creating special file \"%s\""), name);
+					return retval;
+				}
+				break;
+			case S_IFSOCK:
+				/* FIXME: there is no make sockect function atm. */
+				com_err(func_name, 0,
+					_("ignoring sockect file\"%s\""), name);
+				break;
+			case S_IFLNK:
+				if((read_cnt = readlink(name, ln_target, sizeof(ln_target))) == -1) {
+					com_err(func_name, errno,
+						_("while trying to readlink \"%s\""), name);
+					return errno;
+				}
+				ln_target[read_cnt] = '\0';
+				if ((retval = do_symlink_internal(parent_ino, name, ln_target))) {
+					com_err(func_name, retval,
+						_("while writing symlink\"%s\""), name);
+					return retval;
+				}
+				break;
+			case S_IFREG:
+				if ((retval = do_write_internal(parent_ino, name, name))) {
+					com_err(func_name, retval,
+						_("while writing file \"%s\""), name);
+					return retval;
+				}
+				break;
+			case S_IFDIR:
+				if ((retval = do_mkdir_internal(parent_ino, name, &st))) {
+					com_err(func_name, retval,
+						_("while making dir \"%s\""), name);
+					return retval;
+				}
+				if ((retval = ext2fs_namei(current_fs, root, parent_ino, name, &ino))) {
+					com_err(name, retval, 0);
+						return retval;
+				}
+				/* Populate the dir recursively*/
+				retval = populate_fs(ino, name);
+				if (retval) {
+					com_err(func_name, retval, _("while adding dir \"%s\""), name);
+					return retval;
+				}
+				chdir("..");
+				break;
+			default:
+				com_err(func_name, 0,
+					_("ignoring entry \"%s\""), name);
+		}
+	}
+	closedir(dh);
+	return retval;
 }
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 03/10] misc/create_inode.c: create special file
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
  2013-12-23 12:09 ` [PATCH 01/10] mke2fs.c: " Robert Yang
  2013-12-23 12:09 ` [PATCH 02/10] misc/create_inode.c: copy files recursively Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 12:09 ` [PATCH 04/10] misc/create_inode.c: create symlink Robert Yang
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

The do_mknod_internal() is used for creating special file which is
block, character and fifo, most of the code are from debugfs/debugfs.c,
the debugfs/debugfs.c will be modified to use this function.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   73 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 275d3f0..62a40de 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -3,6 +3,79 @@
 /* Make a special file which is block, character and fifo */
 errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 {
+	ext2_ino_t		ino;
+	errcode_t 		retval;
+	struct ext2_inode	inode;
+	char			*func_name = "do_mknod_internal";
+	unsigned long		major, minor, 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;
+	}
+
+	if (!(current_fs->flags & EXT2_FLAG_RW)) {
+		com_err(func_name, 0, "Filesystem opened read/only");
+		return -1;
+	}
+	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &ino);
+	if (retval) {
+		com_err(func_name, retval, 0);
+		return retval;
+	}
+
+#ifdef DEBUGFS
+	printf("Allocated inode: %u\n", ino);
+#endif
+	retval = ext2fs_link(current_fs, cwd, name, ino, filetype);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(current_fs, cwd);
+		if (retval) {
+			com_err(func_name, retval, "while expanding directory");
+			return retval;
+		}
+		retval = ext2fs_link(current_fs, cwd, name, ino, filetype);
+	}
+	if (retval) {
+		com_err(name, retval, 0);
+		return -1;
+	}
+        if (ext2fs_test_inode_bitmap2(current_fs->inode_map, ino))
+		com_err(func_name, 0, "Warning: inode already set");
+	ext2fs_inode_alloc_stats2(current_fs, ino, +1, 0);
+	memset(&inode, 0, sizeof(inode));
+	inode.i_mode = mode;
+	inode.i_atime = inode.i_ctime = inode.i_mtime =
+		current_fs->now ? current_fs->now : time(0);
+
+	major = major(st->st_rdev);
+	minor = minor(st->st_rdev);
+
+	if ((major < 256) && (minor < 256)) {
+		inode.i_block[0] = major * 256 + minor;
+		inode.i_block[1] = 0;
+	} else {
+		inode.i_block[0] = 0;
+		inode.i_block[1] = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
+	}
+	inode.i_links_count = 1;
+
+	retval = ext2fs_write_new_inode(current_fs, ino, &inode);
+	if (retval)
+		com_err(func_name, retval, "while creating inode %u", ino);
+
+	return retval;
 }
 
 /* Make a symlink name -> target */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 04/10] misc/create_inode.c: create symlink
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (2 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 03/10] misc/create_inode.c: create special file Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 19:27   ` Darren Hart
  2013-12-23 12:09 ` [PATCH 05/10] misc/create_inode.c: copy regular file Robert Yang
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

The do_symlink_internal() is used for creating symlinks, most of the
code are from debugfs/debugfs.c, the debugfs/debugfs.c will be modified
to use this function.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 62a40de..45c8a87 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -81,6 +81,40 @@ errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 /* Make a symlink name -> target */
 errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target)
 {
+	char			*cp;
+	ext2_ino_t		parent_ino;
+	errcode_t		retval;
+	struct ext2_inode	inode;
+	struct stat		st;
+
+	cp = strrchr(name, '/');
+	if (cp) {
+		*cp = 0;
+		if ((retval =  ext2fs_namei(current_fs, root, cwd, name, &parent_ino))){
+			com_err(name, retval, 0);
+			return retval;
+		}
+		name = cp+1;
+	} else {
+		parent_ino = cwd;
+		name = name;
+	}
+
+try_again:
+	retval = ext2fs_symlink(current_fs, parent_ino, 0, name, target);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(current_fs, parent_ino);
+		if (retval) {
+			com_err("do_symlink_internal", retval, "while expanding directory");
+			return retval;
+		}
+		goto try_again;
+	}
+	if (retval) {
+		com_err("ext2fs_symlink", retval, 0);
+		return retval;
+	}
+
 }
 
 /* Make a directory in the fs */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 05/10] misc/create_inode.c: copy regular file
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (3 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 04/10] misc/create_inode.c: create symlink Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 19:32   ` Darren Hart
  2013-12-23 12:09 ` [PATCH 06/10] misc/create_inode.c: create directory Robert Yang
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

The do_write_internal() is used for copying file from native fs to
target, most of the code are from debugfs/debugfs.c, the
debugfs/debugfs.c will be modified to use this function.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |  184 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 184 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 45c8a87..718d499 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -1,5 +1,15 @@
 #include "create_inode.h"
 
+/* 64KiB is the minimium blksize to best minimize system call overhead. */
+#ifndef IO_BUFSIZE
+#define IO_BUFSIZE 64*1024
+#endif
+
+/* Block size for `st_blocks' */
+#ifndef S_BLKSIZE
+#define S_BLKSIZE 512
+#endif
+
 /* Make a special file which is block, character and fifo */
 errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 {
@@ -122,9 +132,183 @@ errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 {
 }
 
+static errcode_t copy_file(int fd, ext2_ino_t newfile, int bufsize, int make_holes)
+{
+	ext2_file_t	e2_file;
+	errcode_t	retval;
+	int		got;
+	unsigned int	written;
+	char		*buf;
+	char		*ptr;
+	char		*zero_buf;
+	int		cmp;
+
+	retval = ext2fs_file_open(current_fs, newfile,
+				  EXT2_FILE_WRITE, &e2_file);
+	if (retval)
+		return retval;
+
+	retval = ext2fs_get_mem(bufsize, &buf);
+	if (retval) {
+		com_err("copy_file", retval, "can't allocate buffer\n");
+		return retval;
+	}
+
+	/* This is used for checking whether the whole block is zero */
+	retval = ext2fs_get_memzero(bufsize, &zero_buf);
+	if (retval) {
+		com_err("copy_file", retval, "can't allocate buffer\n");
+		ext2fs_free_mem(&buf);
+		return retval;
+	}
+
+	while (1) {
+		got = read(fd, buf, bufsize);
+		if (got == 0)
+			break;
+		if (got < 0) {
+			retval = errno;
+			goto fail;
+		}
+		ptr = buf;
+
+		/* Sparse copy */
+		if (make_holes) {
+			/* Check whether all is zero */
+			cmp = memcmp(ptr, zero_buf, got);
+			if (cmp == 0) {
+				 /* The whole block is zero, make a hole */
+				retval = ext2fs_file_lseek(e2_file, got, EXT2_SEEK_CUR, NULL);
+				if (retval)
+					goto fail;
+				got = 0;
+			}
+		}
+
+		/* Normal copy */
+		while (got > 0) {
+			retval = ext2fs_file_write(e2_file, ptr,
+						   got, &written);
+			if (retval)
+				goto fail;
+
+			got -= written;
+			ptr += written;
+		}
+	}
+	ext2fs_free_mem(&buf);
+	ext2fs_free_mem(&zero_buf);
+	retval = ext2fs_file_close(e2_file);
+	return retval;
+
+fail:
+	ext2fs_free_mem(&buf);
+	ext2fs_free_mem(&zero_buf);
+	(void) ext2fs_file_close(e2_file);
+	return retval;
+}
+
 /* Copy the native file to the fs */
 errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
 {
+	int		fd;
+	struct stat	statbuf;
+	ext2_ino_t	newfile;
+	errcode_t	retval;
+	struct ext2_inode inode;
+	int		bufsize = IO_BUFSIZE;
+	int		make_holes = 0;
+	char		*func_name = "do_write_internal";
+
+	fd = open(src, O_RDONLY);
+	if (fd < 0) {
+		com_err(src, errno, 0);
+		return errno;
+	}
+	if (fstat(fd, &statbuf) < 0) {
+		com_err(src, errno, 0);
+		close(fd);
+		return errno;
+	}
+
+	retval = ext2fs_namei(current_fs, root, cwd, dest, &newfile);
+	if (retval == 0) {
+		com_err(func_name, 0, "The file '%s' already exists\n", dest);
+		close(fd);
+		return errno;
+	}
+
+	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
+	if (retval) {
+		com_err(func_name, retval, 0);
+		close(fd);
+		return errno;
+	}
+#ifdef DEBUGFS
+	printf("Allocated inode: %u\n", newfile);
+#endif
+	retval = ext2fs_link(current_fs, cwd, dest, newfile,
+				EXT2_FT_REG_FILE);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(current_fs, cwd);
+		if (retval) {
+			com_err(func_name, retval, "while expanding directory");
+			close(fd);
+			return errno;
+		}
+		retval = ext2fs_link(current_fs, cwd, dest, newfile,
+					EXT2_FT_REG_FILE);
+	}
+	if (retval) {
+		com_err(dest, retval, 0);
+		close(fd);
+		return errno;
+	}
+        if (ext2fs_test_inode_bitmap2(current_fs->inode_map, newfile))
+		com_err(func_name, 0, "Warning: inode already set");
+	ext2fs_inode_alloc_stats2(current_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 =
+		current_fs->now ? current_fs->now : time(0);
+	inode.i_links_count = 1;
+	inode.i_size = statbuf.st_size;
+	if (current_fs->super->s_feature_incompat &
+	    EXT3_FEATURE_INCOMPAT_EXTENTS) {
+		int i;
+		struct ext3_extent_header *eh;
+
+		eh = (struct ext3_extent_header *) &inode.i_block[0];
+		eh->eh_depth = 0;
+		eh->eh_entries = 0;
+		eh->eh_magic = EXT3_EXT_MAGIC;
+		i = (sizeof(inode.i_block) - sizeof(*eh)) /
+			sizeof(struct ext3_extent);
+		eh->eh_max = ext2fs_cpu_to_le16(i);
+		inode.i_flags |= EXT4_EXTENTS_FL;
+	}
+
+	if ((retval = ext2fs_write_new_inode(current_fs, newfile, &inode))) {
+		com_err(func_name, retval, "while creating inode %u", newfile);
+		close(fd);
+		return errno;
+	}
+	if (LINUX_S_ISREG(inode.i_mode)) {
+		if (statbuf.st_blocks < statbuf.st_size / S_BLKSIZE) {
+			make_holes = 1;
+			/*
+			 * Use I/O blocksize as buffer size when
+			 * copying sparse files.
+			 */
+			bufsize = statbuf.st_blksize;
+		}
+		retval = copy_file(fd, newfile, bufsize, make_holes);
+		if (retval)
+			com_err("copy_file", retval, 0);
+	}
+	close(fd);
+
+	return 0;
 }
 
 /* Copy files from source_dir to fs */
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 06/10] misc/create_inode.c: create directory
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (4 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 05/10] misc/create_inode.c: copy regular file Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 19:35   ` Darren Hart
  2013-12-23 12:09 ` [PATCH 07/10] misc/create_inode.c: set owner/mode/time for the inode Robert Yang
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

The do_mkdir_internal() is used for making dir on the target fs, most of
the code are from debugfs/debugfs.c, the debugfs/debugfs.c will be
modified to use this function.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   34 ++++++++++++++++++++++++++++++++++
 1 file changed, 34 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 718d499..95acffe 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -130,6 +130,40 @@ try_again:
 /* Make a directory in the fs */
 errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 {
+	char			*cp;
+	ext2_ino_t		parent_ino, ino;
+	errcode_t		retval;
+	struct ext2_inode	inode;
+	char			*func_name = "do_mkdir_internal";
+
+
+	cp = strrchr(name, '/');
+	if (cp) {
+		*cp = 0;
+		if ((retval =  ext2fs_namei(current_fs, root, cwd, name, &parent_ino))){
+			com_err(name, retval, 0);
+			return retval;
+		}
+		name = cp+1;
+	} else {
+		parent_ino = cwd;
+		name = name;
+	}
+
+try_again:
+	retval = ext2fs_mkdir(current_fs, parent_ino, 0, name);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(current_fs, parent_ino);
+		if (retval) {
+			com_err(func_name, retval, "while expanding directory");
+			return retval;
+		}
+		goto try_again;
+	}
+	if (retval) {
+		com_err("ext2fs_mkdir", retval, 0);
+		return retval;
+	}
 }
 
 static errcode_t copy_file(int fd, ext2_ino_t newfile, int bufsize, int make_holes)
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 07/10] misc/create_inode.c: set owner/mode/time for the inode
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (5 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 06/10] misc/create_inode.c: create directory Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 12:09 ` [PATCH 08/10] misc/create_inode.c: handle hardlinks Robert Yang
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

Set the uid, gid, mode and time for inode.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 46 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index 95acffe..afe8567 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -10,6 +10,41 @@
 #define S_BLKSIZE 512
 #endif
 
+/* Fill the uid, gid, mode and time for the inode */
+static void fill_inode(struct ext2_inode *inode, struct stat *st)
+{
+	if (st != NULL) {
+		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;
+	}
+}
+
+/* Set the uid, gid, mode and time for the inode */
+errcode_t set_inode_extra(ext2_ino_t cwd, ext2_ino_t ino, struct stat *st)
+{
+	errcode_t		retval;
+	struct ext2_inode	inode;
+	char			*func_name = "set_inode_extra";
+
+	retval = ext2fs_read_inode(current_fs, ino, &inode);
+        if (retval) {
+		com_err(func_name, retval, "while reading inode %u", ino);
+		return retval;
+	}
+
+	fill_inode(&inode, st);
+
+	retval = ext2fs_write_inode(current_fs, ino, &inode);
+	if (retval) {
+		com_err(func_name, retval, "while writing inode %u", ino);
+		return retval;
+	}
+}
+
 /* Make a special file which is block, character and fifo */
 errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
 {
@@ -435,6 +470,17 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
 				com_err(func_name, 0,
 					_("ignoring entry \"%s\""), name);
 		}
+
+		if ((retval =  ext2fs_namei(current_fs, root, parent_ino, name, &ino))){
+			com_err(name, retval, 0);
+			return retval;
+		}
+
+		if ((retval = set_inode_extra(parent_ino, ino, &st))) {
+			com_err(func_name, retval,
+				_("while setting inode for \"%s\""), name);
+			return retval;
+		}
 	}
 	closedir(dh);
 	return retval;
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 08/10] misc/create_inode.c: handle hardlinks
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (6 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 07/10] misc/create_inode.c: set owner/mode/time for the inode Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 12:09 ` [PATCH 09/10] debugfs: use the functions in misc/create_inode.c Robert Yang
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

Create the inode and save the native inode number when we meet the hard
link (st_nlink > 1) at the first time, use ext2fs_link() to link the
name to the target inode number when we meet the same native inode
number again.

This algorithm is referred this from the genext2fs.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/create_inode.c |   88 +++++++++++++++++++++++++++++++++++++++++++++++++++
 misc/create_inode.h |   18 +++++++++++
 misc/mke2fs.c       |   11 +++++++
 3 files changed, 117 insertions(+)

diff --git a/misc/create_inode.c b/misc/create_inode.c
index afe8567..d21a808 100644
--- a/misc/create_inode.c
+++ b/misc/create_inode.c
@@ -10,6 +10,45 @@
 #define S_BLKSIZE 512
 #endif
 
+/* For saving the hard links */
+int hdlink_cnt = HDLINK_CNT;
+
+/* Link an inode number to a directory */
+static errcode_t add_link(ext2_ino_t parent_ino, ext2_ino_t ino, const char *name)
+{
+	struct ext2_inode	inode;
+	errcode_t		retval;
+	char			*func_name = "add_to_dir";
+
+	retval = ext2fs_read_inode(current_fs, ino, &inode);
+        if (retval) {
+		com_err(func_name, retval, "while reading inode %u", ino);
+		return retval;
+	}
+
+	retval = ext2fs_link(current_fs, parent_ino, name, ino, inode.i_flags);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(current_fs, parent_ino);
+		if (retval) {
+			com_err(func_name, retval, "while expanding directory");
+			return retval;
+		}
+		retval = ext2fs_link(current_fs, parent_ino, name, ino, inode.i_flags);
+	}
+	if (retval) {
+		com_err(func_name, retval, "while linking %s", name);
+		return retval;
+	}
+
+	inode.i_links_count++;
+
+	retval = ext2fs_write_inode(current_fs, ino, &inode);
+	if (retval)
+		com_err(func_name, retval, "while writing inode %u", ino);
+
+	return retval;
+}
+
 /* Fill the uid, gid, mode and time for the inode */
 static void fill_inode(struct ext2_inode *inode, struct stat *st)
 {
@@ -277,6 +316,17 @@ fail:
 	return retval;
 }
 
+int is_hardlink(ext2_ino_t ino)
+{
+	int i;
+
+	for(i = 0; i < hdlinks.count; i++) {
+		if(hdlinks.hdl[i].src_ino == ino)
+			return i;
+	}
+	return -1;
+}
+
 /* Copy the native file to the fs */
 errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
 {
@@ -388,10 +438,12 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
 	struct dirent	*dent;
 	struct stat	st;
 	char		ln_target[PATH_MAX];
+	unsigned int	save_inode = 0;
 	char		*func_name = "populate_fs";
 	ext2_ino_t	ino;
 	errcode_t	retval;
 	int		read_cnt;
+	int		hdlink;
 
 	root = EXT2_ROOT_INO;
 
@@ -413,6 +465,21 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
 		lstat(dent->d_name, &st);
 		name = dent->d_name;
 
+		/* Check for hardlinks */
+		if (!S_ISDIR(st.st_mode) && !S_ISLNK(st.st_mode) && st.st_nlink > 1) {
+			hdlink = is_hardlink(st.st_ino);
+			if (hdlink >= 0) {
+				retval = add_link(parent_ino,
+						hdlinks.hdl[hdlink].dst_ino, name);
+				if (retval) {
+					com_err(func_name, retval, "while linking %s", name);
+					return retval;
+				}
+				continue;
+			} else
+				save_inode = 1;
+		}
+
 		switch(st.st_mode & S_IFMT) {
 			case S_IFCHR:
 			case S_IFBLK:
@@ -481,6 +548,27 @@ errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
 				_("while setting inode for \"%s\""), name);
 			return retval;
 		}
+
+		/* 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 == hdlink_cnt) {
+				if ((hdlinks.hdl = realloc (hdlinks.hdl,
+						(hdlink_cnt + HDLINK_CNT) *
+						sizeof (struct hdlink_s))) == NULL) {
+					com_err(name, errno, "Not enough memory");
+					return errno;
+				}
+				hdlink_cnt += HDLINK_CNT;
+			}
+			hdlinks.hdl[hdlinks.count].src_ino = st.st_ino;
+			hdlinks.hdl[hdlinks.count].dst_ino = ino;
+			hdlinks.count++;
+		}
 	}
 	closedir(dh);
 	return retval;
diff --git a/misc/create_inode.h b/misc/create_inode.h
index 9fc97fa..2b6d429 100644
--- a/misc/create_inode.h
+++ b/misc/create_inode.h
@@ -6,9 +6,27 @@
 #include "ext2fs/ext2fs.h"
 #include "nls-enable.h"
 
+struct hdlink_s
+{
+	ext2_ino_t src_ino;
+	ext2_ino_t dst_ino;
+};
+
+struct hdlinks_s
+{
+	int count;
+	struct hdlink_s *hdl;
+};
+
+struct hdlinks_s hdlinks;
+
 ext2_filsys    current_fs;
 ext2_ino_t     root;
 
+/* For saving the hard links */
+#define HDLINK_CNT     4
+extern int hdlink_cnt;
+
 /* For populating the filesystem */
 extern errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir);
 extern errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st);
diff --git a/misc/mke2fs.c b/misc/mke2fs.c
index eab5463..0f734cc 100644
--- a/misc/mke2fs.c
+++ b/misc/mke2fs.c
@@ -2802,6 +2802,17 @@ no_journal:
 		if (!quiet)
 			printf("%s", _("Copying files into the device: "));
 
+		/*
+		 * Allocate memory for the hardlinks, we don't need free()
+		 * since the lifespan will be over after the fs populated.
+		 */
+		if ((hdlinks.hdl = (struct hdlink_s *)
+				malloc(hdlink_cnt * sizeof(struct hdlink_s))) == NULL) {
+			fprintf(stderr, "%s", _("\nNot enough memory\n"));
+			retval = ext2fs_close(fs);
+			return retval;
+		}
+
 		current_fs = fs;
 		root = EXT2_ROOT_INO;
 		retval = populate_fs(root, root_dir);
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 09/10] debugfs: use the functions in misc/create_inode.c
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (7 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 08/10] misc/create_inode.c: handle hardlinks Robert Yang
@ 2013-12-23 12:09 ` Robert Yang
  2013-12-23 12:10 ` [PATCH 10/10] mke2fs.8.in: update the manual for the -d option Robert Yang
  2013-12-23 19:05 ` [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Darren Hart
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:09 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

* Use the functions in misc/create_inode.c, and remove the duplicated
  code.

* The CREATE_INODE_DEPS in the debugfs/Makefile.in is used for recording
  create_inode.o's depends which is from misc/Makefile.in, we have to
  recompile create_inode.o because we need it to print more messages when
  it is used by debugfs, just like we recompile e2freefrag.o, but it seems
  that the e2freefrag.o's depends in debugfs/Makefile.in is incorrect, it
  would not rebuild when its depends (e.g.: lib/config.h) is changed,
  which would cause unexpected errors. Make duplicated code in
  debugfs/Makefile.in and misc/Makefile.in is not a good idea, maybe we'd
  better define CREATE_INODE_DEPS in the top Makefile, I'd like to send
  another patch and fix the e2freefrag if you are fine with it.

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 debugfs/Makefile.in |   17 ++-
 debugfs/debugfs.c   |  305 +++------------------------------------------------
 debugfs/debugfs.h   |    1 +
 3 files changed, 31 insertions(+), 292 deletions(-)

diff --git a/debugfs/Makefile.in b/debugfs/Makefile.in
index bf037e0..f51b78e 100644
--- a/debugfs/Makefile.in
+++ b/debugfs/Makefile.in
@@ -18,7 +18,7 @@ MK_CMDS=	_SS_DIR_OVERRIDE=../lib/ss ../lib/ss/mk_cmds
 
 DEBUG_OBJS= debug_cmds.o debugfs.o util.o ncheck.o icheck.o ls.o \
 	lsdel.o dump.o set_fields.o logdump.o htree.o unused.o e2freefrag.o \
-	filefrag.o extent_cmds.o extent_inode.o zap.o
+	filefrag.o extent_cmds.o extent_inode.o zap.o create_inode.o
 
 RO_DEBUG_OBJS= ro_debug_cmds.o ro_debugfs.o util.o ncheck.o icheck.o ls.o \
 	lsdel.o logdump.o htree.o e2freefrag.o filefrag.o extent_cmds.o \
@@ -28,7 +28,13 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $(srcdir)/util.c $(srcdir)/ls.c \
 	$(srcdir)/ncheck.c $(srcdir)/icheck.c $(srcdir)/lsdel.c \
 	$(srcdir)/dump.c $(srcdir)/set_fields.c ${srcdir}/logdump.c \
 	$(srcdir)/htree.c $(srcdir)/unused.c ${srcdir}/../misc/e2freefrag.c \
-	$(srcdir)/filefrag.c $(srcdir)/extent_inode.c $(srcdir)/zap.c
+	$(srcdir)/filefrag.c $(srcdir)/extent_inode.c $(srcdir)/zap.c \
+	$(srcdir)/../misc/create_inode.c
+
+CREATE_INODE_DEPS= $(srcdir)/../misc/create_inode.h \
+	$(srcdir)/../misc/create_inode.c $(top_builddir)/lib/config.h \
+	$(srcdir)/../lib/ext2fs/ext2fs.h $(srcdir)/../lib/et/com_err.h \
+	$(srcdir)/../lib/e2p/e2p.h $(srcdir)/../misc/nls-enable.h
 
 LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \
 	$(LIBUUID)
@@ -81,6 +87,11 @@ e2freefrag.o: $(srcdir)/../misc/e2freefrag.c
 	$(E) "	CC $@"
 	$(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) $< -DDEBUGFS -o $@
 
+create_inode.o: $(CREATE_INODE_DEPS)
+	$(E) "	CC $@"
+	$(Q) $(CC) -c $(ALL_CFLAGS) -I$(srcdir) \
+		 $(srcdir)/../misc/create_inode.c -DDEBUGFS -o $@
+
 debugfs.8: $(DEP_SUBSTITUTE) $(srcdir)/debugfs.8.in
 	$(E) "	SUBST $@"
 	$(Q) $(SUBSTITUTE_UPTIME) $(srcdir)/debugfs.8.in debugfs.8
@@ -142,7 +153,7 @@ debugfs.o: $(srcdir)/debugfs.c $(top_srcdir)/lib/et/com_err.h \
  $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
  $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/version.h $(srcdir)/jfs_user.h \
  $(top_srcdir)/lib/ext2fs/kernel-jbd.h $(top_srcdir)/lib/ext2fs/jfs_compat.h \
- $(top_srcdir)/lib/ext2fs/kernel-list.h
+ $(top_srcdir)/lib/ext2fs/kernel-list.h $(top_srcdir)/misc/util.h
 util.o: $(srcdir)/util.c $(srcdir)/debugfs.h \
  $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
  $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
diff --git a/debugfs/debugfs.c b/debugfs/debugfs.c
index 578d577..f5ff7fd 100644
--- a/debugfs/debugfs.c
+++ b/debugfs/debugfs.c
@@ -25,8 +25,6 @@ extern char *optarg;
 #include <errno.h>
 #endif
 #include <fcntl.h>
-#include <sys/types.h>
-#include <sys/stat.h>
 
 #include "debugfs.h"
 #include "uuid/uuid.h"
@@ -41,22 +39,11 @@ extern char *optarg;
 #define BUFSIZ 8192
 #endif
 
-/* 64KiB is the minimium blksize to best minimize system call overhead. */
-#ifndef IO_BUFSIZE
-#define IO_BUFSIZE 64*1024
-#endif
-
-/* Block size for `st_blocks' */
-#ifndef S_BLKSIZE
-#define S_BLKSIZE 512
-#endif
-
 ss_request_table *extra_cmds;
 const char *debug_prog_name;
 int sci_idx;
 
-ext2_filsys	current_fs = NULL;
-ext2_ino_t	root, cwd;
+ext2_ino_t	cwd;
 
 static void open_filesystem(char *device, int open_flags, blk64_t superblock,
 			    blk64_t blocksize, int catastrophic,
@@ -1588,189 +1575,24 @@ void do_find_free_inode(int argc, char *argv[])
 }
 
 #ifndef READ_ONLY
-static errcode_t copy_file(int fd, ext2_ino_t newfile, int bufsize, int make_holes)
-{
-	ext2_file_t	e2_file;
-	errcode_t	retval;
-	int		got;
-	unsigned int	written;
-	char		*buf;
-	char		*ptr;
-	char		*zero_buf;
-	int		cmp;
-
-	retval = ext2fs_file_open(current_fs, newfile,
-				  EXT2_FILE_WRITE, &e2_file);
-	if (retval)
-		return retval;
-
-	retval = ext2fs_get_mem(bufsize, &buf);
-	if (retval) {
-		com_err("copy_file", retval, "can't allocate buffer\n");
-		return retval;
-	}
-
-	/* This is used for checking whether the whole block is zero */
-	retval = ext2fs_get_memzero(bufsize, &zero_buf);
-	if (retval) {
-		com_err("copy_file", retval, "can't allocate buffer\n");
-		ext2fs_free_mem(&buf);
-		return retval;
-	}
-
-	while (1) {
-		got = read(fd, buf, bufsize);
-		if (got == 0)
-			break;
-		if (got < 0) {
-			retval = errno;
-			goto fail;
-		}
-		ptr = buf;
-
-		/* Sparse copy */
-		if (make_holes) {
-			/* Check whether all is zero */
-			cmp = memcmp(ptr, zero_buf, got);
-			if (cmp == 0) {
-				 /* The whole block is zero, make a hole */
-				retval = ext2fs_file_lseek(e2_file, got, EXT2_SEEK_CUR, NULL);
-				if (retval)
-					goto fail;
-				got = 0;
-			}
-		}
-
-		/* Normal copy */
-		while (got > 0) {
-			retval = ext2fs_file_write(e2_file, ptr,
-						   got, &written);
-			if (retval)
-				goto fail;
-
-			got -= written;
-			ptr += written;
-		}
-	}
-	ext2fs_free_mem(&buf);
-	ext2fs_free_mem(&zero_buf);
-	retval = ext2fs_file_close(e2_file);
-	return retval;
-
-fail:
-	ext2fs_free_mem(&buf);
-	ext2fs_free_mem(&zero_buf);
-	(void) ext2fs_file_close(e2_file);
-	return retval;
-}
-
-
 void do_write(int argc, char *argv[])
 {
-	int		fd;
-	struct stat	statbuf;
-	ext2_ino_t	newfile;
 	errcode_t	retval;
-	struct ext2_inode inode;
-	int		bufsize = IO_BUFSIZE;
-	int		make_holes = 0;
 
 	if (common_args_process(argc, argv, 3, 3, "write",
 				"<native file> <new file>", CHECK_FS_RW))
 		return;
 
-	fd = open(argv[1], O_RDONLY);
-	if (fd < 0) {
-		com_err(argv[1], errno, 0);
-		return;
-	}
-	if (fstat(fd, &statbuf) < 0) {
-		com_err(argv[1], errno, 0);
-		close(fd);
-		return;
-	}
-
-	retval = ext2fs_namei(current_fs, root, cwd, argv[2], &newfile);
-	if (retval == 0) {
-		com_err(argv[0], 0, "The file '%s' already exists\n", argv[2]);
-		close(fd);
-		return;
-	}
-
-	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
-	if (retval) {
+	if ((retval = do_write_internal(cwd, argv[1], argv[2])))
 		com_err(argv[0], retval, 0);
-		close(fd);
-		return;
-	}
-	printf("Allocated inode: %u\n", newfile);
-	retval = ext2fs_link(current_fs, cwd, argv[2], newfile,
-			     EXT2_FT_REG_FILE);
-	if (retval == EXT2_ET_DIR_NO_SPACE) {
-		retval = ext2fs_expand_dir(current_fs, cwd);
-		if (retval) {
-			com_err(argv[0], retval, "while expanding directory");
-			close(fd);
-			return;
-		}
-		retval = ext2fs_link(current_fs, cwd, argv[2], newfile,
-				     EXT2_FT_REG_FILE);
-	}
-	if (retval) {
-		com_err(argv[2], retval, 0);
-		close(fd);
-		return;
-	}
-        if (ext2fs_test_inode_bitmap2(current_fs->inode_map,newfile))
-		com_err(argv[0], 0, "Warning: inode already set");
-	ext2fs_inode_alloc_stats2(current_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 =
-		current_fs->now ? current_fs->now : time(0);
-	inode.i_links_count = 1;
-	inode.i_size = statbuf.st_size;
-	if (current_fs->super->s_feature_incompat &
-	    EXT3_FEATURE_INCOMPAT_EXTENTS) {
-		int i;
-		struct ext3_extent_header *eh;
-
-		eh = (struct ext3_extent_header *) &inode.i_block[0];
-		eh->eh_depth = 0;
-		eh->eh_entries = 0;
-		eh->eh_magic = EXT3_EXT_MAGIC;
-		i = (sizeof(inode.i_block) - sizeof(*eh)) /
-			sizeof(struct ext3_extent);
-		eh->eh_max = ext2fs_cpu_to_le16(i);
-		inode.i_flags |= EXT4_EXTENTS_FL;
-	}
-	if (debugfs_write_new_inode(newfile, &inode, argv[0])) {
-		close(fd);
-		return;
-	}
-	if (LINUX_S_ISREG(inode.i_mode)) {
-		if (statbuf.st_blocks < statbuf.st_size / S_BLKSIZE) {
-			make_holes = 1;
-			/*
-			 * Use I/O blocksize as buffer size when
-			 * copying sparse files.
-			 */
-			bufsize = statbuf.st_blksize;
-		}
-		retval = copy_file(fd, newfile, bufsize, make_holes);
-		if (retval)
-			com_err("copy_file", retval, 0);
-	}
-	close(fd);
 }
 
 void do_mknod(int argc, char *argv[])
 {
 	unsigned long	mode, major, minor;
-	ext2_ino_t	newfile;
 	errcode_t 	retval;
-	struct ext2_inode inode;
 	int		filetype, nr;
+	struct stat	st;
 
 	if (check_fs_open(argv[0]))
 		return;
@@ -1779,115 +1601,50 @@ void do_mknod(int argc, char *argv[])
 		com_err(argv[0], 0, "Usage: mknod <name> [p| [c|b] <major> <minor>]");
 		return;
 	}
+
 	mode = minor = major = 0;
 	switch (argv[2][0]) {
 		case 'p':
-			mode = LINUX_S_IFIFO;
-			filetype = EXT2_FT_FIFO;
+			st.st_mode = S_IFIFO;
 			nr = 3;
 			break;
 		case 'c':
-			mode = LINUX_S_IFCHR;
-			filetype = EXT2_FT_CHRDEV;
+			st.st_mode = S_IFCHR;
 			nr = 5;
 			break;
 		case 'b':
-			mode = LINUX_S_IFBLK;
-			filetype = EXT2_FT_BLKDEV;
+			st.st_mode = S_IFBLK;
 			nr = 5;
 			break;
 		default:
-			filetype = 0;
 			nr = 0;
 	}
+
 	if (nr == 5) {
 		major = strtoul(argv[3], argv+3, 0);
 		minor = strtoul(argv[4], argv+4, 0);
 		if (major > 65535 || minor > 65535 || argv[3][0] || argv[4][0])
 			nr = 0;
 	}
+
 	if (argc != nr)
 		goto usage;
-	if (check_fs_read_write(argv[0]))
-		return;
-	retval = ext2fs_new_inode(current_fs, cwd, 010755, 0, &newfile);
-	if (retval) {
+
+	st.st_rdev = makedev(major, minor);
+	if ((retval = do_mknod_internal(cwd, argv[1], &st)))
 		com_err(argv[0], retval, 0);
-		return;
-	}
-	printf("Allocated inode: %u\n", newfile);
-	retval = ext2fs_link(current_fs, cwd, argv[1], newfile, filetype);
-	if (retval == EXT2_ET_DIR_NO_SPACE) {
-		retval = ext2fs_expand_dir(current_fs, cwd);
-		if (retval) {
-			com_err(argv[0], retval, "while expanding directory");
-			return;
-		}
-		retval = ext2fs_link(current_fs, cwd, argv[1], newfile,
-				     filetype);
-	}
-	if (retval) {
-		com_err(argv[1], retval, 0);
-		return;
-	}
-        if (ext2fs_test_inode_bitmap2(current_fs->inode_map,newfile))
-		com_err(argv[0], 0, "Warning: inode already set");
-	ext2fs_inode_alloc_stats2(current_fs, newfile, +1, 0);
-	memset(&inode, 0, sizeof(inode));
-	inode.i_mode = mode;
-	inode.i_atime = inode.i_ctime = inode.i_mtime =
-		current_fs->now ? current_fs->now : time(0);
-	if ((major < 256) && (minor < 256)) {
-		inode.i_block[0] = major*256+minor;
-		inode.i_block[1] = 0;
-	} else {
-		inode.i_block[0] = 0;
-		inode.i_block[1] = (minor & 0xff) | (major << 8) | ((minor & ~0xff) << 12);
-	}
-	inode.i_links_count = 1;
-	if (debugfs_write_new_inode(newfile, &inode, argv[0]))
-		return;
 }
 
 void do_mkdir(int argc, char *argv[])
 {
-	char	*cp;
-	ext2_ino_t	parent;
-	char	*name;
 	errcode_t retval;
 
 	if (common_args_process(argc, argv, 2, 2, "mkdir",
 				"<filename>", CHECK_FS_RW))
 		return;
 
-	cp = strrchr(argv[1], '/');
-	if (cp) {
-		*cp = 0;
-		parent = string_to_inode(argv[1]);
-		if (!parent) {
-			com_err(argv[1], ENOENT, 0);
-			return;
-		}
-		name = cp+1;
-	} else {
-		parent = cwd;
-		name = argv[1];
-	}
-
-try_again:
-	retval = ext2fs_mkdir(current_fs, parent, 0, name);
-	if (retval == EXT2_ET_DIR_NO_SPACE) {
-		retval = ext2fs_expand_dir(current_fs, parent);
-		if (retval) {
-			com_err(argv[0], retval, "while expanding directory");
-			return;
-		}
-		goto try_again;
-	}
-	if (retval) {
-		com_err("ext2fs_mkdir", retval, 0);
-		return;
-	}
+	if ((retval = do_mkdir_internal(cwd, argv[1], NULL)))
+		com_err(argv[0], retval, 0);
 
 }
 
@@ -2282,44 +2039,14 @@ void do_punch(int argc, char *argv[])
 
 void do_symlink(int argc, char *argv[])
 {
-	char		*cp;
-	ext2_ino_t	parent;
-	char		*name, *target;
 	errcode_t	retval;
 
 	if (common_args_process(argc, argv, 3, 3, "symlink",
 				"<filename> <target>", CHECK_FS_RW))
 		return;
 
-	cp = strrchr(argv[1], '/');
-	if (cp) {
-		*cp = 0;
-		parent = string_to_inode(argv[1]);
-		if (!parent) {
-			com_err(argv[1], ENOENT, 0);
-			return;
-		}
-		name = cp+1;
-	} else {
-		parent = cwd;
-		name = argv[1];
-	}
-	target = argv[2];
-
-try_again:
-	retval = ext2fs_symlink(current_fs, parent, 0, name, target);
-	if (retval == EXT2_ET_DIR_NO_SPACE) {
-		retval = ext2fs_expand_dir(current_fs, parent);
-		if (retval) {
-			com_err(argv[0], retval, "while expanding directory");
-			return;
-		}
-		goto try_again;
-	}
-	if (retval) {
-		com_err("ext2fs_symlink", retval, 0);
-		return;
-	}
+	if ((retval = do_symlink_internal(cwd, argv[1], argv[2])))
+		com_err(argv[0], retval, 0);
 
 }
 
diff --git a/debugfs/debugfs.h b/debugfs/debugfs.h
index 45175cf..457700f 100644
--- a/debugfs/debugfs.h
+++ b/debugfs/debugfs.h
@@ -5,6 +5,7 @@
 #include "ss/ss.h"
 #include "ext2fs/ext2_fs.h"
 #include "ext2fs/ext2fs.h"
+#include "../misc/create_inode.h"
 
 #ifdef __STDC__
 #define NOARGS void
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* [PATCH 10/10] mke2fs.8.in: update the manual for the -d option
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (8 preceding siblings ...)
  2013-12-23 12:09 ` [PATCH 09/10] debugfs: use the functions in misc/create_inode.c Robert Yang
@ 2013-12-23 12:10 ` Robert Yang
  2013-12-23 19:05 ` [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Darren Hart
  10 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-23 12:10 UTC (permalink / raw)
  To: tytso, dvhart; +Cc: linux-ext4

Update the manual for the -d option

Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
---
 misc/mke2fs.8.in |    7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/misc/mke2fs.8.in b/misc/mke2fs.8.in
index df244de..6d7388a 100644
--- a/misc/mke2fs.8.in
+++ b/misc/mke2fs.8.in
@@ -52,6 +52,10 @@ mke2fs \- create an ext2/ext3/ext4 filesystem
 .I number-of-inodes
 ]
 [
+.B \-d
+.I root-directory
+]
+[
 .B \-n
 ]
 [
@@ -490,6 +494,9 @@ the
 ratio).  This allows the user to specify the number
 of desired inodes directly.
 .TP
+.BI \-d " root-directory"
+Add the files from the root-directory to the filesystem.
+.TP
 .BI \-o " creator-os"
 Overrides the default value of the "creator operating system" field of the
 filesystem.  The creator field is set by default to the name of the OS the
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 20+ messages in thread

* Re: [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory
  2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
                   ` (9 preceding siblings ...)
  2013-12-23 12:10 ` [PATCH 10/10] mke2fs.8.in: update the manual for the -d option Robert Yang
@ 2013-12-23 19:05 ` Darren Hart
  10 siblings, 0 replies; 20+ messages in thread
From: Darren Hart @ 2013-12-23 19:05 UTC (permalink / raw)
  To: Robert Yang; +Cc: tytso, linux-ext4

On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> Hi Ted,
> 
> I'm very sorry for the late response, I've fixed the problems which you 
> pointed out in the RFC patches, and now the "make check" works well.
> 
> * Changes from the RFC patches:
>   - Move the common code of debugfs and mke2fs to misc/create_inode.c to
>     avoid bloating the tune2fs binary

Hi Robert,

Can you include a size report before and after the changes. With the
concern over code size, we should document the impact.

--
Darren

>   - Fix the error of "make check"
>   - Rebase to the up to date master branch
> 
> Merry Christmas and Happy New Year!
> 
> // Robert
> 
> Robert Yang (10):
>   mke2fs.c: add an option: -d root-directory
>   misc/create_inode.c: copy files recursively
>   misc/create_inode.c: create special file
>   misc/create_inode.c: create symlink
>   misc/create_inode.c: copy regular file
>   misc/create_inode.c: create directory
>   misc/create_inode.c: set owner/mode/time for the inode
>   misc/create_inode.c: handle hardlinks
>   debugfs: use the functions in misc/create_inode.c
>   mke2fs.8.in: update the manual for the -d option
> 
>  debugfs/Makefile.in |   17 +-
>  debugfs/debugfs.c   |  305 ++-------------------------
>  debugfs/debugfs.h   |    1 +
>  misc/Makefile.in    |   13 +-
>  misc/create_inode.c |  575 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  misc/create_inode.h |   35 ++++
>  misc/mke2fs.8.in    |    7 +
>  misc/mke2fs.c       |   43 +++-
>  8 files changed, 691 insertions(+), 305 deletions(-)
>  create mode 100644 misc/create_inode.c
>  create mode 100644 misc/create_inode.h
> 

-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/10] mke2fs.c: add an option: -d root-directory
  2013-12-23 12:09 ` [PATCH 01/10] mke2fs.c: " Robert Yang
@ 2013-12-23 19:08   ` Darren Hart
  2013-12-24  1:52     ` Robert Yang
  2013-12-26 16:07     ` Theodore Ts'o
  0 siblings, 2 replies; 20+ messages in thread
From: Darren Hart @ 2013-12-23 19:08 UTC (permalink / raw)
  To: Robert Yang; +Cc: tytso, linux-ext4

On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> This option is used for adding the files from a given directory (the
> root-directory) to the filesystem, it is similiar to genext2fs, but
> genext2fs doesn't fully support ext4.
> 
> This commit describes the skeleton of the implementation:

This approach strikes me as a bit odd. We're adding an option and empty
functions, rather than fleshing them out at the same time. What is the
motivation for separating this from the actual implementation? At the
very least the -d option shouldn't be added until it is functional - at
the end of the series...

Ted, was there a recommendation to take this approach - maybe I'm
missing some context?

Thanks,

Darren Hart

> * We already have the basic operations in debugfs:
>   - Copy regular file
>   - Create directory
>   - Create symlink
>   - Create special file
> 
>   We will move these operations into create_inode.h and create_inode.c,
>   then let both mke2fs and debugfs use them.
> 
> * What we need to do are:
>   - Copy the given directory recursively
>   - Set the owner, mode and other informations
>   - Handle the hard links
> 
> TODO:
>   - The libext2fs can't create the socket file (S_IFSOCK), do we have a
>     plan to support it ?
> 
> Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
> ---
>  misc/Makefile.in    |   13 +++++++++----
>  misc/create_inode.c |   26 ++++++++++++++++++++++++++
>  misc/create_inode.h |   17 +++++++++++++++++
>  misc/mke2fs.c       |   32 +++++++++++++++++++++++---------
>  4 files changed, 75 insertions(+), 13 deletions(-)
>  create mode 100644 misc/create_inode.c
>  create mode 100644 misc/create_inode.h
> 
> diff --git a/misc/Makefile.in b/misc/Makefile.in
> index a798f96..da780fe 100644
> --- a/misc/Makefile.in
> +++ b/misc/Makefile.in
> @@ -42,7 +42,7 @@ LPROGS=		@E2INITRD_PROG@
>  
>  TUNE2FS_OBJS=	tune2fs.o util.o
>  MKLPF_OBJS=	mklost+found.o
> -MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o
> +MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o create_inode.o
>  CHATTR_OBJS=	chattr.o
>  LSATTR_OBJS=	lsattr.o
>  UUIDGEN_OBJS=	uuidgen.o
> @@ -60,7 +60,8 @@ E2FREEFRAG_OBJS= e2freefrag.o
>  PROFILED_TUNE2FS_OBJS=	profiled/tune2fs.o profiled/util.o
>  PROFILED_MKLPF_OBJS=	profiled/mklost+found.o
>  PROFILED_MKE2FS_OBJS=	profiled/mke2fs.o profiled/util.o profiled/profile.o \
> -			profiled/prof_err.o profiled/default_profile.o
> +			profiled/prof_err.o profiled/default_profile.o \
> +			profiled/create_inode.o
>  PROFILED_CHATTR_OBJS=	profiled/chattr.o
>  PROFILED_LSATTR_OBJS=	profiled/lsattr.o
>  PROFILED_UUIDGEN_OBJS=	profiled/uuidgen.o
> @@ -82,7 +83,7 @@ SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
>  		$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
>  		$(srcdir)/filefrag.c $(srcdir)/base_device.c \
>  		$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
> -		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c
> +		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c
>  
>  LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
>  DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
> @@ -612,7 +613,7 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_builddir)/lib/config.h \
>   $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
>   $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
>   $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
> - $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h \
> + $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h $(srcdir)/create_inode.h\
>   $(top_srcdir)/lib/quota/quotaio.h $(top_srcdir)/lib/quota/dqblk_v2.h \
>   $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h
>  chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
> @@ -692,3 +693,7 @@ e2freefrag.o: $(srcdir)/e2freefrag.c $(top_builddir)/lib/config.h \
>   $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
>   $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
>   $(srcdir)/e2freefrag.h
> +create_inode.o: $(srcdir)/create_inode.h $(srcdir)/create_inode.c \
> + $(top_builddir)/lib/config.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
> + $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
> + $(srcdir)/nls-enable.h
> diff --git a/misc/create_inode.c b/misc/create_inode.c
> new file mode 100644
> index 0000000..46aaa60
> --- /dev/null
> +++ b/misc/create_inode.c
> @@ -0,0 +1,26 @@
> +#include "create_inode.h"
> +
> +/* Make a special file which is block, character and fifo */
> +errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
> +{
> +}
> +
> +/* Make a symlink name -> target */
> +errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target)
> +{
> +}
> +
> +/* Make a directory in the fs */
> +errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
> +{
> +}
> +
> +/* Copy the native file to the fs */
> +errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
> +{
> +}
> +
> +/* Copy files from source_dir to fs */
> +errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
> +{
> +}
> diff --git a/misc/create_inode.h b/misc/create_inode.h
> new file mode 100644
> index 0000000..9fc97fa
> --- /dev/null
> +++ b/misc/create_inode.h
> @@ -0,0 +1,17 @@
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +#include <fcntl.h>
> +#include "et/com_err.h"
> +#include "e2p/e2p.h"
> +#include "ext2fs/ext2fs.h"
> +#include "nls-enable.h"
> +
> +ext2_filsys    current_fs;
> +ext2_ino_t     root;
> +
> +/* For populating the filesystem */
> +extern errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir);
> +extern errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st);
> +extern errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target);
> +extern errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st);
> +extern errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest);
> diff --git a/misc/mke2fs.c b/misc/mke2fs.c
> index 4075099..eab5463 100644
> --- a/misc/mke2fs.c
> +++ b/misc/mke2fs.c
> @@ -22,7 +22,6 @@
>  #include <stdio.h>
>  #include <string.h>
>  #include <strings.h>
> -#include <fcntl.h>
>  #include <ctype.h>
>  #include <time.h>
>  #ifdef __linux__
> @@ -44,24 +43,19 @@ extern int optind;
>  #include <errno.h>
>  #endif
>  #include <sys/ioctl.h>
> -#include <sys/types.h>
> -#include <sys/stat.h>
>  #include <libgen.h>
>  #include <limits.h>
>  #include <blkid/blkid.h>
>  
>  #include "ext2fs/ext2_fs.h"
>  #include "ext2fs/ext2fsP.h"
> -#include "et/com_err.h"
>  #include "uuid/uuid.h"
> -#include "e2p/e2p.h"
> -#include "ext2fs/ext2fs.h"
>  #include "util.h"
>  #include "profile.h"
>  #include "prof_err.h"
>  #include "../version.h"
> -#include "nls-enable.h"
>  #include "quota/mkquota.h"
> +#include "create_inode.h"
>  
>  #define STRIDE_LENGTH 8
>  
> @@ -105,6 +99,7 @@ char *mount_dir;
>  char *journal_device;
>  int sync_kludge;	/* Set using the MKE2FS_SYNC env. option */
>  char **fs_types;
> +const char *root_dir;  /* Copy files from the specified directory */
>  
>  profile_t	profile;
>  
> @@ -116,7 +111,8 @@ static void usage(void)
>  	fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
>  	"[-C cluster-size]\n\t[-i bytes-per-inode] [-I inode-size] "
>  	"[-J journal-options]\n"
> -	"\t[-G flex-group-size] [-N number-of-inodes]\n"
> +	"\t[-G flex-group-size] [-N number-of-inodes] "
> +	"[-d root-directory]\n"
>  	"\t[-m reserved-blocks-percentage] [-o creator-os]\n"
>  	"\t[-g blocks-per-group] [-L volume-label] "
>  	"[-M last-mounted-directory]\n\t[-O feature[,...]] "
> @@ -1403,7 +1399,7 @@ profile_error:
>  	}
>  
>  	while ((c = getopt (argc, argv,
> -		    "b:cg:i:jl:m:no:qr:s:t:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
> +		    "b:cg:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
>  		switch (c) {
>  		case 'b':
>  			blocksize = parse_num_blocks2(optarg, -1);
> @@ -1591,6 +1587,9 @@ profile_error:
>  		case 'U':
>  			fs_uuid = optarg;
>  			break;
> +		case 'd':
> +			root_dir = optarg;
> +			break;
>  		case 'v':
>  			verbose = 1;
>  			break;
> @@ -2798,6 +2797,21 @@ no_journal:
>  				       EXT4_FEATURE_RO_COMPAT_QUOTA))
>  		create_quota_inodes(fs);
>  
> +	/* Copy files from the specified directory */
> +	if (root_dir) {
> +		if (!quiet)
> +			printf("%s", _("Copying files into the device: "));
> +
> +		current_fs = fs;
> +		root = EXT2_ROOT_INO;
> +		retval = populate_fs(root, root_dir);
> +		if (retval)
> +			fprintf(stderr, "%s",
> +				_("\nError while populating %s"), root_dir);
> +		else if (!quiet)
> +			printf("%s", _("done\n"));
> +	}
> +
>  	if (!quiet)
>  		printf("%s", _("Writing superblocks and "
>  		       "filesystem accounting information: "));

-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 04/10] misc/create_inode.c: create symlink
  2013-12-23 12:09 ` [PATCH 04/10] misc/create_inode.c: create symlink Robert Yang
@ 2013-12-23 19:27   ` Darren Hart
  0 siblings, 0 replies; 20+ messages in thread
From: Darren Hart @ 2013-12-23 19:27 UTC (permalink / raw)
  To: Robert Yang; +Cc: tytso, linux-ext4

On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> The do_symlink_internal() is used for creating symlinks, most of the
> code are from debugfs/debugfs.c, the debugfs/debugfs.c will be modified
> to use this function.
> 
> Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
> ---
>  misc/create_inode.c |   34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 
> diff --git a/misc/create_inode.c b/misc/create_inode.c
> index 62a40de..45c8a87 100644
> --- a/misc/create_inode.c
> +++ b/misc/create_inode.c
> @@ -81,6 +81,40 @@ errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
>  /* Make a symlink name -> target */
>  errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target)
>  {
> +	char			*cp;
> +	ext2_ino_t		parent_ino;
> +	errcode_t		retval;
> +	struct ext2_inode	inode;
> +	struct stat		st;
> +
> +	cp = strrchr(name, '/');
> +	if (cp) {
> +		*cp = 0;
> +		if ((retval =  ext2fs_namei(current_fs, root, cwd, name, &parent_ino))){
> +			com_err(name, retval, 0);
> +			return retval;
> +		}
> +		name = cp+1;
> +	} else {
> +		parent_ino = cwd;
> +		name = name;

What is the intent of this assignment to self? It appears to be a
conversion artifact from the debugfs do_symlink() function, and could be
dropped.

-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 05/10] misc/create_inode.c: copy regular file
  2013-12-23 12:09 ` [PATCH 05/10] misc/create_inode.c: copy regular file Robert Yang
@ 2013-12-23 19:32   ` Darren Hart
  2013-12-26 16:03     ` Theodore Ts'o
  0 siblings, 1 reply; 20+ messages in thread
From: Darren Hart @ 2013-12-23 19:32 UTC (permalink / raw)
  To: Robert Yang; +Cc: tytso, linux-ext4

On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> The do_write_internal() is used for copying file from native fs to
> target, most of the code are from debugfs/debugfs.c, the
> debugfs/debugfs.c will be modified to use this function.
> 
> Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
> ---
>  misc/create_inode.c |  184 +++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 184 insertions(+)
> 


> +
>  /* Copy the native file to the fs */
>  errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
>  {
> +	int		fd;
> +	struct stat	statbuf;
> +	ext2_ino_t	newfile;
> +	errcode_t	retval;
> +	struct ext2_inode inode;
> +	int		bufsize = IO_BUFSIZE;
> +	int		make_holes = 0;
> +	char		*func_name = "do_write_internal";

Does __FUNCTION__ not provide this same functionality in this context?
No need to store this explicitly is there?


-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 06/10] misc/create_inode.c: create directory
  2013-12-23 12:09 ` [PATCH 06/10] misc/create_inode.c: create directory Robert Yang
@ 2013-12-23 19:35   ` Darren Hart
  0 siblings, 0 replies; 20+ messages in thread
From: Darren Hart @ 2013-12-23 19:35 UTC (permalink / raw)
  To: Robert Yang; +Cc: tytso, linux-ext4

On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> The do_mkdir_internal() is used for making dir on the target fs, most of
> the code are from debugfs/debugfs.c, the debugfs/debugfs.c will be
> modified to use this function.
> 
> Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
> ---
>  misc/create_inode.c |   34 ++++++++++++++++++++++++++++++++++
>  1 file changed, 34 insertions(+)
> 

Similar comments here...

> diff --git a/misc/create_inode.c b/misc/create_inode.c
> index 718d499..95acffe 100644
> --- a/misc/create_inode.c
> +++ b/misc/create_inode.c
> @@ -130,6 +130,40 @@ try_again:
>  /* Make a directory in the fs */
>  errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
>  {
> +	char			*cp;
> +	ext2_ino_t		parent_ino, ino;
> +	errcode_t		retval;
> +	struct ext2_inode	inode;
> +	char			*func_name = "do_mkdir_internal";


__FUNCTION__ ?

> +
> +
> +	cp = strrchr(name, '/');
> +	if (cp) {
> +		*cp = 0;
> +		if ((retval =  ext2fs_namei(current_fs, root, cwd, name, &parent_ino))){
> +			com_err(name, retval, 0);
> +			return retval;
> +		}
> +		name = cp+1;
> +	} else {
> +		parent_ino = cwd;
> +		name = name;

Copy from debugfs artifact?


-- 
Darren Hart
Intel Open Source Technology Center
Yocto Project - Linux Kernel



^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/10] mke2fs.c: add an option: -d root-directory
  2013-12-23 19:08   ` Darren Hart
@ 2013-12-24  1:52     ` Robert Yang
  2013-12-26 16:07     ` Theodore Ts'o
  1 sibling, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-24  1:52 UTC (permalink / raw)
  To: Darren Hart; +Cc: tytso, linux-ext4


Hi Darren,

Thanks for the reply, I'd like to move part of the first patch
to the end if this puzzles people, here is the size impact on
mke2fs (no impact on tune2fs):

Not stripped:
   1837440 -> 1903522 (64K increased)
Stripped:
   329464 -> 321272 (8K increased)

I will send a V2 with your other comments.

// Robert

On 12/24/2013 03:08 AM, Darren Hart wrote:
> On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
>> This option is used for adding the files from a given directory (the
>> root-directory) to the filesystem, it is similiar to genext2fs, but
>> genext2fs doesn't fully support ext4.
>>
>> This commit describes the skeleton of the implementation:
>
> This approach strikes me as a bit odd. We're adding an option and empty
> functions, rather than fleshing them out at the same time. What is the
> motivation for separating this from the actual implementation? At the
> very least the -d option shouldn't be added until it is functional - at
> the end of the series...
>
> Ted, was there a recommendation to take this approach - maybe I'm
> missing some context?
>
> Thanks,
>
> Darren Hart
>
>> * We already have the basic operations in debugfs:
>>    - Copy regular file
>>    - Create directory
>>    - Create symlink
>>    - Create special file
>>
>>    We will move these operations into create_inode.h and create_inode.c,
>>    then let both mke2fs and debugfs use them.
>>
>> * What we need to do are:
>>    - Copy the given directory recursively
>>    - Set the owner, mode and other informations
>>    - Handle the hard links
>>
>> TODO:
>>    - The libext2fs can't create the socket file (S_IFSOCK), do we have a
>>      plan to support it ?
>>
>> Signed-off-by: Robert Yang <liezhi.yang@windriver.com>
>> ---
>>   misc/Makefile.in    |   13 +++++++++----
>>   misc/create_inode.c |   26 ++++++++++++++++++++++++++
>>   misc/create_inode.h |   17 +++++++++++++++++
>>   misc/mke2fs.c       |   32 +++++++++++++++++++++++---------
>>   4 files changed, 75 insertions(+), 13 deletions(-)
>>   create mode 100644 misc/create_inode.c
>>   create mode 100644 misc/create_inode.h
>>
>> diff --git a/misc/Makefile.in b/misc/Makefile.in
>> index a798f96..da780fe 100644
>> --- a/misc/Makefile.in
>> +++ b/misc/Makefile.in
>> @@ -42,7 +42,7 @@ LPROGS=		@E2INITRD_PROG@
>>
>>   TUNE2FS_OBJS=	tune2fs.o util.o
>>   MKLPF_OBJS=	mklost+found.o
>> -MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o
>> +MKE2FS_OBJS=	mke2fs.o util.o profile.o prof_err.o default_profile.o create_inode.o
>>   CHATTR_OBJS=	chattr.o
>>   LSATTR_OBJS=	lsattr.o
>>   UUIDGEN_OBJS=	uuidgen.o
>> @@ -60,7 +60,8 @@ E2FREEFRAG_OBJS= e2freefrag.o
>>   PROFILED_TUNE2FS_OBJS=	profiled/tune2fs.o profiled/util.o
>>   PROFILED_MKLPF_OBJS=	profiled/mklost+found.o
>>   PROFILED_MKE2FS_OBJS=	profiled/mke2fs.o profiled/util.o profiled/profile.o \
>> -			profiled/prof_err.o profiled/default_profile.o
>> +			profiled/prof_err.o profiled/default_profile.o \
>> +			profiled/create_inode.o
>>   PROFILED_CHATTR_OBJS=	profiled/chattr.o
>>   PROFILED_LSATTR_OBJS=	profiled/lsattr.o
>>   PROFILED_UUIDGEN_OBJS=	profiled/uuidgen.o
>> @@ -82,7 +83,7 @@ SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
>>   		$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
>>   		$(srcdir)/filefrag.c $(srcdir)/base_device.c \
>>   		$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
>> -		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c
>> +		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c $(srcdir)/create_inode.c
>>
>>   LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
>>   DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
>> @@ -612,7 +613,7 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_builddir)/lib/config.h \
>>    $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
>>    $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
>>    $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
>> - $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h \
>> + $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.h $(srcdir)/create_inode.h\
>>    $(top_srcdir)/lib/quota/quotaio.h $(top_srcdir)/lib/quota/dqblk_v2.h \
>>    $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h
>>   chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
>> @@ -692,3 +693,7 @@ e2freefrag.o: $(srcdir)/e2freefrag.c $(top_builddir)/lib/config.h \
>>    $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
>>    $(top_srcdir)/lib/ext2fs/ext2_ext_attr.h $(top_srcdir)/lib/ext2fs/bitops.h \
>>    $(srcdir)/e2freefrag.h
>> +create_inode.o: $(srcdir)/create_inode.h $(srcdir)/create_inode.c \
>> + $(top_builddir)/lib/config.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
>> + $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/e2p/e2p.h \
>> + $(srcdir)/nls-enable.h
>> diff --git a/misc/create_inode.c b/misc/create_inode.c
>> new file mode 100644
>> index 0000000..46aaa60
>> --- /dev/null
>> +++ b/misc/create_inode.c
>> @@ -0,0 +1,26 @@
>> +#include "create_inode.h"
>> +
>> +/* Make a special file which is block, character and fifo */
>> +errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st)
>> +{
>> +}
>> +
>> +/* Make a symlink name -> target */
>> +errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target)
>> +{
>> +}
>> +
>> +/* Make a directory in the fs */
>> +errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st)
>> +{
>> +}
>> +
>> +/* Copy the native file to the fs */
>> +errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest)
>> +{
>> +}
>> +
>> +/* Copy files from source_dir to fs */
>> +errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir)
>> +{
>> +}
>> diff --git a/misc/create_inode.h b/misc/create_inode.h
>> new file mode 100644
>> index 0000000..9fc97fa
>> --- /dev/null
>> +++ b/misc/create_inode.h
>> @@ -0,0 +1,17 @@
>> +#include <sys/types.h>
>> +#include <sys/stat.h>
>> +#include <fcntl.h>
>> +#include "et/com_err.h"
>> +#include "e2p/e2p.h"
>> +#include "ext2fs/ext2fs.h"
>> +#include "nls-enable.h"
>> +
>> +ext2_filsys    current_fs;
>> +ext2_ino_t     root;
>> +
>> +/* For populating the filesystem */
>> +extern errcode_t populate_fs(ext2_ino_t parent_ino, const char *source_dir);
>> +extern errcode_t do_mknod_internal(ext2_ino_t cwd, const char *name, struct stat *st);
>> +extern errcode_t do_symlink_internal(ext2_ino_t cwd, const char *name, char *target);
>> +extern errcode_t do_mkdir_internal(ext2_ino_t cwd, const char *name, struct stat *st);
>> +extern errcode_t do_write_internal(ext2_ino_t cwd, const char *src, const char *dest);
>> diff --git a/misc/mke2fs.c b/misc/mke2fs.c
>> index 4075099..eab5463 100644
>> --- a/misc/mke2fs.c
>> +++ b/misc/mke2fs.c
>> @@ -22,7 +22,6 @@
>>   #include <stdio.h>
>>   #include <string.h>
>>   #include <strings.h>
>> -#include <fcntl.h>
>>   #include <ctype.h>
>>   #include <time.h>
>>   #ifdef __linux__
>> @@ -44,24 +43,19 @@ extern int optind;
>>   #include <errno.h>
>>   #endif
>>   #include <sys/ioctl.h>
>> -#include <sys/types.h>
>> -#include <sys/stat.h>
>>   #include <libgen.h>
>>   #include <limits.h>
>>   #include <blkid/blkid.h>
>>
>>   #include "ext2fs/ext2_fs.h"
>>   #include "ext2fs/ext2fsP.h"
>> -#include "et/com_err.h"
>>   #include "uuid/uuid.h"
>> -#include "e2p/e2p.h"
>> -#include "ext2fs/ext2fs.h"
>>   #include "util.h"
>>   #include "profile.h"
>>   #include "prof_err.h"
>>   #include "../version.h"
>> -#include "nls-enable.h"
>>   #include "quota/mkquota.h"
>> +#include "create_inode.h"
>>
>>   #define STRIDE_LENGTH 8
>>
>> @@ -105,6 +99,7 @@ char *mount_dir;
>>   char *journal_device;
>>   int sync_kludge;	/* Set using the MKE2FS_SYNC env. option */
>>   char **fs_types;
>> +const char *root_dir;  /* Copy files from the specified directory */
>>
>>   profile_t	profile;
>>
>> @@ -116,7 +111,8 @@ static void usage(void)
>>   	fprintf(stderr, _("Usage: %s [-c|-l filename] [-b block-size] "
>>   	"[-C cluster-size]\n\t[-i bytes-per-inode] [-I inode-size] "
>>   	"[-J journal-options]\n"
>> -	"\t[-G flex-group-size] [-N number-of-inodes]\n"
>> +	"\t[-G flex-group-size] [-N number-of-inodes] "
>> +	"[-d root-directory]\n"
>>   	"\t[-m reserved-blocks-percentage] [-o creator-os]\n"
>>   	"\t[-g blocks-per-group] [-L volume-label] "
>>   	"[-M last-mounted-directory]\n\t[-O feature[,...]] "
>> @@ -1403,7 +1399,7 @@ profile_error:
>>   	}
>>
>>   	while ((c = getopt (argc, argv,
>> -		    "b:cg:i:jl:m:no:qr:s:t:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
>> +		    "b:cg:i:jl:m:no:qr:s:t:d:vC:DE:FG:I:J:KL:M:N:O:R:ST:U:V")) != EOF) {
>>   		switch (c) {
>>   		case 'b':
>>   			blocksize = parse_num_blocks2(optarg, -1);
>> @@ -1591,6 +1587,9 @@ profile_error:
>>   		case 'U':
>>   			fs_uuid = optarg;
>>   			break;
>> +		case 'd':
>> +			root_dir = optarg;
>> +			break;
>>   		case 'v':
>>   			verbose = 1;
>>   			break;
>> @@ -2798,6 +2797,21 @@ no_journal:
>>   				       EXT4_FEATURE_RO_COMPAT_QUOTA))
>>   		create_quota_inodes(fs);
>>
>> +	/* Copy files from the specified directory */
>> +	if (root_dir) {
>> +		if (!quiet)
>> +			printf("%s", _("Copying files into the device: "));
>> +
>> +		current_fs = fs;
>> +		root = EXT2_ROOT_INO;
>> +		retval = populate_fs(root, root_dir);
>> +		if (retval)
>> +			fprintf(stderr, "%s",
>> +				_("\nError while populating %s"), root_dir);
>> +		else if (!quiet)
>> +			printf("%s", _("done\n"));
>> +	}
>> +
>>   	if (!quiet)
>>   		printf("%s", _("Writing superblocks and "
>>   		       "filesystem accounting information: "));
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 05/10] misc/create_inode.c: copy regular file
  2013-12-23 19:32   ` Darren Hart
@ 2013-12-26 16:03     ` Theodore Ts'o
  2013-12-27  1:48       ` Robert Yang
  0 siblings, 1 reply; 20+ messages in thread
From: Theodore Ts'o @ 2013-12-26 16:03 UTC (permalink / raw)
  To: Darren Hart; +Cc: Robert Yang, linux-ext4

On Mon, Dec 23, 2013 at 11:32:19AM -0800, Darren Hart wrote:
> 
> Does __FUNCTION__ not provide this same functionality in this context?
> No need to store this explicitly is there?

Note: __func__ (which is specified by C99, and supported by newer
GCC's) is preferred over __FUNCTION__.

If we really care about supporting older versions of GCC, we could do
this:

     #if __STDC_VERSION__ < 199901L
     # if __GNUC__ >= 2
     #  define __func__ __FUNCTION__
     # else
     #  define __func__ "<unknown>"
     # endif
     #endif

Cheers,

						- Ted

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 01/10] mke2fs.c: add an option: -d root-directory
  2013-12-23 19:08   ` Darren Hart
  2013-12-24  1:52     ` Robert Yang
@ 2013-12-26 16:07     ` Theodore Ts'o
  1 sibling, 0 replies; 20+ messages in thread
From: Theodore Ts'o @ 2013-12-26 16:07 UTC (permalink / raw)
  To: Darren Hart; +Cc: Robert Yang, linux-ext4

On Mon, Dec 23, 2013 at 11:08:17AM -0800, Darren Hart wrote:
> On Mon, 2013-12-23 at 07:09 -0500, Robert Yang wrote:
> > This option is used for adding the files from a given directory (the
> > root-directory) to the filesystem, it is similiar to genext2fs, but
> > genext2fs doesn't fully support ext4.
> > 
> > This commit describes the skeleton of the implementation:
> 
> This approach strikes me as a bit odd. We're adding an option and empty
> functions, rather than fleshing them out at the same time. What is the
> motivation for separating this from the actual implementation? At the
> very least the -d option shouldn't be added until it is functional - at
> the end of the series...

I think this approach was used because I complained that intermediate
versions of the commits didn't compile, and this makes bisection
harder.

I'm not going to be that picky about the specific order, though, so
long as after each commit, the result compiles and passes the
regression test suite, although adding support for -d at the very end
does make sense.  Or you could only support directories and regular
files, and then add support for symlinks, special files, etc.

Cheers,

						- Ted

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: [PATCH 05/10] misc/create_inode.c: copy regular file
  2013-12-26 16:03     ` Theodore Ts'o
@ 2013-12-27  1:48       ` Robert Yang
  0 siblings, 0 replies; 20+ messages in thread
From: Robert Yang @ 2013-12-27  1:48 UTC (permalink / raw)
  To: Theodore Ts'o, Darren Hart; +Cc: linux-ext4


Hi Ted,

Thanks for the reply, I will update it.

// Robert

On 12/27/2013 12:03 AM, Theodore Ts'o wrote:
> On Mon, Dec 23, 2013 at 11:32:19AM -0800, Darren Hart wrote:
>>
>> Does __FUNCTION__ not provide this same functionality in this context?
>> No need to store this explicitly is there?
>
> Note: __func__ (which is specified by C99, and supported by newer
> GCC's) is preferred over __FUNCTION__.
>
> If we really care about supporting older versions of GCC, we could do
> this:
>
>       #if __STDC_VERSION__ < 199901L
>       # if __GNUC__ >= 2
>       #  define __func__ __FUNCTION__
>       # else
>       #  define __func__ "<unknown>"
>       # endif
>       #endif
>
> Cheers,
>
> 						- Ted
> --
> To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2013-12-27  1:48 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-12-23 12:09 [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Robert Yang
2013-12-23 12:09 ` [PATCH 01/10] mke2fs.c: " Robert Yang
2013-12-23 19:08   ` Darren Hart
2013-12-24  1:52     ` Robert Yang
2013-12-26 16:07     ` Theodore Ts'o
2013-12-23 12:09 ` [PATCH 02/10] misc/create_inode.c: copy files recursively Robert Yang
2013-12-23 12:09 ` [PATCH 03/10] misc/create_inode.c: create special file Robert Yang
2013-12-23 12:09 ` [PATCH 04/10] misc/create_inode.c: create symlink Robert Yang
2013-12-23 19:27   ` Darren Hart
2013-12-23 12:09 ` [PATCH 05/10] misc/create_inode.c: copy regular file Robert Yang
2013-12-23 19:32   ` Darren Hart
2013-12-26 16:03     ` Theodore Ts'o
2013-12-27  1:48       ` Robert Yang
2013-12-23 12:09 ` [PATCH 06/10] misc/create_inode.c: create directory Robert Yang
2013-12-23 19:35   ` Darren Hart
2013-12-23 12:09 ` [PATCH 07/10] misc/create_inode.c: set owner/mode/time for the inode Robert Yang
2013-12-23 12:09 ` [PATCH 08/10] misc/create_inode.c: handle hardlinks Robert Yang
2013-12-23 12:09 ` [PATCH 09/10] debugfs: use the functions in misc/create_inode.c Robert Yang
2013-12-23 12:10 ` [PATCH 10/10] mke2fs.8.in: update the manual for the -d option Robert Yang
2013-12-23 19:05 ` [PATCH 00/10] e2fsprogs/mke2fs: add an option: -d root-directory Darren Hart

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).