[T106][ZXW-22]7520V3SCV2.01.01.02P42U09_VEC_V0.8_AP_VEC origin source commit

Change-Id: Ic6e05d89ecd62fc34f82b23dcf306c93764aec4b
diff --git a/ap/app/e2fsprogs/e2fsprogs-1.42.9/misc/e2undo.c b/ap/app/e2fsprogs/e2fsprogs-1.42.9/misc/e2undo.c
new file mode 100644
index 0000000..a43c26f
--- /dev/null
+++ b/ap/app/e2fsprogs/e2fsprogs-1.42.9/misc/e2undo.c
@@ -0,0 +1,225 @@
+/*
+ * e2undo.c - Replay an undo log onto an ext2/3/4 filesystem
+ *
+ * Copyright IBM Corporation, 2007
+ * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+#include <fcntl.h>
+#if HAVE_ERRNO_H
+#include <errno.h>
+#endif
+#include "ext2fs/tdb.h"
+#include "ext2fs/ext2fs.h"
+#include "nls-enable.h"
+
+static unsigned char mtime_key[] = "filesystem MTIME";
+static unsigned char uuid_key[] = "filesystem UUID";
+static unsigned char blksize_key[] = "filesystem BLKSIZE";
+
+static char *prg_name;
+
+static void usage(void)
+{
+	fprintf(stderr,
+		_("Usage: %s <transaction file> <filesystem>\n"), prg_name);
+	exit(1);
+}
+
+static int check_filesystem(TDB_CONTEXT *tdb, io_channel channel)
+{
+	__u32   s_mtime;
+	__u8    s_uuid[16];
+	errcode_t retval;
+	TDB_DATA tdb_key, tdb_data;
+	struct ext2_super_block super;
+
+	io_channel_set_blksize(channel, SUPERBLOCK_OFFSET);
+	retval = io_channel_read_blk64(channel, 1, -SUPERBLOCK_SIZE, &super);
+	if (retval) {
+		com_err(prg_name, retval,
+			"%s", _("Failed to read the file system data \n"));
+		return retval;
+	}
+
+	tdb_key.dptr = mtime_key;
+	tdb_key.dsize = sizeof(mtime_key);
+	tdb_data = tdb_fetch(tdb, tdb_key);
+	if (!tdb_data.dptr) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+		com_err(prg_name, retval,
+			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
+		return retval;
+	}
+
+	s_mtime = *(__u32 *)tdb_data.dptr;
+	if (super.s_mtime != s_mtime) {
+
+		com_err(prg_name, 0,
+			_("The file system Mount time didn't match %u\n"),
+			s_mtime);
+
+		return  -1;
+	}
+
+
+	tdb_key.dptr = uuid_key;
+	tdb_key.dsize = sizeof(uuid_key);
+	tdb_data = tdb_fetch(tdb, tdb_key);
+	if (!tdb_data.dptr) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+		com_err(prg_name, retval,
+			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
+		return retval;
+	}
+	memcpy(s_uuid, tdb_data.dptr, sizeof(s_uuid));
+	if (memcmp(s_uuid, super.s_uuid, sizeof(s_uuid))) {
+		com_err(prg_name, 0, "%s",
+			_("The file system UUID didn't match \n"));
+		return -1;
+	}
+
+	return 0;
+}
+
+static int set_blk_size(TDB_CONTEXT *tdb, io_channel channel)
+{
+	int block_size;
+	errcode_t retval;
+	TDB_DATA tdb_key, tdb_data;
+
+	tdb_key.dptr = blksize_key;
+	tdb_key.dsize = sizeof(blksize_key);
+	tdb_data = tdb_fetch(tdb, tdb_key);
+	if (!tdb_data.dptr) {
+		retval = EXT2_ET_TDB_SUCCESS + tdb_error(tdb);
+		com_err(prg_name, retval,
+			_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
+		return retval;
+	}
+
+	block_size = *(int *)tdb_data.dptr;
+#ifdef DEBUG
+	printf("Block size %d\n", block_size);
+#endif
+	io_channel_set_blksize(channel, block_size);
+
+	return 0;
+}
+
+int main(int argc, char *argv[])
+{
+	int c,force = 0;
+	TDB_CONTEXT *tdb;
+	TDB_DATA key, data;
+	io_channel channel;
+	errcode_t retval;
+	int  mount_flags;
+	blk64_t  blk_num;
+	char *device_name, *tdb_file;
+	io_manager manager = unix_io_manager;
+
+#ifdef ENABLE_NLS
+	setlocale(LC_MESSAGES, "");
+	setlocale(LC_CTYPE, "");
+	bindtextdomain(NLS_CAT_NAME, LOCALEDIR);
+	textdomain(NLS_CAT_NAME);
+	set_com_err_gettext(gettext);
+#endif
+	add_error_table(&et_ext2_error_table);
+
+	prg_name = argv[0];
+	while((c = getopt(argc, argv, "f")) != EOF) {
+		switch (c) {
+			case 'f':
+				force = 1;
+				break;
+			default:
+				usage();
+		}
+	}
+
+	if (argc != optind + 2)
+		usage();
+
+	tdb_file = argv[optind];
+	device_name = argv[optind+1];
+
+	tdb = tdb_open(tdb_file, 0, 0, O_RDONLY, 0600);
+
+	if (!tdb) {
+		com_err(prg_name, errno,
+				_("Failed tdb_open %s\n"), tdb_file);
+		exit(1);
+	}
+
+	retval = ext2fs_check_if_mounted(device_name, &mount_flags);
+	if (retval) {
+		com_err(prg_name, retval, _("Error while determining whether "
+				"%s is mounted.\n"), device_name);
+		exit(1);
+	}
+
+	if (mount_flags & EXT2_MF_MOUNTED) {
+		com_err(prg_name, retval, "%s", _("e2undo should only be run "
+						"on unmounted file system\n"));
+		exit(1);
+	}
+
+	retval = manager->open(device_name,
+				IO_FLAG_EXCLUSIVE | IO_FLAG_RW,  &channel);
+	if (retval) {
+		com_err(prg_name, retval,
+				_("Failed to open %s\n"), device_name);
+		exit(1);
+	}
+
+	if (!force && check_filesystem(tdb, channel)) {
+		exit(1);
+	}
+
+	if (set_blk_size(tdb, channel)) {
+		exit(1);
+	}
+
+	for (key = tdb_firstkey(tdb); key.dptr; key = tdb_nextkey(tdb, key)) {
+		if (!strcmp((char *) key.dptr, (char *) mtime_key) ||
+		    !strcmp((char *) key.dptr, (char *) uuid_key) ||
+		    !strcmp((char *) key.dptr, (char *) blksize_key)) {
+			continue;
+		}
+
+		data = tdb_fetch(tdb, key);
+		if (!data.dptr) {
+			com_err(prg_name, 0,
+				_("Failed tdb_fetch %s\n"), tdb_errorstr(tdb));
+			exit(1);
+		}
+		blk_num = *(blk64_t *)key.dptr;
+		printf(_("Replayed transaction of size %zd at location %llu\n"),
+							data.dsize, blk_num);
+		retval = io_channel_write_blk64(channel, blk_num,
+						-data.dsize, data.dptr);
+		if (retval == -1) {
+			com_err(prg_name, retval,
+					_("Failed write %s\n"),
+					strerror(errno));
+			exit(1);
+		}
+	}
+	io_channel_close(channel);
+	tdb_close(tdb);
+
+	return 0;
+}