Description: update to e2fsprogs git commit f3ff319f79
 .
 e2fsprogs (1.42.9-3) unstable; urgency=medium
 .
   * Add the ability for mke2fs to create hugefiles
   * Add support for the sparse_super2 compat feature
   * Mke2fs can now force all of the metadata blocks to be at the
     beginning of the file system
   * Fix loopback mount detection (Closes: #497984)
   * Add support to mke2fs to create a file system at an offset
     (Closes: #417385)
   * Mention badblocks in the package description (Closes: #718725)
   * Update/fix various man pages (Closes: #719184, #719189)
   * Improve e2fsck's "superblock corrupt" message (Closes: #719185)
   * Miscellaneous Coverity clean ups
Author: Theodore Y. Ts'o <tytso@mit.edu>
Origin: upstream<vendor|upstream|other>, <url of original patch>
Bug-Debian: http://bugs.debian.org/417385
Bug-Debian: http://bugs.debian.org/497984
Bug-Debian: http://bugs.debian.org/718725
Bug-Debian: http://bugs.debian.org/719184
Bug-Debian: http://bugs.debian.org/719185
Bug-Debian: http://bugs.debian.org/719189

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: http://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: <YYYY-MM-DD>

--- e2fsprogs-1.42.9.orig/MCONFIG.in
+++ e2fsprogs-1.42.9/MCONFIG.in
@@ -110,6 +110,7 @@ LIBUUID = @LIBUUID@ @SOCKET_LIB@
 LIBQUOTA = @STATIC_LIBQUOTA@
 LIBBLKID = @LIBBLKID@ @PRIVATE_LIBS_CMT@ $(LIBUUID)
 LIBINTL = @LIBINTL@
+SYSLIBS = @LIBS@
 DEPLIBSS = $(LIB)/libss@LIB_EXT@
 DEPLIBCOM_ERR = $(LIB)/libcom_err@LIB_EXT@
 DEPLIBUUID = @DEPLIBUUID@
--- e2fsprogs-1.42.9.orig/configure
+++ e2fsprogs-1.42.9/configure
@@ -2753,6 +2753,21 @@ $as_echo "Release date is ${E2FSPROGS_MO
 
 
 
+WITH_DIET_LIBC=
+
+# Check whether --with-diet-libc was given.
+if test "${with_diet_libc+set}" = set; then :
+  withval=$with_diet_libc; CC="diet cc -nostdinc"
+WITH_DIET_LIBC=yes
+if test -z "$LIBS"
+then
+	LIBS="-lcompat"
+else
+	LIBS="$LIBS -lcompat"
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CC=$CC" >&5
+$as_echo "CC=$CC" >&6; }
+fi
 # Make sure we can run config.sub.
 $SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 ||
   as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5
@@ -3659,15 +3674,6 @@ $as_echo "#define HAVE_DLOPEN 1" >>confd
 fi
 
 
-WITH_DIET_LIBC=
-
-# Check whether --with-diet-libc was given.
-if test "${with_diet_libc+set}" = set; then :
-  withval=$with_diet_libc; CC="diet cc -nostdinc"
-WITH_DIET_LIBC=yes
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: CC=$CC" >&5
-$as_echo "CC=$CC" >&6; }
-fi
 
 # Check whether --with-cc was given.
 if test "${with_cc+set}" = set; then :
@@ -5440,9 +5446,16 @@ $as_echo "Enabling e4defrag support" >&6
 fi
 
 else
-  { $as_echo "$as_me:${as_lineno-$LINENO}: result: Enabling e4defrag support by default" >&5
+  if test -z "$WITH_DIET_LIBC"
+then
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Enabling e4defrag support by default" >&5
 $as_echo "Enabling e4defrag support by default" >&6; }
-DEFRAG_CMT=
+	DEFRAG_CMT=
+else
+	{ $as_echo "$as_me:${as_lineno-$LINENO}: result: Disabling e4defrag support by default" >&5
+$as_echo "Disabling e4defrag support by default" >&6; }
+	DEFRAG_CMT="#"
+fi
 
 fi
 
@@ -10448,6 +10461,16 @@ $as_echo "#define HAVE_RECLEN_DIRENT 1"
 
 fi
 
+ac_fn_c_check_member "$LINENO" "struct stat" "st_atim" "ac_cv_member_struct_stat_st_atim" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_atim" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_STAT_ST_ATIM 1
+_ACEOF
+
+
+fi
+
 ac_fn_c_check_type "$LINENO" "ssize_t" "ac_cv_type_ssize_t" "#include <sys/types.h>
 "
 if test "x$ac_cv_type_ssize_t" = xyes; then :
@@ -11041,7 +11064,7 @@ if test "$ac_res" != no; then :
 fi
 
 fi
-for ac_func in  	__secure_getenv 	backtrace 	blkid_probe_get_topology 	chflags 	fallocate 	fallocate64 	fchown 	fdatasync 	fstat64 	ftruncate64 	getdtablesize 	getmntinfo 	getpwuid_r 	getrlimit 	getrusage 	jrand48 	llseek 	lseek64 	mallinfo 	mbstowcs 	memalign 	mmap 	msync 	nanosleep 	open64 	pathconf 	posix_fadvise 	posix_memalign 	prctl 	secure_getenv 	setmntent 	setresgid 	setresuid 	srandom 	strcasecmp 	strdup 	strnlen 	strptime 	strtoull 	sync_file_range 	sysconf 	usleep 	utime 	valloc
+for ac_func in  	__secure_getenv 	backtrace 	blkid_probe_get_topology 	chflags 	fadvise64 	fallocate 	fallocate64 	fchown 	fdatasync 	fstat64 	ftruncate64 	futimes 	getcwd 	getdtablesize 	getmntinfo 	getpwuid_r 	getrlimit 	getrusage 	jrand48 	llseek 	lseek64 	mallinfo 	mbstowcs 	memalign 	mempcpy 	mmap 	msync 	nanosleep 	open64 	pathconf 	posix_fadvise 	posix_fadvise64 	posix_memalign 	prctl 	secure_getenv 	setmntent 	setresgid 	setresuid 	srandom 	stpcpy 	strcasecmp 	strdup 	strnlen 	strptime 	strtoull 	sync_file_range 	sysconf 	usleep 	utime 	valloc
 do :
   as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
@@ -11425,9 +11448,12 @@ fi
 if test "$USE_INCLUDED_LIBINTL" = "yes" ; then
 	INCLUDES=$INCLUDES' -I$(top_builddir)/intl -I$(top_srcdir)/intl'
 fi
+if test -n "$WITH_DIET_LIBC" ; then
+	INCLUDES="$INCLUDES -D_REENTRANT"
+fi
 
 if test $cross_compiling = no; then
-   BUILD_CFLAGS="$CFLAGS $CPPFLAGS"
+   BUILD_CFLAGS="$CFLAGS $CPPFLAGS $INCLUDES -DHAVE_CONFIG_H"
    BUILD_LDFLAGS="$LDFLAGS"
 else
    BUILD_CFLAGS=
--- e2fsprogs-1.42.9.orig/configure.in
+++ e2fsprogs-1.42.9/configure.in
@@ -2,7 +2,7 @@ AC_INIT(version.h)
 AC_PREREQ(2.54)
 AC_CONFIG_AUX_DIR(config)
 AC_CONFIG_HEADERS([lib/config.h])
-AH_BOTTOM([#include "dirpaths.h"])
+AH_BOTTOM([#include <dirpaths.h>])
 MCONFIG=./MCONFIG
 AC_SUBST_FILE(MCONFIG)
 BINARY_TYPE=bin
@@ -63,15 +63,6 @@ AC_SUBST(E2FSPROGS_MONTH)
 AC_SUBST(E2FSPROGS_DAY)
 AC_SUBST(E2FSPROGS_VERSION)
 AC_SUBST(E2FSPROGS_PKGVER)
-AC_CANONICAL_HOST
-dnl
-dnl Check to see if libdl exists for the sake of dlopen
-dnl
-DLOPEN_LIB=''
-AC_CHECK_LIB(dl, dlopen, 
-[DLOPEN_LIB=-ldl
-AC_DEFINE(HAVE_DLOPEN, 1, [Define to 1 if dlopen/libdl exists])])
-AC_SUBST(DLOPEN_LIB)
 dnl
 dnl Use diet libc
 dnl 
@@ -80,8 +71,24 @@ AC_ARG_WITH([diet-libc],
 [  --with-diet-libc        use diet libc],
 CC="diet cc -nostdinc"
 WITH_DIET_LIBC=yes
+if test -z "$LIBS"
+then
+	LIBS="-lcompat"
+else
+	LIBS="$LIBS -lcompat"
+fi
 AC_MSG_RESULT(CC=$CC))dnl
 dnl
+AC_CANONICAL_HOST
+dnl
+dnl Check to see if libdl exists for the sake of dlopen
+dnl
+DLOPEN_LIB=''
+AC_CHECK_LIB(dl, dlopen,
+[DLOPEN_LIB=-ldl
+AC_DEFINE(HAVE_DLOPEN, 1, [Define to 1 if dlopen/libdl exists])])
+AC_SUBST(DLOPEN_LIB)
+dnl
 AC_ARG_WITH([cc],
 AC_HELP_STRING([--with-cc],[no longer supported, use CC= instead]),
 AC_MSG_ERROR([--with-cc no longer supported; use CC= instead]))
@@ -687,8 +694,14 @@ else
 	AC_MSG_RESULT([Enabling e4defrag support])
 fi
 ,
-AC_MSG_RESULT([Enabling e4defrag support by default])
-DEFRAG_CMT=
+if test -z "$WITH_DIET_LIBC"
+then
+	AC_MSG_RESULT([Enabling e4defrag support by default])
+	DEFRAG_CMT=
+else
+	AC_MSG_RESULT([Disabling e4defrag support by default])
+	DEFRAG_CMT="#"
+fi
 )
 AC_SUBST(DEFRAG_CMT)
 dnl
@@ -909,6 +922,7 @@ dnl is not decleared.
 AC_CHECK_MEMBER(struct dirent.d_reclen,[AC_DEFINE(HAVE_RECLEN_DIRENT, 1,
 		       [Define to 1 if dirent has d_reclen])],,
 		[#include <dirent.h>])
+AC_CHECK_MEMBERS([struct stat.st_atim])
 dnl Check to see if ssize_t was declared
 AC_CHECK_TYPE(ssize_t,[AC_DEFINE(HAVE_TYPE_SSIZE_T, 1,
 		[Define to 1 if ssize_t declared])],,
@@ -1025,12 +1039,15 @@ AC_CHECK_FUNCS(m4_flatten([
 	backtrace
 	blkid_probe_get_topology
 	chflags
+	fadvise64
 	fallocate
 	fallocate64
 	fchown
 	fdatasync
 	fstat64
 	ftruncate64
+	futimes
+	getcwd
 	getdtablesize
 	getmntinfo
 	getpwuid_r
@@ -1042,12 +1059,14 @@ AC_CHECK_FUNCS(m4_flatten([
 	mallinfo
 	mbstowcs
 	memalign
+	mempcpy
 	mmap
 	msync
 	nanosleep
 	open64
 	pathconf
 	posix_fadvise
+	posix_fadvise64
 	posix_memalign
 	prctl
 	secure_getenv
@@ -1055,6 +1074,7 @@ AC_CHECK_FUNCS(m4_flatten([
 	setresgid
 	setresuid
 	srandom
+	stpcpy
 	strcasecmp
 	strdup
 	strnlen
@@ -1275,12 +1295,15 @@ fi
 if test "$USE_INCLUDED_LIBINTL" = "yes" ; then
 	INCLUDES=$INCLUDES' -I$(top_builddir)/intl -I$(top_srcdir)/intl'
 fi
+if test -n "$WITH_DIET_LIBC" ; then
+	INCLUDES="$INCLUDES -D_REENTRANT"
+fi
 AC_SUBST(INCLUDES)
 dnl
 dnl Build CFLAGS
 dnl
 if test $cross_compiling = no; then
-   BUILD_CFLAGS="$CFLAGS $CPPFLAGS"
+   BUILD_CFLAGS="$CFLAGS $CPPFLAGS $INCLUDES -DHAVE_CONFIG_H"
    BUILD_LDFLAGS="$LDFLAGS"
 else
    BUILD_CFLAGS=
--- e2fsprogs-1.42.9.orig/debugfs/Makefile.in
+++ e2fsprogs-1.42.9/debugfs/Makefile.in
@@ -31,12 +31,12 @@ SRCS= debug_cmds.c $(srcdir)/debugfs.c $
 	$(srcdir)/filefrag.c $(srcdir)/extent_inode.c $(srcdir)/zap.c
 
 LIBS= $(LIBEXT2FS) $(LIBE2P) $(LIBSS) $(LIBCOM_ERR) $(LIBBLKID) \
-	$(LIBUUID)
+	$(LIBUUID) $(SYSLIBS)
 DEPLIBS= $(LIBEXT2FS) $(LIBE2P) $(DEPLIBSS) $(DEPLIBCOM_ERR) \
 	$(DEPLIBBLKID) $(DEPLIBUUID)
 
 STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBSS) $(STATIC_LIBCOM_ERR) \
-	$(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(STATIC_LIBE2P)
+	$(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(STATIC_LIBE2P) $(SYSLIBS)
 STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) \
 		$(DEPSTATIC_LIBCOM_ERR) $(DEPSTATIC_LIBUUID) \
 		$(DEPSTATIC_LIBE2P)
--- e2fsprogs-1.42.9.orig/debugfs/debugfs.c
+++ e2fsprogs-1.42.9/debugfs/debugfs.c
@@ -289,8 +289,6 @@ void do_init_filesys(int argc, char **ar
 	if (err)
 		return;
 	ext2fs_blocks_count_set(&param, blocks);
-	if (err)
-		return;
 	retval = ext2fs_initialize(argv[1], 0, &param,
 				   unix_io_manager, &current_fs);
 	if (retval) {
--- e2fsprogs-1.42.9.orig/debugfs/logdump.c
+++ e2fsprogs-1.42.9/debugfs/logdump.c
@@ -273,42 +273,43 @@ print_usage:
 
 
 static int read_journal_block(const char *cmd, struct journal_source *source,
-			      off_t offset, char *buf, int size,
-			      unsigned int *got)
+			      off_t offset, char *buf, unsigned int size)
 {
 	int retval;
+	unsigned int got;
 
 	if (source->where == JOURNAL_IS_EXTERNAL) {
 		if (lseek(source->fd, offset, SEEK_SET) < 0) {
 			retval = errno;
-			com_err(cmd, retval, "while seeking in reading journal");
-			return retval;
+			goto seek_err;
 		}
 		retval = read(source->fd, buf, size);
-		if (retval >= 0) {
-			*got = retval;
-			retval = 0;
-		} else
+		if (retval < 0) {
 			retval = errno;
+			goto read_err;
+		}
+		got = retval;
+		retval = 0;
 	} else {
 		retval = ext2fs_file_lseek(source->file, offset,
 					   EXT2_SEEK_SET, NULL);
 		if (retval) {
+		seek_err:
 			com_err(cmd, retval, "while seeking in reading journal");
 			return retval;
 		}
-
-		retval = ext2fs_file_read(source->file, buf, size, got);
+		retval = ext2fs_file_read(source->file, buf, size, &got);
+		if (retval) {
+		read_err:
+			com_err(cmd, retval, "while reading journal");
+			return retval;
+		}
 	}
-
-	if (retval)
-		com_err(cmd, retval, "while reading journal");
-	else if (*got != (unsigned int) size) {
-		com_err(cmd, 0, "short read (read %d, expected %d) "
-			"while reading journal", *got, size);
+	if (got != size) {
+		com_err(cmd, 0, "short read (read %u, expected %u) "
+			"while reading journal", got, size);
 		retval = -1;
 	}
-
 	return retval;
 }
 
@@ -338,7 +339,6 @@ static void dump_journal(char *cmdname,
 	char			buf[8192];
 	journal_superblock_t	*jsb;
 	unsigned int		blocksize = 1024;
-	unsigned int		got;
 	int			retval;
 	__u32			magic, sequence, blocktype;
 	journal_header_t	*header;
@@ -347,8 +347,7 @@ static void dump_journal(char *cmdname,
 	unsigned int		blocknr = 0;
 
 	/* First, check to see if there's an ext2 superblock header */
-	retval = read_journal_block(cmdname, source, 0,
-				    buf, 2048, &got);
+	retval = read_journal_block(cmdname, source, 0, buf, 2048);
 	if (retval)
 		return;
 
@@ -377,7 +376,7 @@ static void dump_journal(char *cmdname,
 	/* Next, read the journal superblock */
 
 	retval = read_journal_block(cmdname, source, blocknr*blocksize,
-				    jsb_buffer, 1024, &got);
+				    jsb_buffer, 1024);
 	if (retval)
 		return;
 
@@ -401,8 +400,8 @@ static void dump_journal(char *cmdname,
 	while (1) {
 		retval = read_journal_block(cmdname, source,
 					    blocknr*blocksize, buf,
-					    blocksize, &got);
-		if (retval || got != blocksize)
+					    blocksize);
+		if (retval)
 			return;
 
 		header = (journal_header_t *) buf;
@@ -576,7 +575,6 @@ static void dump_metadata_block(FILE *ou
 				int blocksize,
 				tid_t transaction)
 {
-	unsigned int 	got;
 	int		retval;
 	char 		buf[8192];
 
@@ -612,7 +610,7 @@ static void dump_metadata_block(FILE *ou
 
 	retval = read_journal_block("logdump", source,
 				    blocksize * log_blocknr,
-				    buf, blocksize, &got);
+				    buf, blocksize);
 	if (retval)
 		return;
 
--- e2fsprogs-1.42.9.orig/debugfs/set_fields.c
+++ e2fsprogs-1.42.9/debugfs/set_fields.c
@@ -150,6 +150,8 @@ static struct field_set_info super_field
 	{ "usr_quota_inum", &set_sb.s_usr_quota_inum, NULL, 4, parse_uint },
 	{ "grp_quota_inum", &set_sb.s_grp_quota_inum, NULL, 4, parse_uint },
 	{ "overhead_blocks", &set_sb.s_overhead_blocks, NULL, 4, parse_uint },
+	{ "backup_bgs", &set_sb.s_backup_bgs[0], NULL, 4, parse_uint,
+	  FLAG_ARRAY, 2 },
 	{ "checksum", &set_sb.s_checksum, NULL, 4, parse_uint },
 	{ 0, 0, 0, 0 }
 };
--- e2fsprogs-1.42.9.orig/debugfs/util.c
+++ e2fsprogs-1.42.9/debugfs/util.c
@@ -201,7 +201,7 @@ char *time_to_string(__u32 cl)
 		tz = ss_safe_getenv("TZ");
 		if (!tz)
 			tz = "";
-		do_gmt = !strcmp(tz, "GMT");
+		do_gmt = !strcmp(tz, "GMT") | !strcmp(tz, "GMT0");
 	}
 
 	return asctime((do_gmt) ? gmtime(&t) : localtime(&t));
@@ -222,14 +222,18 @@ time_t string_to_time(const char *arg)
 	}
 	if (arg[0] == '@') {
 		/* interpret it as an integer */
-		ret = strtoul(arg+1, &tmp, 0);
+		arg++;
+	fallback:
+		ret = strtoul(arg, &tmp, 0);
 		if (*tmp)
 			return ((time_t) -1);
 		return ret;
 	}
 	memset(&ts, 0, sizeof(ts));
 #ifdef HAVE_STRPTIME
-	strptime(arg, "%Y%m%d%H%M%S", &ts);
+	tmp = strptime(arg, "%Y%m%d%H%M%S", &ts);
+	if (tmp == NULL)
+		goto fallback;
 #else
 	sscanf(arg, "%4d%2d%2d%2d%2d%2d", &ts.tm_year, &ts.tm_mon,
 	       &ts.tm_mday, &ts.tm_hour, &ts.tm_min, &ts.tm_sec);
@@ -241,13 +245,9 @@ time_t string_to_time(const char *arg)
 		ts.tm_mday = 0;
 #endif
 	ts.tm_isdst = -1;
-	ret = mktime(&ts);
-	if (ts.tm_mday == 0 || ret == ((time_t) -1)) {
-		/* Try it as an integer... */
-		ret = strtoul(arg, &tmp, 0);
-		if (*tmp)
-			return ((time_t) -1);
-	}
+	ret = ts.tm_sec + ts.tm_min*60 + ts.tm_hour*3600 + ts.tm_yday*86400 +
+		(ts.tm_year-70)*31536000 + ((ts.tm_year-69)/4)*86400 -
+		((ts.tm_year-1)/100)*86400 + ((ts.tm_year+299)/400)*86400;
 	return ret;
 }
 
--- e2fsprogs-1.42.9.orig/e2fsck/Makefile.in
+++ e2fsprogs-1.42.9/e2fsck/Makefile.in
@@ -16,19 +16,20 @@ MANPAGES=	e2fsck.8
 FMANPAGES=	e2fsck.conf.5
 
 LIBS= $(LIBQUOTA) $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBBLKID) $(LIBUUID) \
-	$(LIBINTL) $(LIBE2P)
+	$(LIBINTL) $(LIBE2P) $(SYSLIBS)
 DEPLIBS= $(DEPLIBQUOTA) $(LIBEXT2FS) $(DEPLIBCOM_ERR) $(DEPLIBBLKID) \
 	 $(DEPLIBUUID) $(DEPLIBE2P)
 
 STATIC_LIBS= $(STATIC_LIBQUOTA) $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
-	     $(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL) $(STATIC_LIBE2P)
+	     $(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL) $(STATIC_LIBE2P) \
+	     $(SYSLIBS)
 STATIC_DEPLIBS= $(DEPSTATIC_LIBQUOTA) $(STATIC_LIBEXT2FS) \
 		$(DEPSTATIC_LIBCOM_ERR) $(DEPSTATIC_LIBBLKID) \
 		$(DEPSTATIC_LIBUUID) $(DEPSTATIC_LIBE2P)
 
 PROFILED_LIBS= $(PROFILED_LIBQUOTA) $(PROFILED_LIBEXT2FS) \
 	       $(PROFILED_LIBCOM_ERR) $(PROFILED_LIBBLKID) $(PROFILED_LIBUUID) \
-	       $(PROFILED_LIBE2P) $(LIBINTL)
+	       $(PROFILED_LIBE2P) $(LIBINTL) $(SYSLIBS)
 PROFILED_DEPLIBS= $(DEPPROFILED_LIBQUOTA) $(PROFILED_LIBEXT2FS) \
 		  $(DEPPROFILED_LIBCOM_ERR) $(DEPPROFILED_LIBBLKID) \
 		  $(DEPPROFILED_LIBUUID) $(DEPPROFILED_LIBE2P)
@@ -153,26 +154,27 @@ tst_problem: $(srcdir)/problem.c $(srcdi
 	$(DEPLIBCOM_ERR)
 	$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_problem \
 		$(srcdir)/problem.c -DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR) \
-		$(LIBINTL)
+		$(LIBINTL) $(SYSLIBS)
 
 tst_crc32: $(srcdir)/crc32.c $(LIBEXT2FS) $(DEPLIBCOM_ERR)
 	$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_crc32 $(srcdir)/crc32.c \
-		-DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR)
+		-DUNITTEST $(LIBEXT2FS) $(LIBCOM_ERR) $(SYSLIBS)
 
 tst_refcount: ea_refcount.c $(DEPLIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_refcount $(srcdir)/ea_refcount.c \
-		$(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(LIBEXT2FS) 
+		$(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(LIBEXT2FS) \
+		$(SYSLIBS)
 
 tst_logfile: $(srcdir)/logfile.c
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_logfile $(srcdir)/logfile.c $(ALL_CFLAGS) \
-		-DTEST_PROGRAM
+		-DTEST_PROGRAM $(SYSLIBS)
 
 tst_region: region.c $(DEPLIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_region $(srcdir)/region.c \
-		$(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR)
+		$(ALL_CFLAGS) -DTEST_PROGRAM $(LIBCOM_ERR) $(SYSLIBS)
 
 check:: tst_refcount tst_region tst_crc32 tst_problem
 	LD_LIBRARY_PATH=$(LIB) DYLD_LIBRARY_PATH=$(LIB) ./tst_refcount
--- e2fsprogs-1.42.9.orig/e2fsck/badblocks.c
+++ e2fsprogs-1.42.9/e2fsck/badblocks.c
@@ -111,6 +111,8 @@ void read_bad_blocks_file(e2fsck_t ctx,
 
 fatal:
 	ctx->flags |= E2F_FLAG_ABORT;
+	if (bb_list)
+		ext2fs_badblocks_list_free(bb_list);
 	return;
 
 }
--- e2fsprogs-1.42.9.orig/e2fsck/dirinfo.c
+++ e2fsprogs-1.42.9/e2fsck/dirinfo.c
@@ -42,6 +42,7 @@ static void setup_tdb(e2fsck_t ctx, ext2
 	struct dir_info_db	*db = ctx->dir_info;
 	unsigned int		threshold;
 	errcode_t		retval;
+	mode_t			save_umask;
 	char			*tdb_dir, uuid[40];
 	int			fd, enable;
 
@@ -62,7 +63,9 @@ static void setup_tdb(e2fsck_t ctx, ext2
 
 	uuid_unparse(ctx->fs->super->s_uuid, uuid);
 	sprintf(db->tdb_fn, "%s/%s-dirinfo-XXXXXX", tdb_dir, uuid);
+	save_umask = umask(077);
 	fd = mkstemp(db->tdb_fn);
+	umask(save_umask);
 	if (fd < 0) {
 		db->tdb = NULL;
 		return;
--- e2fsprogs-1.42.9.orig/e2fsck/e2fsck.conf.5.in
+++ e2fsprogs-1.42.9/e2fsck/e2fsck.conf.5.in
@@ -97,9 +97,8 @@ incorrectly set at the time when e2fsck
 Historically this was usually due to some distributions
 having buggy init scripts and/or installers that didn't
 correctly detect this case and take appropriate
-countermeasures.  However, it's still possible, despite the
-best efforts of init script and installer authors to not be
-able to detect this misconfiguration, usually due to a
+countermeasures.  Unfortunately, this is occasionally
+true even today, usually due to a
 buggy or misconfigured virtualization manager or the
 installer not having access to a network time server
 during the installation process.  So by default, we allow
--- e2fsprogs-1.42.9.orig/e2fsck/message.c
+++ e2fsprogs-1.42.9/e2fsck/message.c
@@ -226,7 +226,8 @@ static void print_time(FILE *f, time_t t
 			time_str = getenv("TZ");
 			if (!time_str)
 				time_str = "";
-			do_gmt = !strcmp(time_str, "GMT0");
+			do_gmt = !strcmp(time_str, "GMT") ||
+				!strcmp(time_str, "GMT0");
 		}
 #endif
 		time_str = asctime((do_gmt > 0) ? gmtime(&t) : localtime(&t));
--- e2fsprogs-1.42.9.orig/e2fsck/pass1.c
+++ e2fsprogs-1.42.9/e2fsck/pass1.c
@@ -546,9 +546,9 @@ void e2fsck_pass1(e2fsck_t ctx)
 	__u64	max_sizes;
 	ext2_filsys fs = ctx->fs;
 	ext2_ino_t	ino = 0;
-	struct ext2_inode *inode;
-	ext2_inode_scan	scan;
-	char		*block_buf;
+	struct ext2_inode *inode = NULL;
+	ext2_inode_scan	scan = NULL;
+	char		*block_buf = NULL;
 #ifdef RESOURCE_TRACK
 	struct resource_track	rtrack;
 #endif
@@ -662,8 +662,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 	if (pctx.errcode) {
 		fix_problem(ctx, PR_1_ALLOCATE_DBCOUNT, &pctx);
 		ctx->flags |= E2F_FLAG_ABORT;
-		ext2fs_free_mem(&inode);
-		return;
+		goto endit;
 	}
 
 	/*
@@ -686,8 +685,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 	if (pctx.errcode) {
 		fix_problem(ctx, PR_1_CONVERT_SUBCLUSTER, &pctx);
 		ctx->flags |= E2F_FLAG_ABORT;
-		ext2fs_free_mem(&inode);
-		return;
+		goto endit;
 	}
 	block_buf = (char *) e2fsck_allocate_memory(ctx, fs->blocksize * 3,
 						    "block interate buffer");
@@ -699,18 +697,16 @@ void e2fsck_pass1(e2fsck_t ctx)
 	if (pctx.errcode) {
 		fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
 		ctx->flags |= E2F_FLAG_ABORT;
-		ext2fs_free_mem(&block_buf);
-		ext2fs_free_mem(&inode);
-		return;
+		goto endit;
 	}
 	ext2fs_inode_scan_flags(scan, EXT2_SF_SKIP_MISSING_ITABLE, 0);
 	ctx->stashed_inode = inode;
 	scan_struct.ctx = ctx;
 	scan_struct.block_buf = block_buf;
 	ext2fs_set_inode_callback(scan, scan_callback, &scan_struct);
-	if (ctx->progress)
-		if ((ctx->progress)(ctx, 1, 0, ctx->fs->group_desc_count))
-			return;
+	if (ctx->progress && ((ctx->progress)(ctx, 1, 0,
+					      ctx->fs->group_desc_count)))
+		goto endit;
 	if ((fs->super->s_wtime < fs->super->s_inodes_count) ||
 	    (fs->super->s_mtime < fs->super->s_inodes_count))
 		busted_fs_time = 1;
@@ -742,7 +738,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 		if (pctx.errcode) {
 			fix_problem(ctx, PR_1_ISCAN_ERROR, &pctx);
 			ctx->flags |= E2F_FLAG_ABORT;
-			return;
+			goto endit;
 		}
 		if (!ino)
 			break;
@@ -756,7 +752,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 				pctx.num = inode->i_links_count;
 				fix_problem(ctx, PR_1_ICOUNT_STORE, &pctx);
 				ctx->flags |= E2F_FLAG_ABORT;
-				return;
+				goto endit;
 			}
 		}
 
@@ -846,7 +842,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 				pctx.num = 4;
 				fix_problem(ctx, PR_1_ALLOCATE_BBITMAP_ERROR, &pctx);
 				ctx->flags |= E2F_FLAG_ABORT;
-				return;
+				goto endit;
 			}
 			pb.ino = EXT2_BAD_INO;
 			pb.num_blocks = pb.last_block = 0;
@@ -863,12 +859,12 @@ void e2fsck_pass1(e2fsck_t ctx)
 			if (pctx.errcode) {
 				fix_problem(ctx, PR_1_BLOCK_ITERATE, &pctx);
 				ctx->flags |= E2F_FLAG_ABORT;
-				return;
+				goto endit;
 			}
 			if (pb.bbcheck)
 				if (!fix_problem(ctx, PR_1_BBINODE_BAD_METABLOCK_PROMPT, &pctx)) {
 				ctx->flags |= E2F_FLAG_ABORT;
-				return;
+				goto endit;
 			}
 			ext2fs_mark_inode_bitmap2(ctx->inode_used_map, ino);
 			clear_problem_context(&pctx);
@@ -1146,17 +1142,18 @@ void e2fsck_pass1(e2fsck_t ctx)
 			check_blocks(ctx, &pctx, block_buf);
 
 		if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-			return;
+			goto endit;
 
 		if (process_inode_count >= ctx->process_inode_size) {
 			process_inodes(ctx, block_buf);
 
 			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
-				return;
+				goto endit;
 		}
 	}
 	process_inodes(ctx, block_buf);
 	ext2fs_close_inode_scan(scan);
+	scan = NULL;
 
 	/*
 	 * If any extended attribute blocks' reference counts need to
@@ -1195,7 +1192,7 @@ void e2fsck_pass1(e2fsck_t ctx)
 			if (!fix_problem(ctx, PR_1_RESIZE_INODE_CREATE,
 					 &pctx)) {
 				ctx->flags |= E2F_FLAG_ABORT;
-				return;
+				goto endit;
 			}
 			pctx.errcode = 0;
 		}
@@ -1233,10 +1230,15 @@ void e2fsck_pass1(e2fsck_t ctx)
 endit:
 	e2fsck_use_inode_shortcuts(ctx, 0);
 
-	ext2fs_free_mem(&block_buf);
-	ext2fs_free_mem(&inode);
+	if (scan)
+		ext2fs_close_inode_scan(scan);
+	if (block_buf)
+		ext2fs_free_mem(&block_buf);
+	if (inode)
+		ext2fs_free_mem(&inode);
 
-	print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
+	if ((ctx->flags & E2F_FLAG_SIGNAL_MASK) == 0)
+		print_resource_track(ctx, _("Pass 1"), &rtrack, ctx->fs->io);
 }
 
 /*
--- e2fsprogs-1.42.9.orig/e2fsck/pass5.c
+++ e2fsprogs-1.42.9/e2fsck/pass5.c
@@ -207,7 +207,6 @@ static void check_block_bitmaps(e2fsck_t
 	int		fixit, had_problem;
 	errcode_t	retval;
 	int		csum_flag;
-	int		skip_group = 0;
 	int	old_desc_blocks = 0;
 	int	count = 0;
 	int	cmp_block = 0;
@@ -260,9 +259,6 @@ redo_counts:
 	had_problem = 0;
 	save_problem = 0;
 	pctx.blk = pctx.blk2 = NO_BLK;
-	if (csum_flag &&
-	    (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
-		skip_group++;
 	for (i = B2C(fs->super->s_first_data_block);
 	     i < ext2fs_blocks_count(fs->super);
 	     i += EXT2FS_CLUSTER_RATIO(fs)) {
@@ -293,15 +289,11 @@ redo_counts:
 				actual_buf);
 		if (retval)
 			goto no_optimize;
-		if (ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT))
-			memset(bitmap_buf, 0, nbytes);
-		else {
-			retval = ext2fs_get_block_bitmap_range2(fs->block_map,
-					B2C(i), fs->super->s_clusters_per_group,
-					bitmap_buf);
-			if (retval)
-				goto no_optimize;
-		}
+		retval = ext2fs_get_block_bitmap_range2(fs->block_map,
+				B2C(i), fs->super->s_clusters_per_group,
+				bitmap_buf);
+		if (retval)
+			goto no_optimize;
 		if (memcmp(actual_buf, bitmap_buf, nbytes) != 0)
 			goto no_optimize;
 		n = ext2fs_bitcount(actual_buf, nbytes);
@@ -311,73 +303,7 @@ redo_counts:
 		goto next_group;
 	no_optimize:
 
-		if (skip_group) {
-			if (first_block_in_bg) {
-				super_blk = 0;
-				old_desc_blk = 0;
-				new_desc_blk = 0;
-				ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
-					 &old_desc_blk, &new_desc_blk, 0);
-
-				if (fs->super->s_feature_incompat &
-						EXT2_FEATURE_INCOMPAT_META_BG)
-					old_desc_blocks =
-						fs->super->s_first_meta_bg;
-				else
-					old_desc_blocks = fs->desc_blocks +
-					fs->super->s_reserved_gdt_blocks;
-
-				count = 0;
-				cmp_block = fs->super->s_clusters_per_group;
-				if (group == (int)fs->group_desc_count - 1)
-					cmp_block = EXT2FS_NUM_B2C(fs,
-						    ext2fs_group_blocks_count(fs, group));
-			}
-
-			bitmap = 0;
-			if (EQ_CLSTR(i, super_blk) ||
-			    (old_desc_blk && old_desc_blocks &&
-			     GE_CLSTR(i, old_desc_blk) &&
-			     LE_CLSTR(i, old_desc_blk + old_desc_blocks-1)) ||
-			    (new_desc_blk && EQ_CLSTR(i, new_desc_blk)) ||
-			    EQ_CLSTR(i, ext2fs_block_bitmap_loc(fs, group)) ||
-			    EQ_CLSTR(i, ext2fs_inode_bitmap_loc(fs, group)) ||
-			    (GE_CLSTR(i, ext2fs_inode_table_loc(fs, group)) &&
-			     LE_CLSTR(i, (ext2fs_inode_table_loc(fs, group) +
-					  fs->inode_blocks_per_group - 1)))) {
-				bitmap = 1;
-				actual = (actual != 0);
-				count++;
-				cmp_block--;
-			} else if ((EXT2FS_B2C(fs, i) - count -
-				    EXT2FS_B2C(fs, fs->super->s_first_data_block)) %
-				   fs->super->s_clusters_per_group == 0) {
-				/*
-				 * When the compare data blocks in block bitmap
-				 * are 0, count the free block,
-				 * skip the current block group.
-				 */
-				if (ext2fs_test_block_bitmap_range2(
-					    ctx->block_found_map,
-					    EXT2FS_B2C(fs, i),
-					    cmp_block)) {
-					/*
-					 * -1 means to skip the current block
-					 * group.
-					 */
-					blocks = fs->super->s_clusters_per_group - 1;
-					group_free = cmp_block;
-					free_blocks += cmp_block;
-					/*
-					 * The current block group's last block
-					 * is set to i.
-					 */
-					i += EXT2FS_C2B(fs, cmp_block - 1);
-					bitmap = 1;
-					goto do_counts;
-				}
-			}
-		} else if (redo_flag)
+		if (redo_flag)
 			bitmap = actual;
 		else
 			bitmap = ext2fs_fast_test_block_bitmap2(fs->block_map, i);
@@ -396,14 +322,15 @@ redo_counts:
 			 */
 			problem = PR_5_BLOCK_USED;
 
-			if (skip_group) {
+			if (ext2fs_bg_flags_test(fs, group,
+						 EXT2_BG_BLOCK_UNINIT)) {
 				struct problem_context pctx2;
 				pctx2.blk = i;
 				pctx2.group = group;
-				if (fix_problem(ctx, PR_5_BLOCK_UNINIT,&pctx2)){
-					ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
-					skip_group = 0;
-				}
+				if (fix_problem(ctx, PR_5_BLOCK_UNINIT,
+						&pctx2))
+					ext2fs_bg_flags_clear(fs, group,
+							EXT2_BG_BLOCK_UNINIT);
 			}
 		}
 		if (pctx.blk == NO_BLK) {
@@ -457,16 +384,10 @@ redo_counts:
 			group ++;
 			blocks = 0;
 			group_free = 0;
-			skip_group = 0;
 			if (ctx->progress)
 				if ((ctx->progress)(ctx, 5, group,
 						    fs->group_desc_count*2))
 					goto errout;
-			if (csum_flag &&
-			    (i != ext2fs_blocks_count(fs->super)-1) &&
-			    ext2fs_bg_flags_test(fs, group, 
-						EXT2_BG_BLOCK_UNINIT))
-				skip_group++;
 		}
 	}
 	if (pctx.blk != NO_BLK)
--- e2fsprogs-1.42.9.orig/e2fsck/problem.c
+++ e2fsprogs-1.42.9/e2fsck/problem.c
@@ -119,11 +119,13 @@ static struct e2fsck_problem problem_tab
 
 	/* Superblock corrupt */
 	{ PR_0_SB_CORRUPT,
-	  N_("\nThe @S could not be read or does not describe a correct ext2\n"
-	  "@f.  If the @v is valid and it really contains an ext2\n"
+	  N_("\nThe @S could not be read or does not describe a valid ext2/ext3/ext4\n"
+	  "@f.  If the @v is valid and it really contains an ext2/ext3/ext4\n"
 	  "@f (and not swap or ufs or something else), then the @S\n"
 	  "is corrupt, and you might try running e2fsck with an alternate @S:\n"
-	  "    e2fsck -b %S <@v>\n\n"),
+	  "    e2fsck -b 8193 <@v>\n"
+	  " or\n"
+	  "    e2fsck -b 32768 <@v>\n\n"),
 	  PROMPT_NONE, PR_FATAL },
 
 	/* Filesystem size is wrong */
--- e2fsprogs-1.42.9.orig/e2fsck/profile.c
+++ e2fsprogs-1.42.9/e2fsck/profile.c
@@ -320,6 +320,7 @@ profile_init(const char **files, profile
 	    for (fs = files; !PROFILE_LAST_FILESPEC(*fs); fs++) {
 		if (array)
 			free_list(array);
+		array = NULL;
 		retval = get_dirlist(*fs, &array);
 		if (retval == 0) {
 			if (!array)
@@ -1544,7 +1545,7 @@ profile_get_integer(profile_t profile, c
 	    /* Empty string is no good.  */
 	    return PROF_BAD_INTEGER;
 	errno = 0;
-	ret_long = strtol (value, &end_value, 10);
+	ret_long = strtol(value, &end_value, 0);
 
 	/* Overflow or underflow.  */
 	if ((ret_long == LONG_MIN || ret_long == LONG_MAX) && errno != 0)
@@ -1586,7 +1587,7 @@ profile_get_uint(profile_t profile, cons
 	    /* Empty string is no good.  */
 	    return PROF_BAD_INTEGER;
 	errno = 0;
-	ret_long = strtoul (value, &end_value, 10);
+	ret_long = strtoul(value, &end_value, 0);
 
 	/* Overflow or underflow.  */
 	if ((ret_long == ULONG_MAX) && errno != 0)
--- e2fsprogs-1.42.9.orig/e2fsck/quota.c
+++ e2fsprogs-1.42.9/e2fsck/quota.c
@@ -22,14 +22,18 @@ static void move_quota_inode(ext2_filsys
 			     ext2_ino_t to_ino, int qtype)
 {
 	struct ext2_inode	inode;
+	errcode_t		retval;
 	char			qf_name[QUOTA_NAME_LEN];
 
 	/* We need the inode bitmap to be loaded */
 	if (ext2fs_read_bitmaps(fs))
 		return;
 
-	if (ext2fs_read_inode(fs, from_ino, &inode))
+	retval = ext2fs_read_inode(fs, from_ino, &inode);
+	if (retval) {
+		com_err("ext2fs_read_inode", retval, _("in move_quota_inode"));
 		return;
+	}
 
 	inode.i_links_count = 1;
 	inode.i_mode = LINUX_S_IFREG | 0600;
@@ -38,7 +42,13 @@ static void move_quota_inode(ext2_filsys
 			EXT3_FEATURE_INCOMPAT_EXTENTS)
 		inode.i_flags |= EXT4_EXTENTS_FL;
 
-	ext2fs_write_new_inode(fs, to_ino, &inode);
+	retval = ext2fs_write_new_inode(fs, to_ino, &inode);
+	if (retval) {
+		com_err("ext2fs_write_new_inode", retval,
+			_("in move_quota_inode"));
+		return;
+	}
+
 	/* unlink the old inode */
 	quota_get_qf_name(qtype, QFMT_VFS_V1, qf_name);
 	ext2fs_unlink(fs, EXT2_ROOT_INO, qf_name, from_ino, 0);
--- e2fsprogs-1.42.9.orig/intl/Makefile.in
+++ e2fsprogs-1.42.9/intl/Makefile.in
@@ -59,6 +59,20 @@ mkinstalldirs = $(SHELL) $(MKINSTALLDIRS
 @ifNotGNUmake@ E = @E@
 @ifNotGNUmake@ Q = @Q@
 
+@ifGNUmake@ CHECK=sparse
+@ifGNUmake@ CHECK_OPTS=-Wsparse-all -Wno-transparent-union -Wno-return-void -Wno-undef -Wno-non-pointer-null
+@ifGNUmake@ ifeq ("$(C)", "2")
+@ifGNUmake@   CHECK_CMD=$(CHECK) $(CHECK_OPTS) -Wbitwise -D__CHECK_ENDIAN__
+@ifGNUmake@ else
+@ifGNUmake@   ifeq ("$(C)", "1")
+@ifGNUmake@     CHECK_CMD=$(CHECK) $(CHECK_OPTS)
+@ifGNUmake@    else
+@ifGNUmake@     CHECK_CMD=@true
+@ifGNUmake@   endif
+@ifGNUmake@ endif
+
+@ifNotGNUmake@ CHECK_CMD=@true
+
 l = @INTL_LIBTOOL_SUFFIX_PREFIX@
 
 AR = ar
--- e2fsprogs-1.42.9.orig/lib/blkid/cache.c
+++ e2fsprogs-1.42.9/lib/blkid/cache.c
@@ -167,8 +167,6 @@ void blkid_gc_cache(blkid_cache cache)
 
 	list_for_each_safe(p, pnext, &cache->bic_devs) {
 		blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
-		if (!p)
-			break;
 		if (stat(dev->bid_name, &st) < 0) {
 			DBG(DEBUG_CACHE,
 			    printf("freeing %s\n", dev->bid_name));
--- e2fsprogs-1.42.9.orig/lib/blkid/devname.c
+++ e2fsprogs-1.42.9/lib/blkid/devname.c
@@ -91,8 +91,6 @@ blkid_dev blkid_get_dev(blkid_cache cach
 		 */
 		list_for_each_safe(p, pnext, &cache->bic_devs) {
 			blkid_dev dev2;
-			if (!p)
-				break;
 			dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
 			if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
 				continue;
--- e2fsprogs-1.42.9.orig/lib/blkid/probe.c
+++ e2fsprogs-1.42.9/lib/blkid/probe.c
@@ -243,7 +243,7 @@ static int check_for_modules(const char
 	return (0);
 }
 
-static int linux_version_code()
+static int linux_version_code(void)
 {
 #ifdef __linux__
 	struct utsname	ut;
@@ -586,7 +586,7 @@ static int probe_fat(struct blkid_probe
 			int count;
 
 			next_sect_off = (next - 2) * vs->vs_cluster_size;
-			next_off = (start_data_sect + next_sect_off) *
+			next_off = (__u64) (start_data_sect + next_sect_off) *
 				sector_size;
 
 			dir = (struct vfat_dir_entry *)
@@ -601,7 +601,9 @@ static int probe_fat(struct blkid_probe
 				break;
 
 			/* get FAT entry */
-			fat_entry_off = (reserved * sector_size) +
+			fat_entry_off =
+				((unsigned int) reserved *
+				 (unsigned int) sector_size) +
 				(next * sizeof(__u32));
 			buf = get_buffer(probe, fat_entry_off, buf_size);
 			if (buf == NULL)
@@ -1003,7 +1005,8 @@ static int probe_udf(struct blkid_probe
 	   (block sizes larger than 2K will be null padded) */
 	for (bs = 1; bs < 16; bs++) {
 		isosb = (struct iso_volume_descriptor *)
-			get_buffer(probe, bs*2048+32768, sizeof(isosb));
+			get_buffer(probe, (blkid_loff_t) bs*2048+32768,
+				   sizeof(*isosb));
 		if (!isosb)
 			return 1;
 		if (isosb->vd_id[0])
@@ -1015,7 +1018,7 @@ static int probe_udf(struct blkid_probe
 		if (j > 1) {
 			isosb = (struct iso_volume_descriptor *)
 				get_buffer(probe, j*bs*2048+32768,
-					   sizeof(isosb));
+					   sizeof(*isosb));
 			if (!isosb)
 				return 1;
 		}
@@ -1223,7 +1226,7 @@ static int probe_hfsplus(struct blkid_pr
 		off = (alloc_first_block * 512) +
 			(embed_first_block * alloc_block_size);
 		buf = get_buffer(probe, off + (id->bim_kboff * 1024),
-				 sizeof(sbd));
+				 sizeof(*sbd));
 		if (!buf)
 			return 1;
 
@@ -1247,7 +1250,7 @@ static int probe_hfsplus(struct blkid_pr
 	memcpy(extents, hfsplus->cat_file.extents, sizeof(extents));
 	cat_block = blkid_be32(extents[0].start_block);
 
-	buf = get_buffer(probe, off + (cat_block * blocksize), 0x2000);
+	buf = get_buffer(probe, off + ((__u64) cat_block * blocksize), 0x2000);
 	if (!buf)
 		return 0;
 
@@ -1278,7 +1281,7 @@ static int probe_hfsplus(struct blkid_pr
 	if (ext == HFSPLUS_EXTENT_COUNT)
 		return 0;
 
-	leaf_off = (ext_block_start + leaf_block) * blocksize;
+	leaf_off = (__u64) (ext_block_start + leaf_block) * blocksize;
 
 	buf = get_buffer(probe, off + leaf_off, leaf_node_size);
 	if (!buf)
@@ -1360,7 +1363,7 @@ static int probe_lvm2(struct blkid_probe
 		return 1;
 	}
 
-	for (i=0, b=1, p=uuid, q= (char *) label->pv_uuid; i <= 32;
+	for (i=0, b=1, p=uuid, q= (char *) label->pv_uuid; i < LVM2_ID_LEN;
 	     i++, b <<= 1) {
 		if (b & 0x4444440)
 			*p++ = '-';
@@ -1580,7 +1583,7 @@ try_again:
 			continue;
 
 		idx = id->bim_kboff + (id->bim_sboff >> 10);
-		buf = get_buffer(&probe, idx << 10, 1024);
+		buf = get_buffer(&probe, (__u64) idx << 10, 1024);
 		if (!buf)
 			continue;
 
--- e2fsprogs-1.42.9.orig/lib/blkid/save.c
+++ e2fsprogs-1.42.9/lib/blkid/save.c
@@ -94,8 +94,10 @@ int blkid_flush_cache(blkid_cache cache)
 	if (ret == 0 && S_ISREG(st.st_mode)) {
 		tmp = malloc(strlen(filename) + 8);
 		if (tmp) {
+			mode_t save_umask = umask(022);
 			sprintf(tmp, "%s-XXXXXX", filename);
 			fd = mkstemp(tmp);
+			umask(save_umask);
 			if (fd >= 0) {
 				file = fdopen(fd, "w");
 				opened = tmp;
@@ -134,7 +136,7 @@ int blkid_flush_cache(blkid_cache cache)
 	fclose(file);
 	if (opened != filename) {
 		if (ret < 0) {
-			unlink(opened);
+			(void) unlink(opened);
 			DBG(DEBUG_SAVE,
 			    printf("unlinked temp cache %s\n", opened));
 		} else {
@@ -147,7 +149,8 @@ int blkid_flush_cache(blkid_cache cache)
 				link(filename, backup);
 				free(backup);
 			}
-			rename(opened, filename);
+			if (rename(opened, filename) < 0)
+				(void) unlink(opened);
 			DBG(DEBUG_SAVE,
 			    printf("moved temp cache %s\n", opened));
 		}
--- e2fsprogs-1.42.9.orig/lib/config.h.in
+++ e2fsprogs-1.42.9/lib/config.h.in
@@ -103,6 +103,9 @@
 /* Define to 1 if Ext2 ioctls present */
 #undef HAVE_EXT2_IOCTLS
 
+/* Define to 1 if you have the `fadvise64' function. */
+#undef HAVE_FADVISE64
+
 /* Define to 1 if you have the `fallocate' function. */
 #undef HAVE_FALLOCATE
 
@@ -121,6 +124,9 @@
 /* Define to 1 if you have the `ftruncate64' function. */
 #undef HAVE_FTRUNCATE64
 
+/* Define to 1 if you have the `futimes' function. */
+#undef HAVE_FUTIMES
+
 /* Define to 1 if you have the `fwprintf' function. */
 #undef HAVE_FWPRINTF
 
@@ -197,6 +203,9 @@
 /* Define to 1 if you have the <linux/fd.h> header file. */
 #undef HAVE_LINUX_FD_H
 
+/* Define to 1 if you have the <linux/loop.h> header file. */
+#undef HAVE_LINUX_LOOP_H
+
 /* Define to 1 if you have the <linux/major.h> header file. */
 #undef HAVE_LINUX_MAJOR_H
 
@@ -281,6 +290,9 @@
 /* Define to 1 if you have the `posix_fadvise' function. */
 #undef HAVE_POSIX_FADVISE
 
+/* Define to 1 if you have the `posix_fadvise64' function. */
+#undef HAVE_POSIX_FADVISE64
+
 /* Define to 1 if you have the `posix_memalign' function. */
 #undef HAVE_POSIX_MEMALIGN
 
@@ -381,6 +393,9 @@
 /* Define to 1 if you have the `strtoull' function. */
 #undef HAVE_STRTOULL
 
+/* Define to 1 if `st_atim' is a member of `struct stat'. */
+#undef HAVE_STRUCT_STAT_ST_ATIM
+
 /* Define to 1 if you have the `sync_file_range' function. */
 #undef HAVE_SYNC_FILE_RANGE
 
@@ -620,4 +635,4 @@
    <inttypes.h> don't define. */
 #undef uintmax_t
 
-#include "dirpaths.h"
+#include <dirpaths.h>
--- e2fsprogs-1.42.9.orig/lib/e2p/feature.c
+++ e2fsprogs-1.42.9/lib/e2p/feature.c
@@ -43,6 +43,8 @@ static struct feature feature_list[] = {
 			"lazy_bg" },
 	{	E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP,
 			"snapshot_bitmap" },
+	{	E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_SPARSE_SUPER2,
+			"sparse_super2" },
 
 	{	E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
 			"sparse_super" },
--- e2fsprogs-1.42.9.orig/lib/e2p/ls.c
+++ e2fsprogs-1.42.9/lib/e2p/ls.c
@@ -368,6 +368,14 @@ void list_super2(struct ext2_super_block
 			fprintf(f, "type %u\n", sb->s_jnl_backup_type);
 		}
 	}
+	if (sb->s_backup_bgs[0] || sb->s_backup_bgs[1]) {
+		fprintf(f, "Backup block groups:      ");
+		if (sb->s_backup_bgs[0])
+			fprintf(f, "%u ", sb->s_backup_bgs[0]);
+		if (sb->s_backup_bgs[1])
+			fprintf(f, "%u ", sb->s_backup_bgs[1]);
+		fputc('\n', f);
+	}
 	if (sb->s_snapshot_inum) {
 		fprintf(f, "Snapshot inode:           %u\n",
 			sb->s_snapshot_inum);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/Makefile.in
+++ e2fsprogs-1.42.9/lib/ext2fs/Makefile.in
@@ -225,72 +225,72 @@ ext2fs.pc: $(srcdir)/ext2fs.pc.in $(top_
 tst_badblocks: tst_badblocks.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_badblocks tst_badblocks.o $(STATIC_LIBEXT2FS) \
-		$(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_icount: $(srcdir)/icount.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_icount $(srcdir)/icount.c -DDEBUG $(ALL_CFLAGS) \
-		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_iscan: tst_iscan.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_iscan tst_iscan.o $(STATIC_LIBEXT2FS) \
-		$(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_getsize: tst_getsize.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_getsize tst_getsize.o $(STATIC_LIBEXT2FS) \
-		$(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS) \
 		$(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_ismounted $(srcdir)/ismounted.c \
 		$(STATIC_LIBEXT2FS) -DDEBUG $(ALL_CFLAGS) \
-		$(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_byteswap: tst_byteswap.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_byteswap tst_byteswap.o $(STATIC_LIBEXT2FS) \
-		$(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_bitops: tst_bitops.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_bitops tst_bitops.o $(ALL_CFLAGS) \
-		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_getsectsize: tst_getsectsize.o $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_sectgetsize tst_getsectsize.o \
-		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_types.o: $(srcdir)/tst_types.c ext2_types.h 
 
 tst_types: tst_types.o ext2_types.h 
 	$(E) "	LD $@"
-	$(Q) $(CC) -o tst_types tst_types.o 
+	$(Q) $(CC) -o tst_types tst_types.o $(SYSLIBS)
 
 tst_super_size.o: $(srcdir)/tst_super_size.c $(srcdir)/ext2_fs.h
 
 tst_super_size: tst_super_size.o
 	$(E) "	LD $@"
-	$(Q) $(CC) -o tst_super_size tst_super_size.o 
+	$(Q) $(CC) -o tst_super_size tst_super_size.o $(SYSLIBS)
 
 tst_fs_struct.o: $(srcdir)/tst_fs_struct.c $(srcdir)/ext2fs.h
 
 tst_fs_struct: tst_fs_struct.o
 	$(E) "	LD $@"
-	$(Q) $(CC) -o tst_fs_struct tst_fs_struct.o 
+	$(Q) $(CC) -o tst_fs_struct tst_fs_struct.o $(SYSLIBS)
 
 tst_inode_size.o: $(srcdir)/tst_inode_size.c $(srcdir)/ext2_fs.h
 
 tst_inode_size: tst_inode_size.o
 	$(E) "	LD $@"
-	$(Q) $(CC) -o tst_inode_size tst_inode_size.o 
+	$(Q) $(CC) -o tst_inode_size tst_inode_size.o $(SYSLIBS)
 
 ext2_tdbtool: tdbtool.o
 	$(E) "	LD $@"
-	$(Q) $(CC) -o ext2_tdbtool tdbtool.o tdb.o
+	$(Q) $(CC) -o ext2_tdbtool tdbtool.o tdb.o $(SYSLIBS)
 
 extent_dbg.c: $(srcdir)/extent_dbg.ct
 	$(E) "	MK_CMDS $<"
@@ -372,11 +372,13 @@ tst_bitmaps_cmd.c: tst_bitmaps_cmd.ct
 	$(E) "	MK_CMDS $@"
 	$(Q) DIR=$(srcdir) $(MK_CMDS) $(srcdir)/tst_bitmaps_cmd.ct
 
-tst_bitmaps: tst_bitmaps.o tst_bitmaps_cmd.o $(STATIC_LIBEXT2FS) \
-		$(DEPSTATIC_LIBSS) $(DEPSTATIC_LIBCOM_ERR)
+tst_bitmaps: tst_bitmaps.o tst_bitmaps_cmd.o $(srcdir)/blkmap64_rb.c \
+		$(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBSS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
-	$(Q) $(CC) -o $@ tst_bitmaps.o tst_bitmaps_cmd.o $(ALL_CFLAGS) \
-		$(STATIC_LIBEXT2FS) $(STATIC_LIBSS) $(STATIC_LIBCOM_ERR)
+	$(Q) $(CC) -o $@ tst_bitmaps.o tst_bitmaps_cmd.o \
+		-DDEBUG_RB $(srcdir)/blkmap64_rb.c $(ALL_CFLAGS) \
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBSS) $(STATIC_LIBCOM_ERR) \
+		$(SYSLIBS)
 
 tst_extents: $(srcdir)/extent.c $(DEBUG_OBJS) $(DEPSTATIC_LIBSS) \
 	$(STATIC_LIBE2P) $(DEPLIBUUID) $(DEPLIBBLKID) $(DEPSTATIC_LIBCOM_ERR)
@@ -384,27 +386,29 @@ tst_extents: $(srcdir)/extent.c $(DEBUG_
 	$(Q) $(CC) -o tst_extents $(srcdir)/extent.c \
 		$(ALL_CFLAGS) -DDEBUG $(DEBUG_OBJS) $(STATIC_LIBSS) \
 		$(STATIC_LIBE2P) $(STATIC_LIBEXT2FS) $(LIBBLKID) $(LIBUUID) \
-		$(STATIC_LIBCOM_ERR) -I $(top_srcdir)/debugfs
+		$(STATIC_LIBCOM_ERR) $(SYSLIBS) -I $(top_srcdir)/debugfs
 
 tst_inline: $(srcdir)/inline.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_inline $(srcdir)/inline.c $(ALL_CFLAGS) -DDEBUG \
-		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+		$(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) $(SYSLIBS)
 
 tst_csum: csum.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) $(STATIC_LIBE2P) \
 		$(top_srcdir)/lib/e2p/e2p.h
 	$(E) "	LD $@"
 	$(Q) $(CC) -o tst_csum $(srcdir)/csum.c -DDEBUG \
 		$(ALL_CFLAGS) $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
-		$(STATIC_LIBE2P)
+		$(STATIC_LIBE2P) $(SYSLIBS)
 
 tst_crc32c: $(srcdir)/crc32c.c $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR)
 	$(Q) $(CC) $(BUILD_LDFLAGS) $(ALL_CFLAGS) -o tst_crc32c $(srcdir)/crc32c.c \
-		-DUNITTEST $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
+		-DUNITTEST $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
+		$(SYSLIBS)
 
 mkjournal: mkjournal.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
 	$(E) "	LD $@"
-	$(Q) $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG $(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS)
+	$(Q) $(CC) -o mkjournal $(srcdir)/mkjournal.c -DDEBUG \
+		$(STATIC_LIBEXT2FS) $(LIBCOM_ERR) $(ALL_CFLAGS) $(SYSLIBS)
 
 check:: tst_bitops tst_badblocks tst_iscan tst_types tst_icount \
     tst_super_size tst_types tst_inode_size tst_csum tst_crc32c tst_bitmaps \
@@ -573,10 +577,11 @@ block.o: $(srcdir)/block.c $(top_builddi
  $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
 bmap.o: $(srcdir)/bmap.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
- $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fsP.h \
+ $(srcdir)/ext2fs.h $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.h $(srcdir)/ext2_io.h \
+ $(top_builddir)/lib/ext2fs/ext2_err.h $(srcdir)/ext2_ext_attr.h \
+ $(srcdir)/bitops.h
 check_desc.o: $(srcdir)/check_desc.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
@@ -671,7 +676,7 @@ fileio.o: $(srcdir)/fileio.c $(top_build
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
  $(srcdir)/ext2_fs.h $(srcdir)/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
  $(srcdir)/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
- $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h
+ $(srcdir)/ext2_ext_attr.h $(srcdir)/bitops.h $(srcdir)/ext2fsP.h
 finddev.o: $(srcdir)/finddev.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(srcdir)/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/ext2fs.h \
--- e2fsprogs-1.42.9.orig/lib/ext2fs/alloc.c
+++ e2fsprogs-1.42.9/lib/ext2fs/alloc.c
@@ -27,48 +27,17 @@
 #include "ext2fs.h"
 
 /*
- * Check for uninit block bitmaps and deal with them appropriately
+ * Clear the uninit block bitmap flag if necessary
  */
-static void check_block_uninit(ext2_filsys fs, ext2fs_block_bitmap map,
-			       dgrp_t group)
+static void clear_block_uninit(ext2_filsys fs, dgrp_t group)
 {
-	blk_t		i;
-	blk64_t		blk, super_blk, old_desc_blk, new_desc_blk;
-	int		old_desc_blocks;
-
 	if (!(EXT2_HAS_RO_COMPAT_FEATURE(fs->super,
 					 EXT4_FEATURE_RO_COMPAT_GDT_CSUM)) ||
 	    !(ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
 		return;
 
-	blk = ext2fs_group_first_block2(fs, group);
-
-	ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
-				  &old_desc_blk, &new_desc_blk, 0);
+	/* uninit block bitmaps are now initialized in read_bitmaps() */
 
-	if (fs->super->s_feature_incompat &
-	    EXT2_FEATURE_INCOMPAT_META_BG)
-		old_desc_blocks = fs->super->s_first_meta_bg;
-	else
-		old_desc_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
-
-	for (i=0; i < fs->super->s_blocks_per_group; i++, blk++)
-		ext2fs_fast_unmark_block_bitmap2(map, blk);
-
-	blk = ext2fs_group_first_block2(fs, group);
-	for (i=0; i < fs->super->s_blocks_per_group; i++, blk++) {
-		if ((blk == super_blk) ||
-		    (old_desc_blk && old_desc_blocks &&
-		     (blk >= old_desc_blk) &&
-		     (blk < old_desc_blk + old_desc_blocks)) ||
-		    (new_desc_blk && (blk == new_desc_blk)) ||
-		    (blk == ext2fs_block_bitmap_loc(fs, group)) ||
-		    (blk == ext2fs_inode_bitmap_loc(fs, group)) ||
-		    (blk >= ext2fs_inode_table_loc(fs, group) &&
-		     (blk < ext2fs_inode_table_loc(fs, group)
-		      + fs->inode_blocks_per_group)))
-			ext2fs_fast_mark_block_bitmap2(map, blk);
-	}
 	ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
 	ext2fs_group_desc_csum_set(fs, group);
 	ext2fs_mark_super_dirty(fs);
@@ -93,10 +62,11 @@ static void check_inode_uninit(ext2_fils
 		ext2fs_fast_unmark_inode_bitmap2(map, ino);
 
 	ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
+	/* Mimics what the kernel does */
+	ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
 	ext2fs_group_desc_csum_set(fs, group);
 	ext2fs_mark_ib_dirty(fs);
 	ext2fs_mark_super_dirty(fs);
-	check_block_uninit(fs, fs->block_map, group);
 }
 
 /*
@@ -167,8 +137,8 @@ errcode_t ext2fs_new_inode(ext2_filsys f
 errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
 			   ext2fs_block_bitmap map, blk64_t *ret)
 {
-	blk64_t	i;
-	int	c_ratio;
+	errcode_t retval;
+	blk64_t	b;
 
 	EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
 
@@ -178,29 +148,21 @@ errcode_t ext2fs_new_block2(ext2_filsys
 		return EXT2_ET_NO_BLOCK_BITMAP;
 	if (!goal || (goal >= ext2fs_blocks_count(fs->super)))
 		goal = fs->super->s_first_data_block;
-	i = goal;
-	c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
-	if (c_ratio > 1)
-		goal &= ~EXT2FS_CLUSTER_MASK(fs);
-	check_block_uninit(fs, map,
-			   (i - fs->super->s_first_data_block) /
-			   EXT2_BLOCKS_PER_GROUP(fs->super));
-	do {
-		if (((i - fs->super->s_first_data_block) %
-		     EXT2_BLOCKS_PER_GROUP(fs->super)) == 0)
-			check_block_uninit(fs, map,
-					   (i - fs->super->s_first_data_block) /
-					   EXT2_BLOCKS_PER_GROUP(fs->super));
-
-		if (!ext2fs_fast_test_block_bitmap2(map, i)) {
-			*ret = i;
-			return 0;
-		}
-		i = (i + c_ratio) & ~(c_ratio - 1);
-		if (i >= ext2fs_blocks_count(fs->super))
-			i = fs->super->s_first_data_block;
-	} while (i != goal);
-	return EXT2_ET_BLOCK_ALLOC_FAIL;
+	goal &= ~EXT2FS_CLUSTER_MASK(fs);
+
+	retval = ext2fs_find_first_zero_block_bitmap2(map,
+			goal, ext2fs_blocks_count(fs->super) - 1, &b);
+	if ((retval == ENOENT) && (goal != fs->super->s_first_data_block))
+		retval = ext2fs_find_first_zero_block_bitmap2(map,
+			fs->super->s_first_data_block, goal - 1, &b);
+	if (retval == ENOENT)
+		return EXT2_ET_BLOCK_ALLOC_FAIL;
+	if (retval)
+		return retval;
+
+	clear_block_uninit(fs, ext2fs_group_of_blk2(fs, b));
+	*ret = b;
+	return 0;
 }
 
 errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
--- e2fsprogs-1.42.9.orig/lib/ext2fs/alloc_sb.c
+++ e2fsprogs-1.42.9/lib/ext2fs/alloc_sb.c
@@ -65,8 +65,6 @@ int ext2fs_reserve_super_and_bgd(ext2_fi
 		ext2fs_mark_block_bitmap2(bmap, 0);
 
 	if (old_desc_blk) {
-		if (fs->super->s_reserved_gdt_blocks && fs->block_map == bmap)
-			ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
 		num_blocks = old_desc_blocks;
 		if (old_desc_blk + num_blocks >= ext2fs_blocks_count(fs->super))
 			num_blocks = ext2fs_blocks_count(fs->super) -
--- e2fsprogs-1.42.9.orig/lib/ext2fs/alloc_stats.c
+++ e2fsprogs-1.42.9/lib/ext2fs/alloc_stats.c
@@ -106,3 +106,44 @@ void ext2fs_set_block_alloc_stats_callba
 
 	fs->block_alloc_stats = func;
 }
+
+void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
+				    blk_t num, int inuse)
+{
+#ifndef OMIT_COM_ERR
+	if (blk + num > ext2fs_blocks_count(fs->super)) {
+		com_err("ext2fs_block_alloc_stats_range", 0,
+			"Illegal block range: %llu (%u) ",
+			(unsigned long long) blk, num);
+		return;
+	}
+#endif
+	if (inuse == 0)
+		return;
+	if (inuse > 0) {
+		ext2fs_mark_block_bitmap_range2(fs->block_map, blk, num);
+		inuse = 1;
+	} else {
+		ext2fs_unmark_block_bitmap_range2(fs->block_map, blk, num);
+		inuse = -1;
+	}
+	while (num) {
+		int group = ext2fs_group_of_blk2(fs, blk);
+		blk64_t last_blk = ext2fs_group_last_block2(fs, group);
+		blk_t n = num;
+
+		if (blk + num > last_blk)
+			n = last_blk - blk + 1;
+
+		ext2fs_bg_free_blocks_count_set(fs, group,
+			ext2fs_bg_free_blocks_count(fs, group) -
+			inuse*n/EXT2FS_CLUSTER_RATIO(fs));
+		ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
+		ext2fs_group_desc_csum_set(fs, group);
+		ext2fs_free_blocks_count_add(fs->super, -inuse * n);
+		blk += n;
+		num -= n;
+	}
+	ext2fs_mark_super_dirty(fs);
+	ext2fs_mark_bb_dirty(fs);
+}
--- e2fsprogs-1.42.9.orig/lib/ext2fs/alloc_tables.c
+++ e2fsprogs-1.42.9/lib/ext2fs/alloc_tables.c
@@ -83,9 +83,8 @@ static blk64_t flexbg_offset(ext2_filsys
 errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
 				      ext2fs_block_bitmap bmap)
 {
-	unsigned int	j;
 	errcode_t	retval;
-	blk64_t		group_blk, start_blk, last_blk, new_blk, blk;
+	blk64_t		group_blk, start_blk, last_blk, new_blk;
 	dgrp_t		last_grp = 0;
 	int		rem_grps = 0, flexbg_size = 0;
 
@@ -205,19 +204,12 @@ errcode_t ext2fs_allocate_group_table(ex
 						bmap, &new_blk);
 		if (retval)
 			return retval;
-		for (j=0, blk = new_blk;
-		     j < fs->inode_blocks_per_group;
-		     j++, blk++) {
-			ext2fs_mark_block_bitmap2(bmap, blk);
-			if (flexbg_size) {
-				dgrp_t gr = ext2fs_group_of_blk2(fs, blk);
-				ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
-				ext2fs_free_blocks_count_add(fs->super, -1);
-				ext2fs_bg_flags_clear(fs, gr,
-						     EXT2_BG_BLOCK_UNINIT);
-				ext2fs_group_desc_csum_set(fs, gr);
-			}
-		}
+		if (flexbg_size)
+			ext2fs_block_alloc_stats_range(fs, new_blk,
+				       fs->inode_blocks_per_group, +1);
+		else
+			ext2fs_mark_block_bitmap_range2(fs->block_map,
+					new_blk, fs->inode_blocks_per_group);
 		ext2fs_inode_table_loc_set(fs, group, new_blk);
 	}
 	ext2fs_group_desc_csum_set(fs, group);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/bitops.h
+++ e2fsprogs-1.42.9/lib/ext2fs/bitops.h
@@ -157,6 +157,14 @@ extern errcode_t ext2fs_find_first_zero_
 						      ext2_ino_t start,
 						      ext2_ino_t end,
 						      ext2_ino_t *out);
+extern errcode_t ext2fs_find_first_set_block_bitmap2(ext2fs_block_bitmap bitmap,
+						     blk64_t start,
+						     blk64_t end,
+						     blk64_t *out);
+extern errcode_t ext2fs_find_first_set_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+						      ext2_ino_t start,
+						      ext2_ino_t end,
+						      ext2_ino_t *out);
 extern blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap);
 extern ext2_ino_t ext2fs_get_inode_bitmap_start2(ext2fs_inode_bitmap bitmap);
 extern blk64_t ext2fs_get_block_bitmap_end2(ext2fs_block_bitmap bitmap);
@@ -198,6 +206,9 @@ extern void ext2fs_unmark_block_bitmap_r
 extern errcode_t ext2fs_find_first_zero_generic_bmap(ext2fs_generic_bitmap bitmap,
 						     __u64 start, __u64 end,
 						     __u64 *out);
+extern errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
+						    __u64 start, __u64 end,
+						    __u64 *out);
 
 /*
  * The inline routines themselves...
@@ -602,6 +613,36 @@ _INLINE_ errcode_t ext2fs_find_first_zer
 	if (!rv)
 		*out = (ext2_ino_t) o;
 	return rv;
+}
+
+_INLINE_ errcode_t ext2fs_find_first_set_block_bitmap2(ext2fs_block_bitmap bitmap,
+						       blk64_t start,
+						       blk64_t end,
+						       blk64_t *out)
+{
+	__u64 o;
+	errcode_t rv;
+
+	rv = ext2fs_find_first_set_generic_bmap((ext2fs_generic_bitmap) bitmap,
+						start, end, &o);
+	if (!rv)
+		*out = o;
+	return rv;
+}
+
+_INLINE_ errcode_t ext2fs_find_first_set_inode_bitmap2(ext2fs_inode_bitmap bitmap,
+						       ext2_ino_t start,
+						       ext2_ino_t end,
+						       ext2_ino_t *out)
+{
+	__u64 o;
+	errcode_t rv;
+
+	rv = ext2fs_find_first_set_generic_bmap((ext2fs_generic_bitmap) bitmap,
+						start, end, &o);
+	if (!rv)
+		*out = (ext2_ino_t) o;
+	return rv;
 }
 
 _INLINE_ blk64_t ext2fs_get_block_bitmap_start2(ext2fs_block_bitmap bitmap)
--- e2fsprogs-1.42.9.orig/lib/ext2fs/blkmap64_ba.c
+++ e2fsprogs-1.42.9/lib/ext2fs/blkmap64_ba.c
@@ -328,12 +328,6 @@ static errcode_t ba_find_first_zero(ext2
 	const unsigned char *pos;
 	unsigned long max_loop_count, i;
 
-	if (start < bitmap->start || end > bitmap->end || start > end)
-		return EINVAL;
-
-	if (bitmap->cluster_bits)
-		return EINVAL;
-
 	/* scan bits until we hit a byte boundary */
 	while ((bitpos & 0x7) != 0 && count > 0) {
 		if (!ext2fs_test_bit64(bitpos, bp->bitarray)) {
@@ -397,6 +391,80 @@ static errcode_t ba_find_first_zero(ext2
 	return ENOENT;
 }
 
+/* Find the first one bit between start and end, inclusive. */
+static errcode_t ba_find_first_set(ext2fs_generic_bitmap bitmap,
+				    __u64 start, __u64 end, __u64 *out)
+{
+	ext2fs_ba_private bp = (ext2fs_ba_private)bitmap->private;
+	unsigned long bitpos = start - bitmap->start;
+	unsigned long count = end - start + 1;
+	int byte_found = 0; /* whether a != 0xff byte has been found */
+	const unsigned char *pos;
+	unsigned long max_loop_count, i;
+
+	/* scan bits until we hit a byte boundary */
+	while ((bitpos & 0x7) != 0 && count > 0) {
+		if (ext2fs_test_bit64(bitpos, bp->bitarray)) {
+			*out = bitpos + bitmap->start;
+			return 0;
+		}
+		bitpos++;
+		count--;
+	}
+
+	if (!count)
+		return ENOENT;
+
+	pos = ((unsigned char *)bp->bitarray) + (bitpos >> 3);
+	/* scan bytes until 8-byte (64-bit) aligned */
+	while (count >= 8 && (((unsigned long)pos) & 0x07)) {
+		if (*pos != 0) {
+			byte_found = 1;
+			break;
+		}
+		pos++;
+		count -= 8;
+		bitpos += 8;
+	}
+
+	if (!byte_found) {
+		max_loop_count = count >> 6; /* 8-byte blocks */
+		i = max_loop_count;
+		while (i) {
+			if (*((const __u64 *)pos) != 0)
+				break;
+			pos += 8;
+			i--;
+		}
+		count -= 64 * (max_loop_count - i);
+		bitpos += 64 * (max_loop_count - i);
+
+		max_loop_count = count >> 3;
+		i = max_loop_count;
+		while (i) {
+			if (*pos != 0) {
+				byte_found = 1;
+				break;
+			}
+			pos++;
+			i--;
+		}
+		count -= 8 * (max_loop_count - i);
+		bitpos += 8 * (max_loop_count - i);
+	}
+
+	/* Here either count < 8 or byte_found == 1. */
+	while (count-- > 0) {
+		if (ext2fs_test_bit64(bitpos, bp->bitarray)) {
+			*out = bitpos + bitmap->start;
+			return 0;
+		}
+		bitpos++;
+	}
+
+	return ENOENT;
+}
+
 struct ext2_bitmap_ops ext2fs_blkmap64_bitarray = {
 	.type = EXT2FS_BMAP64_BITARRAY,
 	.new_bmap = ba_new_bmap,
@@ -413,5 +481,6 @@ struct ext2_bitmap_ops ext2fs_blkmap64_b
 	.get_bmap_range = ba_get_bmap_range,
 	.clear_bmap = ba_clear_bmap,
 	.print_stats = ba_print_stats,
-	.find_first_zero = ba_find_first_zero
+	.find_first_zero = ba_find_first_zero,
+	.find_first_set = ba_find_first_set
 };
--- e2fsprogs-1.42.9.orig/lib/ext2fs/blkmap64_rb.c
+++ e2fsprogs-1.42.9/lib/ext2fs/blkmap64_rb.c
@@ -135,7 +135,7 @@ err_out:
 }
 #else
 #define check_tree(root, msg) do {} while (0)
-#define print_tree(root, msg) do {} while (0)
+#define print_tree(root) do {} while (0)
 #endif
 
 static void rb_get_new_extent(struct bmap_rb_extent **ext, __u64 start,
@@ -569,11 +569,14 @@ static int rb_remove_extent(__u64 start,
 static int rb_mark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
 {
 	struct ext2fs_rb_private *bp;
+	int retval;
 
 	bp = (struct ext2fs_rb_private *) bitmap->private;
 	arg -= bitmap->start;
 
-	return rb_insert_extent(arg, 1, bp);
+	retval = rb_insert_extent(arg, 1, bp);
+	check_tree(&bp->root, __func__);
+	return retval;
 }
 
 static int rb_unmark_bmap(ext2fs_generic_bitmap bitmap, __u64 arg)
@@ -610,6 +613,7 @@ static void rb_mark_bmap_extent(ext2fs_g
 	arg -= bitmap->start;
 
 	rb_insert_extent(arg, num, bp);
+	check_tree(&bp->root, __func__);
 }
 
 static void rb_unmark_bmap_extent(ext2fs_generic_bitmap bitmap, __u64 arg,
@@ -714,11 +718,14 @@ static errcode_t rb_set_bmap_range(ext2f
 
 		rb_insert_extent(start + first_set - bitmap->start,
 				 i - first_set, bp);
+		check_tree(&bp->root, __func__);
 		first_set = -1;
 	}
-	if (first_set != -1)
+	if (first_set != -1) {
 		rb_insert_extent(start + first_set - bitmap->start,
 				 num - first_set, bp);
+		check_tree(&bp->root, __func__);
+	}
 
 	return 0;
 }
@@ -799,6 +806,94 @@ static void rb_clear_bmap(ext2fs_generic
 	bp->rcursor = NULL;
 	bp->rcursor_next = NULL;
 	bp->wcursor = NULL;
+	check_tree(&bp->root, __func__);
+}
+
+static errcode_t rb_find_first_zero(ext2fs_generic_bitmap bitmap,
+				   __u64 start, __u64 end, __u64 *out)
+{
+	struct rb_node *parent = NULL, **n;
+	struct rb_node *node, *next;
+	struct ext2fs_rb_private *bp;
+	struct bmap_rb_extent *ext;
+	int retval = 1;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	n = &bp->root.rb_node;
+	start -= bitmap->start;
+	end -= bitmap->start;
+
+	if (start > end)
+		return EINVAL;
+
+	if (EXT2FS_RB_EMPTY_ROOT(&bp->root))
+		return ENOENT;
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+		} else if (start >= (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+		} else if (ext->start + ext->count <= end) {
+			*out = ext->start + ext->count + bitmap->start;
+			return 0;
+		} else
+			return ENOENT;
+	}
+
+	*out = start + bitmap->start;
+	return 0;
+}
+
+static errcode_t rb_find_first_set(ext2fs_generic_bitmap bitmap,
+				   __u64 start, __u64 end, __u64 *out)
+{
+	struct rb_node *parent = NULL, **n;
+	struct rb_node *node, *next;
+	struct ext2fs_rb_private *bp;
+	struct bmap_rb_extent *ext;
+	int retval = 1;
+
+	bp = (struct ext2fs_rb_private *) bitmap->private;
+	n = &bp->root.rb_node;
+	start -= bitmap->start;
+	end -= bitmap->start;
+
+	if (start > end)
+		return EINVAL;
+
+	if (EXT2FS_RB_EMPTY_ROOT(&bp->root))
+		return ENOENT;
+
+	while (*n) {
+		parent = *n;
+		ext = node_to_extent(parent);
+		if (start < ext->start) {
+			n = &(*n)->rb_left;
+		} else if (start >= (ext->start + ext->count)) {
+			n = &(*n)->rb_right;
+		} else {
+			/* The start bit is set */
+			*out = start + bitmap->start;
+			return 0;
+		}
+	}
+
+	node = parent;
+	ext = node_to_extent(node);
+	if (ext->start < start) {
+		node = ext2fs_rb_next(node);
+		if (node == NULL)
+			return ENOENT;
+		ext = node_to_extent(node);
+	}
+	if (ext->start <= end) {
+		*out = ext->start + bitmap->start;
+		return 0;
+	}
+	return ENOENT;
 }
 
 #ifdef BMAP_STATS
@@ -819,7 +914,6 @@ static void rb_print_stats(ext2fs_generi
 
 	bp = (struct ext2fs_rb_private *) bitmap->private;
 
-	node = ext2fs_rb_first(&bp->root);
 	for (node = ext2fs_rb_first(&bp->root); node != NULL;
 	     node = ext2fs_rb_next(node)) {
 		ext = node_to_extent(node);
@@ -883,4 +977,6 @@ struct ext2_bitmap_ops ext2fs_blkmap64_r
 	.get_bmap_range = rb_get_bmap_range,
 	.clear_bmap = rb_clear_bmap,
 	.print_stats = rb_print_stats,
+	.find_first_zero = rb_find_first_zero,
+	.find_first_set = rb_find_first_set,
 };
--- e2fsprogs-1.42.9.orig/lib/ext2fs/bmap64.h
+++ e2fsprogs-1.42.9/lib/ext2fs/bmap64.h
@@ -94,6 +94,10 @@ struct ext2_bitmap_ops {
 	 * May be NULL, in which case a generic function is used. */
 	errcode_t (*find_first_zero)(ext2fs_generic_bitmap bitmap,
 				     __u64 start, __u64 end, __u64 *out);
+	/* Find the first set bit between start and end, inclusive.
+	 * May be NULL, in which case a generic function is used. */
+	errcode_t (*find_first_set)(ext2fs_generic_bitmap bitmap,
+				    __u64 start, __u64 end, __u64 *out);
 };
 
 extern struct ext2_bitmap_ops ext2fs_blkmap64_bitarray;
--- e2fsprogs-1.42.9.orig/lib/ext2fs/closefs.c
+++ e2fsprogs-1.42.9/lib/ext2fs/closefs.c
@@ -35,8 +35,16 @@ static int test_root(unsigned int a, uns
 
 int ext2fs_bg_has_super(ext2_filsys fs, dgrp_t group)
 {
-	if (!(fs->super->s_feature_ro_compat &
-	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER) || group <= 1)
+	if (group == 0)
+		return 1;
+	if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+		if (group == fs->super->s_backup_bgs[0] ||
+		    group == fs->super->s_backup_bgs[1])
+			return 1;
+		return 0;
+	}
+	if ((group <= 1) || !(fs->super->s_feature_ro_compat &
+			      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER))
 		return 1;
 	if (!(group & 1))
 		return 0;
--- e2fsprogs-1.42.9.orig/lib/ext2fs/csum.c
+++ e2fsprogs-1.42.9/lib/ext2fs/csum.c
@@ -36,7 +36,7 @@ __u16 ext2fs_group_desc_csum(ext2_filsys
 							 group);
 	size_t size = EXT2_DESC_SIZE(fs->super);
 	size_t offset;
-	__u16 crc;
+	__u16 crc = 0;
 
 	if (fs->super->s_feature_ro_compat & EXT4_FEATURE_RO_COMPAT_GDT_CSUM) {
 		size_t offset = offsetof(struct ext2_group_desc, bg_checksum);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/ext2_fs.h
+++ e2fsprogs-1.42.9/lib/ext2fs/ext2_fs.h
@@ -645,7 +645,8 @@ struct ext2_super_block {
 	__u32	s_usr_quota_inum;	/* inode number of user quota file */
 	__u32	s_grp_quota_inum;	/* inode number of group quota file */
 	__u32	s_overhead_blocks;	/* overhead blocks/clusters in fs */
-	__u32   s_reserved[108];        /* Padding to the end of the block */
+	__u32	s_backup_bgs[2];	/* If sparse_super2 enabled */
+	__u32   s_reserved[106];        /* Padding to the end of the block */
 	__u32	s_checksum;		/* crc32c(superblock) */
 };
 
@@ -696,6 +697,7 @@ struct ext2_super_block {
 #define EXT2_FEATURE_COMPAT_LAZY_BG		0x0040
 /* #define EXT2_FEATURE_COMPAT_EXCLUDE_INODE	0x0080 not used, legacy */
 #define EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP	0x0100
+#define EXT4_FEATURE_COMPAT_SPARSE_SUPER2	0x0200
 
 
 #define EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER	0x0001
--- e2fsprogs-1.42.9.orig/lib/ext2fs/ext2fs.h
+++ e2fsprogs-1.42.9/lib/ext2fs/ext2fs.h
@@ -550,7 +550,8 @@ typedef struct ext2_icount *ext2_icount_
 					 EXT3_FEATURE_COMPAT_HAS_JOURNAL|\
 					 EXT2_FEATURE_COMPAT_RESIZE_INODE|\
 					 EXT2_FEATURE_COMPAT_DIR_INDEX|\
-					 EXT2_FEATURE_COMPAT_EXT_ATTR)
+					 EXT2_FEATURE_COMPAT_EXT_ATTR|\
+					 EXT4_FEATURE_COMPAT_SPARSE_SUPER2)
 
 /* This #ifdef is temporary until compression is fully supported */
 #ifdef ENABLE_COMPRESSION
@@ -683,6 +684,8 @@ void ext2fs_inode_alloc_stats2(ext2_fils
 			       int inuse, int isdir);
 void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse);
 void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse);
+void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
+				    blk_t num, int inuse);
 
 /* alloc_tables.c */
 extern errcode_t ext2fs_allocate_tables(ext2_filsys fs);
@@ -1177,6 +1180,9 @@ extern errcode_t ext2fs_set_generic_bitm
 extern errcode_t ext2fs_find_first_zero_generic_bitmap(ext2fs_generic_bitmap bitmap,
 						       __u32 start, __u32 end,
 						       __u32 *out);
+extern errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
+						       __u32 start, __u32 end,
+						       __u32 *out);
 
 /* gen_bitmap64.c */
 
@@ -1365,6 +1371,8 @@ extern errcode_t ext2fs_add_journal_devi
 					   ext2_filsys journal_dev);
 extern errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks,
 					  int flags);
+extern errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
+					   blk64_t goal, int flags);
 extern int ext2fs_default_journal_size(__u64 num_blocks);
 
 /* openfs.c */
@@ -1375,6 +1383,11 @@ extern errcode_t ext2fs_open2(const char
 			      int flags, int superblock,
 			      unsigned int block_size, io_manager manager,
 			      ext2_filsys *ret_fs);
+/*
+ * The dgrp_t argument to these two functions is not actually a group number
+ * but a block number offset within a group table!  Convert with the formula
+ * (group_number / groups_per_block).
+ */
 extern blk64_t ext2fs_descriptor_block_loc2(ext2_filsys fs,
 					blk64_t group_block, dgrp_t i);
 extern blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block,
--- e2fsprogs-1.42.9.orig/lib/ext2fs/extent.c
+++ e2fsprogs-1.42.9/lib/ext2fs/extent.c
@@ -1092,8 +1092,10 @@ errcode_t ext2fs_extent_insert(ext2_exte
 			ix++;
 			path->left--;
 		}
-	} else
+	} else {
 		ix = EXT_FIRST_INDEX(eh);
+		path->left = -1;
+	}
 
 	path->curr = ix;
 
--- e2fsprogs-1.42.9.orig/lib/ext2fs/gen_bitmap.c
+++ e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap.c
@@ -527,6 +527,28 @@ errcode_t ext2fs_find_first_zero_generic
 	return ENOENT;
 }
 
+errcode_t ext2fs_find_first_set_generic_bitmap(ext2fs_generic_bitmap bitmap,
+					       __u32 start, __u32 end,
+					       __u32 *out)
+{
+	blk_t b;
+
+	if (start < bitmap->start || end > bitmap->end || start > end) {
+		ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+		return EINVAL;
+	}
+
+	while (start <= end) {
+		b = ext2fs_test_bit(start - bitmap->start, bitmap->bitmap);
+		if (b) {
+			*out = start;
+			return 0;
+		}
+		start++;
+	}
+
+	return ENOENT;
+}
 
 int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap,
 				   blk_t block, int num)
--- e2fsprogs-1.42.9.orig/lib/ext2fs/gen_bitmap64.c
+++ e2fsprogs-1.42.9/lib/ext2fs/gen_bitmap64.c
@@ -801,17 +801,14 @@ errcode_t ext2fs_find_first_zero_generic
 					      __u64 start, __u64 end, __u64 *out)
 {
 	int b;
+	__u64 cstart, cend, cout;
+	errcode_t retval;
 
 	if (!bitmap)
 		return EINVAL;
 
-	if (EXT2FS_IS_64_BITMAP(bitmap) && bitmap->bitmap_ops->find_first_zero)
-		return bitmap->bitmap_ops->find_first_zero(bitmap, start,
-							   end, out);
-
 	if (EXT2FS_IS_32_BITMAP(bitmap)) {
 		blk_t blk = 0;
-		errcode_t retval;
 
 		if (((start) & ~0xffffffffULL) ||
 		    ((end) & ~0xffffffffULL)) {
@@ -829,22 +826,83 @@ errcode_t ext2fs_find_first_zero_generic
 	if (!EXT2FS_IS_64_BITMAP(bitmap))
 		return EINVAL;
 
-	start >>= bitmap->cluster_bits;
-	end >>= bitmap->cluster_bits;
+	cstart = start >> bitmap->cluster_bits;
+	cend = end >> bitmap->cluster_bits;
 
-	if (start < bitmap->start || end > bitmap->end || start > end) {
+	if (cstart < bitmap->start || cend > bitmap->end || start > end) {
 		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
 		return EINVAL;
 	}
 
-	while (start <= end) {
-		b = bitmap->bitmap_ops->test_bmap(bitmap, start);
-		if (!b) {
-			*out = start << bitmap->cluster_bits;
-			return 0;
+	if (bitmap->bitmap_ops->find_first_zero) {
+		retval = bitmap->bitmap_ops->find_first_zero(bitmap, cstart,
+							     cend, &cout);
+		if (retval)
+			return retval;
+	found:
+		cout <<= bitmap->cluster_bits;
+		*out = (cout >= start) ? cout : start;
+		return 0;
+	}
+
+	for (cout = cstart; cout <= cend; cout++)
+		if (!bitmap->bitmap_ops->test_bmap(bitmap, cout))
+			goto found;
+
+	return ENOENT;
+}
+
+errcode_t ext2fs_find_first_set_generic_bmap(ext2fs_generic_bitmap bitmap,
+					     __u64 start, __u64 end, __u64 *out)
+{
+	int b;
+	__u64 cstart, cend, cout;
+	errcode_t retval;
+
+	if (!bitmap)
+		return EINVAL;
+
+	if (EXT2FS_IS_32_BITMAP(bitmap)) {
+		blk_t blk = 0;
+
+		if (((start) & ~0xffffffffULL) ||
+		    ((end) & ~0xffffffffULL)) {
+			ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, start);
+			return EINVAL;
 		}
-		start++;
+
+		retval = ext2fs_find_first_set_generic_bitmap(bitmap, start,
+							      end, &blk);
+		if (retval == 0)
+			*out = blk;
+		return retval;
 	}
 
+	if (!EXT2FS_IS_64_BITMAP(bitmap))
+		return EINVAL;
+
+	cstart = start >> bitmap->cluster_bits;
+	cend = end >> bitmap->cluster_bits;
+
+	if (cstart < bitmap->start || cend > bitmap->end || start > end) {
+		warn_bitmap(bitmap, EXT2FS_TEST_ERROR, start);
+		return EINVAL;
+	}
+
+	if (bitmap->bitmap_ops->find_first_set) {
+		retval = bitmap->bitmap_ops->find_first_set(bitmap, cstart,
+							    cend, &cout);
+		if (retval)
+			return retval;
+	found:
+		cout <<= bitmap->cluster_bits;
+		*out = (cout >= start) ? cout : start;
+		return 0;
+	}
+
+	for (cout = cstart; cout <= cend; cout++)
+		if (bitmap->bitmap_ops->test_bmap(bitmap, cout))
+			goto found;
+
 	return ENOENT;
 }
--- e2fsprogs-1.42.9.orig/lib/ext2fs/icount.c
+++ e2fsprogs-1.42.9/lib/ext2fs/icount.c
@@ -181,6 +181,7 @@ errcode_t ext2fs_create_icount_tdb(ext2_
 	errcode_t	retval;
 	char 		*fn, uuid[40];
 	ext2_ino_t	num_inodes;
+	mode_t		save_umask;
 	int		fd;
 
 	retval = alloc_icount(fs, flags,  &icount);
@@ -192,10 +193,14 @@ errcode_t ext2fs_create_icount_tdb(ext2_
 		goto errout;
 	uuid_unparse(fs->super->s_uuid, uuid);
 	sprintf(fn, "%s/%s-icount-XXXXXX", tdb_dir, uuid);
+	icount->tdb_fn = fn;
+	save_umask = umask(077);
 	fd = mkstemp(fn);
-	if (fd < 0)
-		return fd;
-
+	if (fd < 0) {
+		retval = errno;
+		goto errout;
+	}
+	umask(save_umask);
 	/*
 	 * This is an overestimate of the size that we will need; the
 	 * ideal value is the number of used inodes with a count
@@ -206,18 +211,15 @@ errcode_t ext2fs_create_icount_tdb(ext2_
 	 */
 	num_inodes = fs->super->s_inodes_count - fs->super->s_free_inodes_count;
 
-	icount->tdb_fn = fn;
 	icount->tdb = tdb_open(fn, num_inodes, TDB_NOLOCK | TDB_NOSYNC,
 			       O_RDWR | O_CREAT | O_TRUNC, 0600);
-	if (icount->tdb) {
-		close(fd);
-		*ret = icount;
-		return 0;
-	}
-
-	retval = errno;
 	close(fd);
-
+	if (icount->tdb == NULL) {
+		retval = errno;
+		goto errout;
+	}
+	*ret = icount;
+	return 0;
 errout:
 	ext2fs_free_icount(icount);
 	return(retval);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/initialize.c
+++ e2fsprogs-1.42.9/lib/ext2fs/initialize.c
@@ -173,6 +173,8 @@ errcode_t ext2fs_initialize(const char *
 	set_field(s_raid_stripe_width, 0);	/* default stripe width: 0 */
 	set_field(s_log_groups_per_flex, 0);
 	set_field(s_flags, 0);
+	assign_field(s_backup_bgs[0]);
+	assign_field(s_backup_bgs[1]);
 	if (super->s_feature_incompat & ~EXT2_LIB_FEATURE_INCOMPAT_SUPP) {
 		retval = EXT2_ET_UNSUPP_FEATURE;
 		goto cleanup;
@@ -422,6 +424,21 @@ ipg_retry:
 	 * count.
 	 */
 
+	/* Set up the locations of the backup superblocks */
+	if (super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+		if (super->s_backup_bgs[0] >= fs->group_desc_count)
+			super->s_backup_bgs[0] = fs->group_desc_count - 1;
+		if (super->s_backup_bgs[1] >= fs->group_desc_count)
+			super->s_backup_bgs[1] = fs->group_desc_count - 1;
+		if (super->s_backup_bgs[0] == super->s_backup_bgs[1])
+			super->s_backup_bgs[1] = 0;
+		if (super->s_backup_bgs[0] > super->s_backup_bgs[1]) {
+			__u32 t = super->s_backup_bgs[0];
+			super->s_backup_bgs[0] = super->s_backup_bgs[1];
+			super->s_backup_bgs[1] = t;
+		}
+	}
+
 	retval = ext2fs_get_mem(strlen(fs->device_name) + 80, &buf);
 	if (retval)
 		goto cleanup;
--- e2fsprogs-1.42.9.orig/lib/ext2fs/mkjournal.c
+++ e2fsprogs-1.42.9/lib/ext2fs/mkjournal.c
@@ -295,13 +295,43 @@ static int mkjournal_proc(ext2_filsys	fs
 }
 
 /*
+ * Calculate the initial goal block to be roughly at the middle of the
+ * filesystem.  Pick a group that has the largest number of free
+ * blocks.
+ */
+static blk64_t get_midpoint_journal_block(ext2_filsys fs)
+{
+	dgrp_t	group, start, end, i, log_flex;
+
+	group = ext2fs_group_of_blk2(fs, (ext2fs_blocks_count(fs->super) -
+					 fs->super->s_first_data_block) / 2);
+	log_flex = 1 << fs->super->s_log_groups_per_flex;
+	if (fs->super->s_log_groups_per_flex && (group > log_flex)) {
+		group = group & ~(log_flex - 1);
+		while ((group < fs->group_desc_count) &&
+		       ext2fs_bg_free_blocks_count(fs, group) == 0)
+			group++;
+		if (group == fs->group_desc_count)
+			group = 0;
+		start = group;
+	} else
+		start = (group > 0) ? group-1 : group;
+	end = ((group+1) < fs->group_desc_count) ? group+1 : group;
+	group = start;
+	for (i = start + 1; i <= end; i++)
+		if (ext2fs_bg_free_blocks_count(fs, i) >
+		    ext2fs_bg_free_blocks_count(fs, group))
+			group = i;
+	return ext2fs_group_first_block2(fs, group);
+}
+
+/*
  * This function creates a journal using direct I/O routines.
  */
 static errcode_t write_journal_inode(ext2_filsys fs, ext2_ino_t journal_ino,
-				     blk_t num_blocks, int flags)
+				     blk_t num_blocks, blk64_t goal, int flags)
 {
 	char			*buf;
-	dgrp_t			group, start, end, i, log_flex;
 	errcode_t		retval;
 	struct ext2_inode	inode;
 	unsigned long long	inode_size;
@@ -328,6 +358,7 @@ static errcode_t write_journal_inode(ext
 	es.err = 0;
 	es.flags = flags;
 	es.zero_count = 0;
+	es.goal = (goal != ~0ULL) ? goal : get_midpoint_journal_block(fs);
 
 	if (fs->super->s_feature_incompat & EXT3_FEATURE_INCOMPAT_EXTENTS) {
 		inode.i_flags |= EXT4_EXTENTS_FL;
@@ -335,32 +366,6 @@ static errcode_t write_journal_inode(ext
 			goto out2;
 	}
 
-	/*
-	 * Set the initial goal block to be roughly at the middle of
-	 * the filesystem.  Pick a group that has the largest number
-	 * of free blocks.
-	 */
-	group = ext2fs_group_of_blk2(fs, (ext2fs_blocks_count(fs->super) -
-					 fs->super->s_first_data_block) / 2);
-	log_flex = 1 << fs->super->s_log_groups_per_flex;
-	if (fs->super->s_log_groups_per_flex && (group > log_flex)) {
-		group = group & ~(log_flex - 1);
-		while ((group < fs->group_desc_count) &&
-		       ext2fs_bg_free_blocks_count(fs, group) == 0)
-			group++;
-		if (group == fs->group_desc_count)
-			group = 0;
-		start = group;
-	} else
-		start = (group > 0) ? group-1 : group;
-	end = ((group+1) < fs->group_desc_count) ? group+1 : group;
-	group = start;
-	for (i=start+1; i <= end; i++)
-		if (ext2fs_bg_free_blocks_count(fs, i) >
-		    ext2fs_bg_free_blocks_count(fs, group))
-			group = i;
-
-	es.goal = ext2fs_group_first_block2(fs, group);
 	retval = ext2fs_block_iterate3(fs, journal_ino, BLOCK_FLAG_APPEND,
 				       0, mkjournal_proc, &es);
 	if (es.err) {
@@ -491,7 +496,8 @@ errcode_t ext2fs_add_journal_device(ext2
  * POSIX routines if the filesystem is mounted, or using direct I/O
  * functions if it is not.
  */
-errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags)
+errcode_t ext2fs_add_journal_inode2(ext2_filsys fs, blk_t num_blocks,
+				    blk64_t goal, int flags)
 {
 	errcode_t		retval;
 	ext2_ino_t		journal_ino;
@@ -582,7 +588,7 @@ errcode_t ext2fs_add_journal_inode(ext2_
 		}
 		journal_ino = EXT2_JOURNAL_INO;
 		if ((retval = write_journal_inode(fs, journal_ino,
-						  num_blocks, flags)))
+						  num_blocks, goal, flags)))
 			return retval;
 	}
 
@@ -600,6 +606,12 @@ errout:
 	return retval;
 }
 
+errcode_t ext2fs_add_journal_inode(ext2_filsys fs, blk_t num_blocks, int flags)
+{
+	return ext2fs_add_journal_inode2(fs, num_blocks, ~0ULL, flags);
+}
+
+
 #ifdef DEBUG
 main(int argc, char **argv)
 {
--- e2fsprogs-1.42.9.orig/lib/ext2fs/openfs.c
+++ e2fsprogs-1.42.9/lib/ext2fs/openfs.c
@@ -37,17 +37,24 @@ blk64_t ext2fs_descriptor_block_loc2(ext
 				     dgrp_t i)
 {
 	int	bg;
-	int	has_super = 0;
+	int	has_super = 0, group_zero_adjust = 0;
 	blk64_t	ret_blk;
 
+	/*
+	 * On a bigalloc FS with 1K blocks, block 0 is reserved for non-ext4
+	 * stuff, so adjust for that if we're being asked for group 0.
+	 */
+	if (i == 0 && fs->blocksize == 1024 && EXT2FS_CLUSTER_RATIO(fs) > 1)
+		group_zero_adjust = 1;
+
 	if (!(fs->super->s_feature_incompat & EXT2_FEATURE_INCOMPAT_META_BG) ||
 	    (i < fs->super->s_first_meta_bg))
-		return (group_block + i + 1);
+		return group_block + i + 1 + group_zero_adjust;
 
 	bg = EXT2_DESC_PER_BLOCK(fs->super) * i;
 	if (ext2fs_bg_has_super(fs, bg))
 		has_super = 1;
-	ret_blk = ext2fs_group_first_block2(fs, bg) + has_super;
+	ret_blk = ext2fs_group_first_block2(fs, bg);
 	/*
 	 * If group_block is not the normal value, we're trying to use
 	 * the backup group descriptors and superblock --- so use the
@@ -57,10 +64,21 @@ blk64_t ext2fs_descriptor_block_loc2(ext
 	 * have the infrastructure in place to do that.
 	 */
 	if (group_block != fs->super->s_first_data_block &&
-	    ((ret_blk + fs->super->s_blocks_per_group) <
-	     ext2fs_blocks_count(fs->super)))
+	    ((ret_blk + has_super + fs->super->s_blocks_per_group) <
+	     ext2fs_blocks_count(fs->super))) {
 		ret_blk += fs->super->s_blocks_per_group;
-	return ret_blk;
+
+		/*
+		 * If we're going to jump forward a block group, make sure
+		 * that we adjust has_super to account for the next group's
+		 * backup superblock (or lack thereof).
+		 */
+		if (ext2fs_bg_has_super(fs, bg + 1))
+			has_super = 1;
+		else
+			has_super = 0;
+	}
+	return ret_blk + has_super + group_zero_adjust;
 }
 
 blk_t ext2fs_descriptor_block_loc(ext2_filsys fs, blk_t group_block, dgrp_t i)
@@ -102,6 +120,7 @@ errcode_t ext2fs_open2(const char *name,
 	unsigned int	blocks_per_group, io_flags;
 	blk64_t		group_block, blk;
 	char		*dest, *cp;
+	int		group_zero_adjust = 0;
 #ifdef WORDS_BIGENDIAN
 	unsigned int	groups_per_block;
 	struct ext2_group_desc *gdp;
@@ -342,8 +361,19 @@ errcode_t ext2fs_open2(const char *name,
 		goto cleanup;
 	if (!group_block)
 		group_block = fs->super->s_first_data_block;
+	/*
+	 * On a FS with a 1K blocksize, block 0 is reserved for bootloaders
+	 * so we must increment block numbers to any group 0 items.
+	 *
+	 * However, we cannot touch group_block directly because in the meta_bg
+	 * case, the ext2fs_descriptor_block_loc2() function will interpret
+	 * group_block != s_first_data_block to mean that we want to access the
+	 * backup group descriptors.  This is not what we want if the caller
+	 * set superblock == 0 (i.e. auto-detect the superblock), which is
+	 * what's going on here.
+	 */
 	if (group_block == 0 && fs->blocksize == 1024)
-		group_block = 1; /* Deal with 1024 blocksize && bigalloc */
+		group_zero_adjust = 1;
 	dest = (char *) fs->group_desc;
 #ifdef WORDS_BIGENDIAN
 	groups_per_block = EXT2_DESC_PER_BLOCK(fs->super);
@@ -353,7 +383,8 @@ errcode_t ext2fs_open2(const char *name,
 	else
 		first_meta_bg = fs->desc_blocks;
 	if (first_meta_bg) {
-		retval = io_channel_read_blk(fs->io, group_block+1,
+		retval = io_channel_read_blk(fs->io, group_block +
+					     group_zero_adjust + 1,
 					     first_meta_bg, dest);
 		if (retval)
 			goto cleanup;
--- e2fsprogs-1.42.9.orig/lib/ext2fs/qcow2.c
+++ e2fsprogs-1.42.9/lib/ext2fs/qcow2.c
@@ -235,8 +235,10 @@ int qcow2_write_raw_image(int qcow2_fd,
 	}
 
 	/* Resize the output image to the filesystem size */
-	if (ext2fs_llseek(raw_fd, img.image_size - 1, SEEK_SET) < 0)
-		return errno;
+	if (ext2fs_llseek(raw_fd, img.image_size - 1, SEEK_SET) < 0) {
+		ret = errno;
+		goto out;
+	}
 
 	((char *)copy_buf)[0] = 0;
 	size = write(raw_fd, copy_buf, 1);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/res_gdt.c
+++ e2fsprogs-1.42.9/lib/ext2fs/res_gdt.c
@@ -31,6 +31,19 @@ static unsigned int list_backups(ext2_fi
 	int mult = 3;
 	unsigned int ret;
 
+	if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+		if (*min == 1) {
+			*min += 1;
+			if (fs->super->s_backup_bgs[0])
+				return fs->super->s_backup_bgs[0];
+		}
+		if (*min == 2) {
+			*min += 1;
+			if (fs->super->s_backup_bgs[1])
+				return fs->super->s_backup_bgs[1];
+		}
+		return fs->group_desc_count;
+	}
 	if (!(fs->super->s_feature_ro_compat &
 	      EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER)) {
 		ret = *min;
--- e2fsprogs-1.42.9.orig/lib/ext2fs/rw_bitmaps.c
+++ e2fsprogs-1.42.9/lib/ext2fs/rw_bitmaps.c
@@ -145,6 +145,43 @@ errout:
 	return retval;
 }
 
+static errcode_t mark_uninit_bg_group_blocks(ext2_filsys fs)
+{
+	dgrp_t			i;
+	blk64_t			blk;
+	ext2fs_block_bitmap	bmap = fs->block_map;
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		if (!ext2fs_bg_flags_test(fs, i, EXT2_BG_BLOCK_UNINIT))
+			continue;
+
+		ext2fs_reserve_super_and_bgd(fs, i, bmap);
+
+		/*
+		 * Mark the blocks used for the inode table
+		 */
+		blk = ext2fs_inode_table_loc(fs, i);
+		if (blk)
+			ext2fs_mark_block_bitmap_range2(bmap, blk,
+						fs->inode_blocks_per_group);
+
+		/*
+		 * Mark block used for the block bitmap
+		 */
+		blk = ext2fs_block_bitmap_loc(fs, i);
+		if (blk)
+			ext2fs_mark_block_bitmap2(bmap, blk);
+
+		/*
+		 * Mark block used for the inode bitmap
+		 */
+		blk = ext2fs_inode_bitmap_loc(fs, i);
+		if (blk)
+			ext2fs_mark_block_bitmap2(bmap, blk);
+	}
+	return 0;
+}
+
 static errcode_t read_bitmaps(ext2_filsys fs, int do_inode, int do_block)
 {
 	dgrp_t i;
@@ -292,6 +329,14 @@ static errcode_t read_bitmaps(ext2_filsy
 			ino_itr += inode_nbytes << 3;
 		}
 	}
+
+	/* Mark group blocks for any BLOCK_UNINIT groups */
+	if (do_block) {
+		retval = mark_uninit_bg_group_blocks(fs);
+		if (retval)
+			goto cleanup;
+	}
+
 success_cleanup:
 	if (inode_bitmap)
 		ext2fs_free_mem(&inode_bitmap);
--- e2fsprogs-1.42.9.orig/lib/ext2fs/swapfs.c
+++ e2fsprogs-1.42.9/lib/ext2fs/swapfs.c
@@ -99,6 +99,8 @@ void ext2fs_swap_super(struct ext2_super
 	}
 	for (; i < 17; i++)
 		sb->s_jnl_blocks[i] = ext2fs_swab32(sb->s_jnl_blocks[i]);
+	sb->s_backup_bgs[0] = ext2fs_swab32(sb->s_backup_bgs[0]);
+	sb->s_backup_bgs[1] = ext2fs_swab32(sb->s_backup_bgs[1]);
 }
 
 void ext2fs_swap_group_desc2(ext2_filsys fs, struct ext2_group_desc *gdp)
--- e2fsprogs-1.42.9.orig/lib/ext2fs/tst_bitmaps.c
+++ e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps.c
@@ -436,6 +436,39 @@ void do_ffzb(int argc, char *argv[])
 	printf("First unmarked block is %llu\n", out);
 }
 
+void do_ffsb(int argc, char *argv[])
+{
+	unsigned int start, end;
+	int err;
+	errcode_t retval;
+	blk64_t out;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 3 && argc != 3) {
+		com_err(argv[0], 0, "Usage: ffsb <start> <end>");
+		return;
+	}
+
+	start = parse_ulong(argv[1], argv[0], "start", &err);
+	if (err)
+		return;
+
+	end = parse_ulong(argv[2], argv[0], "end", &err);
+	if (err)
+		return;
+
+	retval = ext2fs_find_first_set_block_bitmap2(test_fs->block_map,
+						      start, end, &out);
+	if (retval) {
+		printf("ext2fs_find_first_set_block_bitmap2() returned %s\n",
+		       error_message(retval));
+		return;
+	}
+	printf("First marked block is %llu\n", out);
+}
+
 
 void do_zerob(int argc, char *argv[])
 {
@@ -559,6 +592,38 @@ void do_ffzi(int argc, char *argv[])
 	printf("First unmarked inode is %u\n", out);
 }
 
+void do_ffsi(int argc, char *argv[])
+{
+	unsigned int start, end;
+	int err;
+	errcode_t retval;
+	ext2_ino_t out;
+
+	if (check_fs_open(argv[0]))
+		return;
+
+	if (argc != 3 && argc != 3) {
+		com_err(argv[0], 0, "Usage: ffsi <start> <end>");
+		return;
+	}
+
+	start = parse_ulong(argv[1], argv[0], "start", &err);
+	if (err)
+		return;
+
+	end = parse_ulong(argv[2], argv[0], "end", &err);
+	if (err)
+		return;
+
+	retval = ext2fs_find_first_set_inode_bitmap2(test_fs->inode_map,
+						     start, end, &out);
+	if (retval) {
+		printf("ext2fs_find_first_set_inode_bitmap2() returned %s\n",
+		       error_message(retval));
+		return;
+	}
+	printf("First marked inode is %u\n", out);
+}
 
 void do_zeroi(int argc, char *argv[])
 {
--- e2fsprogs-1.42.9.orig/lib/ext2fs/tst_bitmaps_cmd.ct
+++ e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmd.ct
@@ -24,6 +24,9 @@ request do_testb, "Test block",
 request do_ffzb, "Find first zero block",
 	find_first_zero_block, ffzb;
 
+request do_ffsb, "Find first set block",
+	find_first_set_block, ffsb;
+
 request do_zerob, "Clear block bitmap",
 	clear_block_bitmap, zerob;
 
@@ -39,6 +42,9 @@ request do_testi, "Test inode",
 request do_ffzi, "Find first zero inode",
 	find_first_zero_inode, ffzi;
 
+request do_ffsi, "Find first set inode",
+	find_first_set_inode, ffsi;
+
 request do_zeroi, "Clear inode bitmap",
 	clear_inode_bitmap, zeroi;
 
--- e2fsprogs-1.42.9.orig/lib/ext2fs/tst_bitmaps_cmds
+++ e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_cmds
@@ -19,8 +19,17 @@ dump_bb
 ffzb 11 16
 ffzb 12 16
 ffzb 12 20
+ffsb 0 127
+ffsb 1 128
+ffsb 1 127
+ffsb 1 10
+ffsb 1 11
+ffsb 12 12
+ffsb 13 12
+ffsb 12 15
 clearb 13
 ffzb 12 20
+ffsb 13 18
 setb 13
 clearb 12 7
 testb 12 7
@@ -42,8 +51,15 @@ dump_ib
 ffzi 1 6
 ffzi 2 5
 ffzi 2 6
+ffsi 0 31
+ffsi 1 33
+ffsi 1 32
+ffsi 2 32
+ffsi 6 32
 cleari 4
 ffzi 2 6
+ffsi 4 32
+ffsi 5 32
 zeroi
 testi 5
 seti 5
@@ -95,5 +111,38 @@ clearb 2
 clearb 3
 clearb 7
 dump_bb
+ffsb 14 127
+ffsb 15 127
+ffsb 36 127
+ffsb 32 127
+ffsb 52 127
+ffsb 53 127
+ffsb 46 127
+ffsb 45 127
+ffsb 41 127
+ffsb 20 127
+ffsb 1 127
+ffsb 2 127
+ffsb 3 127
+ffsb 4 127
+ffsb 5 127
+ffsb 6 127
+ffsb 7 127
+ffsb 8 127
+ffzb 1 127
+ffzb 2 127
+ffzb 3 127
+ffzb 4 127
+ffzb 5 127
+ffzb 6 127
+ffzb 7 127
+ffzb 8 127
+ffzb 45 127
+ffzb 46 127
+ffzb 47 127
+ffzb 48 127
+ffzb 49 127
+ffzb 50 127
+ffzb 51 127
 quit
 
--- e2fsprogs-1.42.9.orig/lib/ext2fs/tst_bitmaps_exp
+++ e2fsprogs-1.42.9/lib/ext2fs/tst_bitmaps_exp
@@ -43,10 +43,28 @@ tst_bitmaps: ffzb 12 16
 ext2fs_find_first_zero_block_bitmap2() returned No such file or directory
 tst_bitmaps: ffzb 12 20
 First unmarked block is 17
+tst_bitmaps: ffsb 0 127
+ext2fs_find_first_set_block_bitmap2() returned Invalid argument
+tst_bitmaps: ffsb 1 128
+ext2fs_find_first_set_block_bitmap2() returned Invalid argument
+tst_bitmaps: ffsb 1 127
+First marked block is 12
+tst_bitmaps: ffsb 1 10
+ext2fs_find_first_set_block_bitmap2() returned No such file or directory
+tst_bitmaps: ffsb 1 11
+ext2fs_find_first_set_block_bitmap2() returned No such file or directory
+tst_bitmaps: ffsb 12 12
+First marked block is 12
+tst_bitmaps: ffsb 13 12
+ext2fs_find_first_set_block_bitmap2() returned Invalid argument
+tst_bitmaps: ffsb 12 15
+First marked block is 12
 tst_bitmaps: clearb 13
 Clearing block 13, was set before
 tst_bitmaps: ffzb 12 20
 First unmarked block is 13
+tst_bitmaps: ffsb 13 18
+First marked block is 14
 tst_bitmaps: setb 13
 Setting block 13, was clear before
 tst_bitmaps: clearb 12 7
@@ -91,10 +109,24 @@ tst_bitmaps: ffzi 2 5
 ext2fs_find_first_zero_inode_bitmap2() returned No such file or directory
 tst_bitmaps: ffzi 2 6
 First unmarked inode is 6
+tst_bitmaps: ffsi 0 31
+ext2fs_find_first_set_inode_bitmap2() returned Invalid argument
+tst_bitmaps: ffsi 1 33
+ext2fs_find_first_set_inode_bitmap2() returned Invalid argument
+tst_bitmaps: ffsi 1 32
+First marked inode is 2
+tst_bitmaps: ffsi 2 32
+First marked inode is 2
+tst_bitmaps: ffsi 6 32
+ext2fs_find_first_set_inode_bitmap2() returned No such file or directory
 tst_bitmaps: cleari 4
 Clearing inode 4, was set before
 tst_bitmaps: ffzi 2 6
 First unmarked inode is 4
+tst_bitmaps: ffsi 4 32
+First marked inode is 5
+tst_bitmaps: ffsi 5 32
+First marked inode is 5
 tst_bitmaps: zeroi
 Clearing inode bitmap.
 tst_bitmaps: testi 5
@@ -207,5 +239,71 @@ Clearing block 7, was set before
 tst_bitmaps: dump_bb
 block bitmap: b92a85e6c4680d000000000000000000
 bits set: 25
+tst_bitmaps: ffsb 14 127
+First marked block is 14
+tst_bitmaps: ffsb 15 127
+First marked block is 17
+tst_bitmaps: ffsb 36 127
+First marked block is 39
+tst_bitmaps: ffsb 32 127
+First marked block is 32
+tst_bitmaps: ffsb 52 127
+First marked block is 52
+tst_bitmaps: ffsb 53 127
+ext2fs_find_first_set_block_bitmap2() returned No such file or directory
+tst_bitmaps: ffsb 46 127
+First marked block is 46
+tst_bitmaps: ffsb 45 127
+First marked block is 46
+tst_bitmaps: ffsb 41 127
+First marked block is 44
+tst_bitmaps: ffsb 20 127
+First marked block is 24
+tst_bitmaps: ffsb 1 127
+First marked block is 1
+tst_bitmaps: ffsb 2 127
+First marked block is 4
+tst_bitmaps: ffsb 3 127
+First marked block is 4
+tst_bitmaps: ffsb 4 127
+First marked block is 4
+tst_bitmaps: ffsb 5 127
+First marked block is 5
+tst_bitmaps: ffsb 6 127
+First marked block is 6
+tst_bitmaps: ffsb 7 127
+First marked block is 8
+tst_bitmaps: ffsb 8 127
+First marked block is 8
+tst_bitmaps: ffzb 1 127
+First unmarked block is 2
+tst_bitmaps: ffzb 2 127
+First unmarked block is 2
+tst_bitmaps: ffzb 3 127
+First unmarked block is 3
+tst_bitmaps: ffzb 4 127
+First unmarked block is 7
+tst_bitmaps: ffzb 5 127
+First unmarked block is 7
+tst_bitmaps: ffzb 6 127
+First unmarked block is 7
+tst_bitmaps: ffzb 7 127
+First unmarked block is 7
+tst_bitmaps: ffzb 8 127
+First unmarked block is 9
+tst_bitmaps: ffzb 45 127
+First unmarked block is 45
+tst_bitmaps: ffzb 46 127
+First unmarked block is 48
+tst_bitmaps: ffzb 47 127
+First unmarked block is 48
+tst_bitmaps: ffzb 48 127
+First unmarked block is 48
+tst_bitmaps: ffzb 49 127
+First unmarked block is 50
+tst_bitmaps: ffzb 50 127
+First unmarked block is 50
+tst_bitmaps: ffzb 51 127
+First unmarked block is 53
 tst_bitmaps: quit
 tst_bitmaps: 
--- e2fsprogs-1.42.9.orig/lib/ext2fs/tst_super_size.c
+++ e2fsprogs-1.42.9/lib/ext2fs/tst_super_size.c
@@ -135,7 +135,8 @@ int main(int argc, char **argv)
 	check_field(s_usr_quota_inum, 4);
 	check_field(s_grp_quota_inum, 4);
 	check_field(s_overhead_blocks, 4);
-	check_field(s_reserved, 108 * 4);
+	check_field(s_backup_bgs, 8);
+	check_field(s_reserved, 106 * 4);
 	check_field(s_checksum, 4);
 	do_field("Superblock end", 0, 0, cur_offset, 1024);
 #endif
--- e2fsprogs-1.42.9.orig/lib/ext2fs/unix_io.c
+++ e2fsprogs-1.42.9/lib/ext2fs/unix_io.c
@@ -931,10 +931,10 @@ static errcode_t unix_discard(io_channel
 
 	if (channel->flags & CHANNEL_FLAGS_BLOCK_DEVICE) {
 #ifdef BLKDISCARD
-		__uint64_t range[2];
+		__u64 range[2];
 
-		range[0] = (__uint64_t)(block) * channel->block_size;
-		range[1] = (__uint64_t)(count) * channel->block_size;
+		range[0] = (__u64)(block) * channel->block_size;
+		range[1] = (__u64)(count) * channel->block_size;
 
 		ret = ioctl(data->dev, BLKDISCARD, &range);
 #else
--- e2fsprogs-1.42.9.orig/lib/quota/Makefile.in
+++ e2fsprogs-1.42.9/lib/quota/Makefile.in
@@ -135,27 +135,29 @@ mkquota.o: $(srcdir)/mkquota.c $(top_bui
  $(srcdir)/quotaio_tree.h $(srcdir)/quotaio_v2.h $(srcdir)/mkquota.h \
  $(top_srcdir)/lib/../e2fsck/dict.h $(srcdir)/common.h
 quotaio.o: $(srcdir)/quotaio.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h $(srcdir)/quotaio.h \
- $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_builddir)/lib/ext2fs/ext2_types.h \
- $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
- $(top_srcdir)/lib/et/com_err.h $(top_srcdir)/lib/ext2fs/ext2_io.h \
- $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.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)/dqblk_v2.h $(srcdir)/quotaio_tree.h
 quotaio_tree.o: $(srcdir)/quotaio_tree.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h $(srcdir)/quotaio_tree.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio_tree.h \
  $(srcdir)/quotaio.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
- $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.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)/dqblk_v2.h
 quotaio_v2.o: $(srcdir)/quotaio_v2.c $(top_builddir)/lib/config.h \
- $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h $(srcdir)/quotaio_v2.h \
+ $(top_builddir)/lib/dirpaths.h $(srcdir)/common.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(srcdir)/quotaio_v2.h \
  $(srcdir)/quotaio.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
- $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
- $(top_srcdir)/lib/ext2fs/ext3_extents.h $(top_srcdir)/lib/et/com_err.h \
- $(top_srcdir)/lib/ext2fs/ext2_io.h $(top_builddir)/lib/ext2fs/ext2_err.h \
+ $(top_srcdir)/lib/ext2fs/ext2_fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.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)/dqblk_v2.h $(srcdir)/quotaio_tree.h
 dict.o: $(srcdir)/../../e2fsck/dict.c $(top_builddir)/lib/config.h \
--- e2fsprogs-1.42.9.orig/lib/quota/common.h
+++ e2fsprogs-1.42.9/lib/quota/common.h
@@ -7,6 +7,13 @@
 #ifndef __QUOTA_COMMON_H__
 #define __QUOTA_COMMON_H__
 
+#if EXT2_FLAT_INCLUDES
+#include "e2_types.h"
+#else
+#include <ext2fs/ext2_types.h>
+#endif /* EXT2_FLAT_INCLUDES */
+
+
 #ifndef __attribute__
 # if !defined __GNUC__ || __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) || __STRICT_ANSI__
 #  define __attribute__(x)
--- e2fsprogs-1.42.9.orig/lib/quota/mkquota.c
+++ e2fsprogs-1.42.9/lib/quota/mkquota.c
@@ -89,8 +89,13 @@ void quota_set_sb_inum(ext2_filsys fs, e
 errcode_t quota_remove_inode(ext2_filsys fs, int qtype)
 {
 	ext2_ino_t qf_ino;
+	errcode_t	retval;
 
-	ext2fs_read_bitmaps(fs);
+	retval = ext2fs_read_bitmaps(fs);
+	if (retval) {
+		log_err("Couldn't read bitmaps: %s", error_message(retval));
+		return retval;
+	}
 	qf_ino = (qtype == USRQUOTA) ? fs->super->s_usr_quota_inum :
 		fs->super->s_grp_quota_inum;
 	quota_set_sb_inum(fs, 0, qtype);
@@ -100,7 +105,11 @@ errcode_t quota_remove_inode(ext2_filsys
 
 	ext2fs_mark_super_dirty(fs);
 	fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
-	ext2fs_write_bitmaps(fs);
+	retval = ext2fs_write_bitmaps(fs);
+	if (retval) {
+		log_err("Couldn't write bitmaps: %s", error_message(retval));
+		return retval;
+	}
 	return 0;
 }
 
@@ -133,11 +142,16 @@ errcode_t quota_write_inode(quota_ctx_t
 	fs = qctx->fs;
 	retval = ext2fs_get_mem(sizeof(struct quota_handle), &h);
 	if (retval) {
-		log_err("Unable to allocate quota handle");
+		log_err("Unable to allocate quota handle: %s",
+			error_message(retval));
 		goto out;
 	}
 
-	ext2fs_read_bitmaps(fs);
+	retval = ext2fs_read_bitmaps(fs);
+	if (retval) {
+		log_err("Couldn't read bitmaps: %s", error_message(retval));
+		goto out;
+	}
 
 	for (i = 0; i < MAXQUOTAS; i++) {
 		if ((qtype != -1) && (i != qtype))
@@ -171,7 +185,11 @@ errcode_t quota_write_inode(quota_ctx_t
 		fs->flags &= ~EXT2_FLAG_SUPER_ONLY;
 	}
 
-	ext2fs_write_bitmaps(fs);
+	retval = ext2fs_write_bitmaps(fs);
+	if (retval) {
+		log_err("Couldn't write bitmaps: %s", error_message(retval));
+		goto out;
+	}
 out:
 	if (h)
 		ext2fs_free_mem(&h);
--- e2fsprogs-1.42.9.orig/lib/quota/quotaio.c
+++ e2fsprogs-1.42.9/lib/quota/quotaio.c
@@ -30,8 +30,8 @@ static const char * const basenames[] =
 
 /* Header in all newer quotafiles */
 struct disk_dqheader {
-	u_int32_t dqh_magic;
-	u_int32_t dqh_version;
+	__u32 dqh_magic;
+	__u32 dqh_version;
 } __attribute__ ((packed));
 
 /**
--- e2fsprogs-1.42.9.orig/lib/quota/quotaio_tree.c
+++ e2fsprogs-1.42.9/lib/quota/quotaio_tree.c
@@ -59,7 +59,7 @@ static inline void mark_quotafile_info_d
 }
 
 /* Read given block */
-static void read_blk(struct quota_handle *h, uint blk, dqbuf_t buf)
+static void read_blk(struct quota_handle *h, unsigned int blk, dqbuf_t buf)
 {
 	int err;
 
@@ -72,7 +72,7 @@ static void read_blk(struct quota_handle
 }
 
 /* Write block */
-static int write_blk(struct quota_handle *h, uint blk, dqbuf_t buf)
+static int write_blk(struct quota_handle *h, unsigned int blk, dqbuf_t buf)
 {
 	int err;
 
@@ -117,7 +117,8 @@ static int get_free_dqblk(struct quota_h
 }
 
 /* Put given block to free list */
-static void put_free_dqblk(struct quota_handle *h, dqbuf_t buf, uint blk)
+static void put_free_dqblk(struct quota_handle *h, dqbuf_t buf,
+			   unsigned int blk)
 {
 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
 	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
@@ -131,11 +132,12 @@ static void put_free_dqblk(struct quota_
 }
 
 /* Remove given block from the list of blocks with free entries */
-static void remove_free_dqentry(struct quota_handle *h, dqbuf_t buf, uint blk)
+static void remove_free_dqentry(struct quota_handle *h, dqbuf_t buf,
+				unsigned int blk)
 {
 	dqbuf_t tmpbuf = getdqbuf();
 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
-	uint nextblk = ext2fs_le32_to_cpu(dh->dqdh_next_free), prevblk =
+	unsigned int nextblk = ext2fs_le32_to_cpu(dh->dqdh_next_free), prevblk =
 
 		ext2fs_le32_to_cpu(dh->dqdh_prev_free);
 
@@ -164,7 +166,8 @@ static void remove_free_dqentry(struct q
 }
 
 /* Insert given block to the beginning of list with free entries */
-static void insert_free_dqentry(struct quota_handle *h, dqbuf_t buf, uint blk)
+static void insert_free_dqentry(struct quota_handle *h, dqbuf_t buf,
+				unsigned int blk)
 {
 	dqbuf_t tmpbuf = getdqbuf();
 	struct qt_disk_dqdbheader *dh = (struct qt_disk_dqdbheader *)buf;
@@ -188,8 +191,8 @@ static void insert_free_dqentry(struct q
 }
 
 /* Find space for dquot */
-static uint find_free_dqentry(struct quota_handle *h, struct dquot *dquot,
-			      int *err)
+static unsigned int find_free_dqentry(struct quota_handle *h,
+				      struct dquot *dquot, int *err)
 {
 	int blk, i;
 	struct qt_disk_dqdbheader *dh;
@@ -247,12 +250,12 @@ static uint find_free_dqentry(struct quo
 
 /* Insert reference to structure into the trie */
 static int do_insert_tree(struct quota_handle *h, struct dquot *dquot,
-			  uint * treeblk, int depth)
+			  unsigned int * treeblk, int depth)
 {
 	dqbuf_t buf;
 	int newson = 0, newact = 0;
-	u_int32_t *ref;
-	uint newblk;
+	__u32 *ref;
+	unsigned int newblk;
 	int ret = 0;
 
 	log_debug("inserting in tree: treeblk=%u, depth=%d", *treeblk, depth);
@@ -271,7 +274,7 @@ static int do_insert_tree(struct quota_h
 		read_blk(h, *treeblk, buf);
 	}
 
-	ref = (u_int32_t *) buf;
+	ref = (__u32 *) buf;
 	newblk = ext2fs_le32_to_cpu(ref[get_index(dquot->dq_id, depth)]);
 	if (!newblk)
 		newson = 1;
@@ -301,11 +304,11 @@ out_buf:
 /* Wrapper for inserting quota structure into tree */
 static void dq_insert_tree(struct quota_handle *h, struct dquot *dquot)
 {
-	uint tmp = QT_TREEOFF;
+	unsigned int tmp = QT_TREEOFF;
 
 	if (do_insert_tree(h, dquot, &tmp, 0) < 0)
 		log_err("Cannot write quota (id %u): %s",
-			(uint) dquot->dq_id, strerror(errno));
+			(unsigned int) dquot->dq_id, strerror(errno));
 }
 
 /* Write dquot to file */
@@ -323,9 +326,10 @@ void qtree_write_dquot(struct dquot *dqu
 	if (ret) {
 		errno = ENOMEM;
 		log_err("Quota write failed (id %u): %s",
-			(uint)dquot->dq_id, strerror(errno));
+			(unsigned int)dquot->dq_id, strerror(errno));
 		return;
 	}
+	memset(ddquot, 0, info->dqi_entry_size);
 
 	if (!dquot->dq_dqb.u.v2_mdqb.dqb_off)
 		dq_insert_tree(dquot->dq_h, dquot);
@@ -340,13 +344,14 @@ void qtree_write_dquot(struct dquot *dqu
 		if (ret > 0)
 			errno = ENOSPC;
 		log_err("Quota write failed (id %u): %s",
-			(uint)dquot->dq_id, strerror(errno));
+			(unsigned int)dquot->dq_id, strerror(errno));
 	}
 	ext2fs_free_mem(&ddquot);
 }
 
 /* Free dquot entry in data block */
-static void free_dqentry(struct quota_handle *h, struct dquot *dquot, uint blk)
+static void free_dqentry(struct quota_handle *h, struct dquot *dquot,
+			 unsigned int blk)
 {
 	struct qt_disk_dqdbheader *dh;
 	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
@@ -358,7 +363,7 @@ static void free_dqentry(struct quota_ha
 	if (dquot->dq_dqb.u.v2_mdqb.dqb_off >> QT_BLKSIZE_BITS != blk)
 		log_err("Quota structure has offset to other block (%u) "
 			"than it should (%u).", blk,
-			  (uint) (dquot->dq_dqb.u.v2_mdqb.dqb_off >>
+			  (unsigned int) (dquot->dq_dqb.u.v2_mdqb.dqb_off >>
 				  QT_BLKSIZE_BITS));
 
 	read_blk(h, blk, buf);
@@ -388,11 +393,11 @@ static void free_dqentry(struct quota_ha
 
 /* Remove reference to dquot from tree */
 static void remove_tree(struct quota_handle *h, struct dquot *dquot,
-			uint * blk, int depth)
+			unsigned int * blk, int depth)
 {
 	dqbuf_t buf = getdqbuf();
-	uint newblk;
-	u_int32_t *ref = (u_int32_t *) buf;
+	unsigned int newblk;
+	__u32 *ref = (__u32 *) buf;
 
 	if (!buf)
 		return;
@@ -428,7 +433,7 @@ static void remove_tree(struct quota_han
 /* Delete dquot from tree */
 void qtree_delete_dquot(struct dquot *dquot)
 {
-	uint tmp = QT_TREEOFF;
+	unsigned int tmp = QT_TREEOFF;
 
 	if (!dquot->dq_dqb.u.v2_mdqb.dqb_off)	/* Even not allocated? */
 		return;
@@ -437,7 +442,7 @@ void qtree_delete_dquot(struct dquot *dq
 
 /* Find entry in block */
 static ext2_loff_t find_block_dqentry(struct quota_handle *h,
-				      struct dquot *dquot, uint blk)
+				      struct dquot *dquot, unsigned int blk)
 {
 	struct qtree_mem_dqinfo *info = &h->qh_info.u.v2_mdqi.dqi_qtree;
 	dqbuf_t buf = getdqbuf();
@@ -464,11 +469,11 @@ static ext2_loff_t find_block_dqentry(st
 /* Find entry for given id in the tree */
 static ext2_loff_t find_tree_dqentry(struct quota_handle *h,
 				     struct dquot *dquot,
-				     uint blk, int depth)
+				     unsigned int blk, int depth)
 {
 	dqbuf_t buf = getdqbuf();
 	ext2_loff_t ret = 0;
-	u_int32_t *ref = (u_int32_t *) buf;
+	__u32 *ref = (__u32 *) buf;
 
 	if (!buf)
 		return -ENOMEM;
@@ -540,7 +545,7 @@ struct dquot *qtree_read_dquot(struct qu
 #define set_bit(bmp, ind) ((bmp)[(ind) >> 3] |= (1 << ((ind) & 7)))
 #define get_bit(bmp, ind) ((bmp)[(ind) >> 3] & (1 << ((ind) & 7)))
 
-static int report_block(struct dquot *dquot, uint blk, char *bitmap,
+static int report_block(struct dquot *dquot, unsigned int blk, char *bitmap,
 			int (*process_dquot) (struct dquot *, void *),
 			void *data)
 {
@@ -574,7 +579,7 @@ static int report_block(struct dquot *dq
 	return entries;
 }
 
-static void check_reference(struct quota_handle *h, uint blk)
+static void check_reference(struct quota_handle *h, unsigned int blk)
 {
 	if (blk >= h->qh_info.u.v2_mdqi.dqi_qtree.dqi_blocks)
 		log_err("Illegal reference (%u >= %u) in %s quota file. "
@@ -585,13 +590,14 @@ static void check_reference(struct quota
 			type2name(h->qh_type));
 }
 
-static int report_tree(struct dquot *dquot, uint blk, int depth, char *bitmap,
+static int report_tree(struct dquot *dquot, unsigned int blk, int depth,
+		       char *bitmap,
 		       int (*process_dquot) (struct dquot *, void *),
 		       void *data)
 {
 	int entries = 0, i;
 	dqbuf_t buf = getdqbuf();
-	u_int32_t *ref = (u_int32_t *) buf;
+	__u32 *ref = (__u32 *) buf;
 
 	if (!buf)
 		return 0;
@@ -620,9 +626,9 @@ static int report_tree(struct dquot *dqu
 	return entries;
 }
 
-static uint find_set_bits(char *bmp, int blocks)
+static unsigned int find_set_bits(char *bmp, int blocks)
 {
-	uint i, used = 0;
+	unsigned int i, used = 0;
 
 	for (i = 0; i < blocks; i++)
 		if (get_bit(bmp, i))
--- e2fsprogs-1.42.9.orig/lib/quota/quotaio_tree.h
+++ e2fsprogs-1.42.9/lib/quota/quotaio_tree.h
@@ -7,7 +7,7 @@
 
 #include <sys/types.h>
 
-typedef u_int32_t qid_t;        /* Type in which we store ids in memory */
+typedef __u32 qid_t;        /* Type in which we store ids in memory */
 
 #define QT_TREEOFF	1	/* Offset of tree in file in blocks */
 #define QT_TREEDEPTH	4	/* Depth of quota tree */
@@ -20,13 +20,13 @@ typedef u_int32_t qid_t;        /* Type
  *  so there will be space for exactly 21 quota-entries in a block
  */
 struct qt_disk_dqdbheader {
-	u_int32_t dqdh_next_free;	/* Number of next block with free
+	__u32 dqdh_next_free;	/* Number of next block with free
 					 * entry */
-	u_int32_t dqdh_prev_free; /* Number of previous block with free
+	__u32 dqdh_prev_free; /* Number of previous block with free
 				   * entry */
-	u_int16_t dqdh_entries; /* Number of valid entries in block */
-	u_int16_t dqdh_pad1;
-	u_int32_t dqdh_pad2;
+	__u16 dqdh_entries; /* Number of valid entries in block */
+	__u16 dqdh_pad1;
+	__u32 dqdh_pad2;
 } __attribute__ ((packed));
 
 struct dquot;
--- e2fsprogs-1.42.9.orig/lib/quota/quotaio_v2.h
+++ e2fsprogs-1.42.9/lib/quota/quotaio_v2.h
@@ -16,8 +16,8 @@
 #define V2_VERSION 1
 
 struct v2_disk_dqheader {
-	u_int32_t dqh_magic;	/* Magic number identifying file */
-	u_int32_t dqh_version;	/* File version */
+	__u32 dqh_magic;	/* Magic number identifying file */
+	__u32 dqh_version;	/* File version */
 } __attribute__ ((packed));
 
 /* Flags for version specific files */
@@ -25,30 +25,30 @@ struct v2_disk_dqheader {
 
 /* Header with type and version specific information */
 struct v2_disk_dqinfo {
-	u_int32_t dqi_bgrace;	/* Time before block soft limit becomes
+	__u32 dqi_bgrace;	/* Time before block soft limit becomes
 				 * hard limit */
-	u_int32_t dqi_igrace;	/* Time before inode soft limit becomes
+	__u32 dqi_igrace;	/* Time before inode soft limit becomes
 				 * hard limit */
-	u_int32_t dqi_flags;	/* Flags for quotafile (DQF_*) */
-	u_int32_t dqi_blocks;	/* Number of blocks in file */
-	u_int32_t dqi_free_blk;	/* Number of first free block in the list */
-	u_int32_t dqi_free_entry;	/* Number of block with at least one
+	__u32 dqi_flags;	/* Flags for quotafile (DQF_*) */
+	__u32 dqi_blocks;	/* Number of blocks in file */
+	__u32 dqi_free_blk;	/* Number of first free block in the list */
+	__u32 dqi_free_entry;	/* Number of block with at least one
 					 * free entry */
 } __attribute__ ((packed));
 
 struct v2r1_disk_dqblk {
-	u_int32_t dqb_id;	/* id this quota applies to */
-	u_int32_t dqb_pad;
-	u_int64_t dqb_ihardlimit;	/* absolute limit on allocated inodes */
-	u_int64_t dqb_isoftlimit;	/* preferred inode limit */
-	u_int64_t dqb_curinodes;	/* current # allocated inodes */
-	u_int64_t dqb_bhardlimit;	/* absolute limit on disk space
+	__u32 dqb_id;	/* id this quota applies to */
+	__u32 dqb_pad;
+	__u64 dqb_ihardlimit;	/* absolute limit on allocated inodes */
+	__u64 dqb_isoftlimit;	/* preferred inode limit */
+	__u64 dqb_curinodes;	/* current # allocated inodes */
+	__u64 dqb_bhardlimit;	/* absolute limit on disk space
 					 * (in QUOTABLOCK_SIZE) */
-	u_int64_t dqb_bsoftlimit;	/* preferred limit on disk space
+	__u64 dqb_bsoftlimit;	/* preferred limit on disk space
 					 * (in QUOTABLOCK_SIZE) */
-	u_int64_t dqb_curspace;	/* current space occupied (in bytes) */
-	u_int64_t dqb_btime;	/* time limit for excessive disk use */
-	u_int64_t dqb_itime;	/* time limit for excessive inode use */
+	__u64 dqb_curspace;	/* current space occupied (in bytes) */
+	__u64 dqb_btime;	/* time limit for excessive disk use */
+	__u64 dqb_itime;	/* time limit for excessive inode use */
 } __attribute__ ((packed));
 
 #endif
--- e2fsprogs-1.42.9.orig/lib/ss/Makefile.in
+++ e2fsprogs-1.42.9/lib/ss/Makefile.in
@@ -162,7 +162,7 @@ uninstall::
 test_ss: test_ss.o test_cmd.o $(DEPLIBSS) $(DEPLIBCOM_ERR)
 	$(E) "	LD $@"
 	$(Q) $(CC) -o $@ test_ss.o test_cmd.o $(ALL_CFLAGS) \
-		$(LIBSS) $(LIBCOM_ERR)
+		$(LIBSS) $(LIBCOM_ERR) $(SYSLIBS)
 
 check:: all test_ss
 	$(E) "	RUN TEST test_ss"
--- e2fsprogs-1.42.9.orig/lib/ss/invocation.c
+++ e2fsprogs-1.42.9/lib/ss/invocation.c
@@ -45,7 +45,8 @@ int ss_create_invocation(const char *sub
 	table = (ss_data **) realloc((char *)table,
 				     ((unsigned)sci_idx+2)*size);
 	if (table == NULL) {
-		*code_ptr = errno;
+		*code_ptr = ENOMEM;
+		free(new_table);
 		return 0;
 	}
 	table[sci_idx+1] = (ss_data *) NULL;
--- e2fsprogs-1.42.9.orig/lib/ss/list_rqs.c
+++ e2fsprogs-1.42.9/lib/ss/list_rqs.c
@@ -18,20 +18,15 @@
 
 typedef void sigret_t;
 
-static char const twentyfive_spaces[26] =
-    "                         ";
-static char const NL[2] = "\n";
-
 void ss_list_requests(int argc __SS_ATTR((unused)),
 		      const char * const *argv __SS_ATTR((unused)),
 		      int sci_idx, void *infop __SS_ATTR((unused)))
 {
     ss_request_entry *entry;
     char const * const *name;
-    int spacing;
+    int i, spacing;
     ss_request_table **table;
 
-    char buffer[BUFSIZ];
     FILE *output;
     int fd;
     sigset_t omask, igmask;
@@ -60,27 +55,24 @@ void ss_list_requests(int argc __SS_ATTR
         entry = (*table)->requests;
         for (; entry->command_names; entry++) {
             spacing = -2;
-            buffer[0] = '\0';
             if (entry->flags & SS_OPT_DONT_LIST)
                 continue;
             for (name = entry->command_names; *name; name++) {
                 int len = strlen(*name);
-                strncat(buffer, *name, len);
+                fputs(*name, output);
                 spacing += len + 2;
                 if (name[1]) {
-                    strcat(buffer, ", ");
+                    fputs(", ", output);
                 }
             }
             if (spacing > 23) {
-                strcat(buffer, NL);
-                fputs(buffer, output);
+                fputc('\n', output);
                 spacing = 0;
-                buffer[0] = '\0';
             }
-            strncat(buffer, twentyfive_spaces, 25-spacing);
-            strcat(buffer, entry->info_string);
-            strcat(buffer, NL);
-            fputs(buffer, output);
+            for (i = 0; i < 25 - spacing; i++)
+                fputc(' ', output);
+            fputs(entry->info_string, output);
+            fputc('\n', output);
         }
     }
     fclose(output);
--- e2fsprogs-1.42.9.orig/lib/ss/parse.c
+++ e2fsprogs-1.42.9/lib/ss/parse.c
@@ -45,7 +45,7 @@ enum parse_mode { WHITESPACE, TOKEN, QUO
 
 char **ss_parse(int sci_idx, register char *line_ptr, int *argc_ptr)
 {
-    register char **argv, *cp;
+    register char **argv, **new_argv, *cp;
     register int argc;
     register enum parse_mode parse_mode;
 
@@ -78,7 +78,13 @@ char **ss_parse(int sci_idx, register ch
 		/* go to quoted-string mode */
 		parse_mode = QUOTED_STRING;
 		cp = line_ptr++;
-		argv = NEW_ARGV (argv, argc);
+		new_argv = NEW_ARGV (argv, argc);
+		if (new_argv == NULL) {
+			free(argv);
+			*argc_ptr = 0;
+			return NULL;
+		}
+		argv = new_argv;
 		argv[argc++] = cp;
 		argv[argc] = NULL;
 	    }
@@ -86,11 +92,13 @@ char **ss_parse(int sci_idx, register ch
 		/* random-token mode */
 		parse_mode = TOKEN;
 		cp = line_ptr;
-		argv = NEW_ARGV (argv, argc);
-		if (argv == NULL) {
-			*argc_ptr = errno;
-			return argv;
+		new_argv = NEW_ARGV (argv, argc);
+		if (new_argv == NULL) {
+			free(argv);
+			*argc_ptr = 0;
+			return NULL;
 		}
+		argv = new_argv;
 		argv[argc++] = line_ptr;
 		argv[argc] = NULL;
 	    }
--- e2fsprogs-1.42.9.orig/lib/uuid/gen_uuid.c
+++ e2fsprogs-1.42.9/lib/uuid/gen_uuid.c
@@ -326,10 +326,12 @@ static int get_clock(uint32_t *clock_hig
 		state_fd = open("/var/lib/libuuid/clock.txt",
 				O_RDWR|O_CREAT, 0660);
 		(void) umask(save_umask);
-		state_f = fdopen(state_fd, "r+");
-		if (!state_f) {
-			close(state_fd);
-			state_fd = -1;
+		if (state_fd >= 0) {
+			state_f = fdopen(state_fd, "r+");
+			if (!state_f) {
+				close(state_fd);
+				state_fd = -1;
+			}
 		}
 	}
 	fl.l_type = F_WRLCK;
@@ -343,7 +345,6 @@ static int get_clock(uint32_t *clock_hig
 			if ((errno == EAGAIN) || (errno == EINTR))
 				continue;
 			fclose(state_f);
-			close(state_fd);
 			state_fd = -1;
 			break;
 		}
@@ -412,7 +413,10 @@ try_again:
 		}
 		rewind(state_f);
 		fl.l_type = F_UNLCK;
-		fcntl(state_fd, F_SETLK, &fl);
+		if (fcntl(state_fd, F_SETLK, &fl) < 0) {
+			fclose(state_f);
+			state_fd = -1;
+		}
 	}
 
 	*clock_high = clock_reg >> 32;
--- e2fsprogs-1.42.9.orig/lib/uuid/tst_uuid.c
+++ e2fsprogs-1.42.9/lib/uuid/tst_uuid.c
@@ -154,7 +154,10 @@ main(int argc ATTR((unused)) , char **ar
 		printf("UUID time comparison succeeded.\n");
 	}
 
-	uuid_parse(str, tst);
+	if (uuid_parse(str, tst) < 0) {
+		printf("UUID parse failed\n");
+		failed++;
+	}
 	if (!uuid_compare(buf, tst)) {
 		printf("UUID parse and compare succeeded.\n");
 	} else {
--- e2fsprogs-1.42.9.orig/misc/Makefile.in
+++ e2fsprogs-1.42.9/misc/Makefile.in
@@ -42,7 +42,8 @@ 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 \
+			mk_hugefiles.o
 CHATTR_OBJS=	chattr.o
 LSATTR_OBJS=	lsattr.o
 UUIDGEN_OBJS=	uuidgen.o
@@ -76,7 +77,7 @@ PROFILED_E2FREEFRAG_OBJS= profiled/e2fre
 PROFILED_E2UNDO_OBJS=	profiled/e2undo.o
 PROFILED_E4DEFRAG_OBJS=	profiled/e4defrag.o
 
-SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c \
+SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklost+found.c $(srcdir)/mke2fs.c $(srcdir)/mk_hugefiles.c \
 		$(srcdir)/chattr.c $(srcdir)/lsattr.c $(srcdir)/dumpe2fs.c \
 		$(srcdir)/badblocks.c $(srcdir)/fsck.c $(srcdir)/util.c \
 		$(srcdir)/uuidgen.c $(srcdir)/blkid.c $(srcdir)/logsave.c \
@@ -84,12 +85,12 @@ SRCS=	$(srcdir)/tune2fs.c $(srcdir)/mklo
 		$(srcdir)/ismounted.c $(srcdir)/../e2fsck/profile.c \
 		$(srcdir)/e2undo.c $(srcdir)/e2freefrag.c
 
-LIBS= $(LIBEXT2FS) $(LIBCOM_ERR) 
+LIBS= $(LIBEXT2FS) $(LIBCOM_ERR)
 DEPLIBS= $(LIBEXT2FS) $(DEPLIBCOM_ERR)
 PROFILED_LIBS= $(PROFILED_LIBEXT2FS) $(PROFILED_LIBCOM_ERR)
 PROFILED_DEPLIBS= $(PROFILED_LIBEXT2FS) $(DEPPROFILED_LIBCOM_ERR)
 
-STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) 
+STATIC_LIBS= $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR)
 STATIC_DEPLIBS= $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) 
 
 LIBS_E2P= $(LIBE2P) $(LIBCOM_ERR) 
@@ -142,7 +143,7 @@ profile.o:
 
 findsuper: findsuper.o
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o findsuper findsuper.o $(LIBS)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o findsuper findsuper.o $(LIBS) $(SYSLIBS)
 
 partinfo: partinfo.o
 	$(E) "	LD $@"
@@ -151,20 +152,20 @@ partinfo: partinfo.o
 e2initrd_helper: e2initrd_helper.o $(DEPLIBS) $(DEPLIBBLKID) $(LIBEXT2FS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o e2initrd_helper e2initrd_helper.o $(LIBS) \
-		$(LIBBLKID) $(LIBEXT2FS) $(LIBINTL)
+		$(LIBBLKID) $(LIBEXT2FS) $(LIBINTL) $(SYSLIBS)
 
 tune2fs: $(TUNE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBBLKID) \
 		$(DEPLIBUUID) $(DEPLIBQUOTA) $(LIBEXT2FS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o tune2fs $(TUNE2FS_OBJS) $(LIBS) \
 		$(LIBBLKID) $(LIBUUID) $(LIBQUOTA) $(LIBEXT2FS) $(LIBS_E2P) \
-		$(LIBINTL)
+		$(LIBINTL) $(SYSLIBS)
 
 tune2fs.static: $(TUNE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBE2P) $(DEPSTATIC_LIBBLKID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(LDFLAGS_STATIC) -o tune2fs.static $(TUNE2FS_OBJS) \
 		$(STATIC_LIBS) $(STATIC_LIBBLKID) $(STATIC_LIBUUID) \
-		$(STATIC_LIBQUOTA) $(STATIC_LIBE2P) $(LIBINTL)
+		$(STATIC_LIBQUOTA) $(STATIC_LIBE2P) $(LIBINTL) $(SYSLIBS)
 
 tune2fs.profiled: $(TUNE2FS_OBJS) $(PROFILED_DEPLIBS) \
 		$(PROFILED_E2P) $(DEPPROFILED_LIBBLKID) $(DEPPROFILED_LIBUUID) \
@@ -173,55 +174,58 @@ tune2fs.profiled: $(TUNE2FS_OBJS) $(PROF
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o tune2fs.profiled \
 		$(PROFILED_TUNE2FS_OBJS) $(PROFILED_LIBBLKID) \
 		$(PROFILED_LIBUUID) $(PROFILED_LIBQUOTA) $(PROFILED_LIBE2P) \
-		$(LIBINTL) $(PROFILED_LIBS)
+		$(LIBINTL) $(PROFILED_LIBS) $(SYSLIBS)
 
 blkid: $(BLKID_OBJS) $(DEPLIBBLKID) $(LIBEXT2FS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o blkid $(BLKID_OBJS) $(LIBBLKID) $(LIBINTL) \
-		$(LIBEXT2FS)
+		$(LIBEXT2FS) $(SYSLIBS)
 
 blkid.static: $(BLKID_OBJS) $(STATIC_DEPLIBS) $(DEPSTATIC_LIBBLKID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o blkid.static $(BLKID_OBJS) $(STATIC_LIBS) \
-		$(STATIC_LIBBLKID) $(LIBINTL)
+		$(STATIC_LIBBLKID) $(LIBINTL) $(SYSLIBS)
 
 blkid.profiled: $(BLKID_OBJS) $(DEPPROFILED_LIBBLKID) \
 		$(PROFILED_LIBEXT2FS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o blkid.profiled $(PROFILED_BLKID_OBJS) \
-		$(PROFILED_LIBBLKID) $(LIBINTL) $(PROFILED_LIBEXT2FS)
+		$(PROFILED_LIBBLKID) $(LIBINTL) $(PROFILED_LIBEXT2FS) $(SYSLIBS)
 
 e2image: $(E2IMAGE_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o e2image $(E2IMAGE_OBJS) $(LIBS) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o e2image $(E2IMAGE_OBJS) $(LIBS) \
+		$(LIBINTL) $(SYSLIBS)
 
 e2image.profiled: $(E2IMAGE_OBJS) $(PROFILED_DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2image.profiled \
-		$(PROFILED_E2IMAGE_OBJS) $(PROFILED_LIBS) $(LIBINTL)
+		$(PROFILED_E2IMAGE_OBJS) $(PROFILED_LIBS) $(LIBINTL) $(SYSLIBS)
 
 e2undo: $(E2UNDO_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o e2undo $(E2UNDO_OBJS) $(LIBS) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o e2undo $(E2UNDO_OBJS) $(LIBS) \
+		$(LIBINTL) $(SYSLIBS)
 
 e2undo.profiled: $(E2UNDO_OBJS) $(PROFILED_DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2undo.profiled \
-		$(PROFILED_E2UNDO_OBJS) $(PROFILED_LIBS) $(LIBINTL)
+		$(PROFILED_E2UNDO_OBJS) $(PROFILED_LIBS) $(LIBINTL) $(SYSLIBS)
 
 e4defrag: $(E4DEFRAG_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o e4defrag $(E4DEFRAG_OBJS) $(LIBS)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o e4defrag $(E4DEFRAG_OBJS) $(LIBS) \
+		$(SYSLIBS)
 
 e4defrag.profiled: $(E4DEFRAG_OBJS) $(PROFILED_DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e4defrag.profiled \
-		$(PROFILED_E4DEFRAG_OBJS) $(PROFILED_LIBS)
+		$(PROFILED_E4DEFRAG_OBJS) $(PROFILED_LIBS) $(SYSLIBS)
 
 base_device: base_device.c
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) $(srcdir)/base_device.c \
-		-DDEBUG -o base_device
+		-DDEBUG -o base_device $(SYSLIBS)
 
 check:: base_device
 	./base_device < $(srcdir)/base_device.tst > base_device.out
@@ -229,20 +233,22 @@ check:: base_device
 
 mklost+found: $(MKLPF_OBJS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o mklost+found $(MKLPF_OBJS) \
+		$(LIBINTL) $(SYSLIBS)
 
 mke2fs: $(MKE2FS_OBJS) $(DEPLIBS) $(LIBE2P) $(DEPLIBBLKID) $(DEPLIBUUID) \
 		$(DEPLIBQUOTA) $(LIBEXT2FS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o mke2fs $(MKE2FS_OBJS) $(LIBS) $(LIBBLKID) \
-		$(LIBUUID) $(LIBQUOTA) $(LIBEXT2FS) $(LIBE2P) $(LIBINTL)
+		$(LIBUUID) $(LIBQUOTA) $(LIBEXT2FS) $(LIBE2P) $(LIBINTL) \
+		$(SYSLIBS)
 
 mke2fs.static: $(MKE2FS_OBJS) $(STATIC_DEPLIBS) $(STATIC_LIBE2P) $(DEPSTATIC_LIBUUID) \
 		$(DEPSTATIC_LIBQUOTA) $(DEPSTATIC_LIBBLKID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -static -o mke2fs.static $(MKE2FS_OBJS) \
 		$(STATIC_LIBQUOTA) $(STATIC_LIBS) $(STATIC_LIBE2P) \
-		$(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL)
+		$(STATIC_LIBBLKID) $(STATIC_LIBUUID) $(LIBINTL) $(SYSLIBS)
 
 mke2fs.profiled: $(MKE2FS_OBJS) $(PROFILED_DEPLIBS) \
 	$(PROFILED_LIBE2P) $(PROFILED_DEPLIBBLKID) $(PROFILED_DEPLIBUUID) \
@@ -250,85 +256,95 @@ mke2fs.profiled: $(MKE2FS_OBJS) $(PROFIL
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o mke2fs.profiled \
 		$(PROFILED_MKE2FS_OBJS) $(PROFILED_LIBBLKID) \
-		$(PROFILED_LIBUUID) $(PROFILED_LIBQUOTA) $(PROFILED_LIBE2P) $(LIBINTL) \
-		$(PROFILED_LIBS)
+		$(PROFILED_LIBUUID) $(PROFILED_LIBQUOTA) $(PROFILED_LIBE2P) \
+		$(LIBINTL) $(PROFILED_LIBS) $(SYSLIBS)
 
 chattr: $(CHATTR_OBJS) $(DEPLIBS_E2P)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o chattr $(CHATTR_OBJS) $(LIBS_E2P) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o chattr $(CHATTR_OBJS) $(LIBS_E2P) \
+		$(LIBINTL) $(SYSLIBS)
 
 lsattr: $(LSATTR_OBJS) $(DEPLIBS_E2P)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o lsattr $(LSATTR_OBJS) $(LIBS_E2P) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o lsattr $(LSATTR_OBJS) $(LIBS_E2P) \
+		$(LIBINTL) $(SYSLIBS)
 
 uuidgen: $(UUIDGEN_OBJS) $(DEPLIBUUID)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o uuidgen $(UUIDGEN_OBJS) $(LIBUUID) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o uuidgen $(UUIDGEN_OBJS) $(LIBUUID) \
+		$(LIBINTL) $(SYSLIBS)
 
 uuidgen.profiled: $(UUIDGEN_OBJS) $(PROFILED_DEPLIBUUID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o uuidgen.profiled \
-		$(PROFILED_UUIDGEN_OBJS) $(PROFILED_LIBUUID) $(LIBINTL)
+		$(PROFILED_UUIDGEN_OBJS) $(PROFILED_LIBUUID) $(LIBINTL) \
+		$(SYSLIBS)
 
 uuidd: $(UUIDD_OBJS) $(DEPLIBUUID)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o uuidd $(UUIDD_OBJS) $(LIBUUID) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o uuidd $(UUIDD_OBJS) $(LIBUUID) \
+		$(LIBINTL) $(SYSLIBS)
 
 uuidd.profiled: $(UUIDD_OBJS) $(PROFILED_DEPLIBUUID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o uuidd.profiled $(PROFILED_UUIDD_OBJS) \
-		$(PROFILED_LIBUUID) $(LIBINTL)
+		$(PROFILED_LIBUUID) $(LIBINTL) $(SYSLIBS)
 
 dumpe2fs: $(DUMPE2FS_OBJS) $(DEPLIBS) $(DEPLIBS_E2P) $(DEPLIBUUID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -o dumpe2fs $(DUMPE2FS_OBJS) $(LIBS) \
-		$(LIBS_E2P) $(LIBUUID) $(LIBINTL)
+		$(LIBS_E2P) $(LIBUUID) $(LIBINTL) $(SYSLIBS)
 
 dumpe2fs.profiled: $(DUMPE2FS_OBJS) $(PROFILED_DEPLIBS) \
 		$(PROFILED_LIBE2P) $(PROFILED_DEPLIBUUID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o dumpe2fs.profiled \
 		$(PROFILED_DUMPE2FS_OBJS) $(PROFILED_LIBS) \
-		$(PROFILED_LIBE2P) $(PROFILED_LIBUUID) $(LIBINTL)
+		$(PROFILED_LIBE2P) $(PROFILED_LIBUUID) $(LIBINTL) $(SYSLIBS)
 
 fsck: $(FSCK_OBJS) $(DEPLIBBLKID)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBBLKID) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o fsck $(FSCK_OBJS) $(LIBBLKID) \
+		$(LIBINTL) $(SYSLIBS)
 
 fsck.profiled: $(FSCK_OBJS) $(PROFILED_DEPLIBBLKID)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o fsck.profiled $(PROFILED_FSCK_OBJS) \
-		$(PROFILED_LIBBLKID) $(LIBINTL)
+		$(PROFILED_LIBBLKID) $(LIBINTL) $(SYSLIBS)
 
 badblocks: $(BADBLOCKS_OBJS) $(DEPLIBS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o badblocks $(BADBLOCKS_OBJS) $(LIBS) $(LIBINTL)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o badblocks $(BADBLOCKS_OBJS) $(LIBS) \
+		$(LIBINTL) $(SYSLIBS)
 
 badblocks.profiled: $(BADBLOCKS_OBJS) $(PROFILED_DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o badblocks.profiled \
-		$(PROFILED_BADBLOCKS_OBJS) $(PROFILED_LIBS) $(LIBINTL)
+		$(PROFILED_BADBLOCKS_OBJS) $(PROFILED_LIBS) $(LIBINTL) \
+		$(SYSLIBS)
 
 logsave: logsave.o
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o logsave logsave.o
+	$(Q) $(CC) $(ALL_LDFLAGS) -o logsave logsave.o $(SYSLIBS)
 
 logsave.profiled: logsave.o
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o logsave.profiled profiled/logsave.o
+	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o logsave.profiled \
+		profiled/logsave.o $(SYSLIBS)
 
 e2freefrag: $(E2FREEFRAG_OBJS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o e2freefrag $(E2FREEFRAG_OBJS) $(LIBS)
+	$(Q) $(CC) $(ALL_LDFLAGS) -o e2freefrag $(E2FREEFRAG_OBJS) \
+		$(LIBS) $(SYSLIBS)
 
 e2freefrag.profiled: $(E2FREEFRAG_OBJS) $(PROFILED_DEPLIBS)
 	$(E) "	LD $@"
 	$(Q) $(CC) $(ALL_LDFLAGS) -g -pg -o e2freefrag.profiled \
-		$(PROFILED_E2FREEFRAG_OBJS) $(PROFILED_LIBS)
+		$(PROFILED_E2FREEFRAG_OBJS) $(PROFILED_LIBS) $(SYSLIBS)
 
 filefrag: $(FILEFRAG_OBJS)
 	$(E) "	LD $@"
-	$(Q) $(CC) $(ALL_LDFLAGS) -o filefrag $(FILEFRAG_OBJS) 
+	$(Q) $(CC) $(ALL_LDFLAGS) -o filefrag $(FILEFRAG_OBJS) $(SYSLIBS)
 
 filefrag.profiled: $(FILEFRAG_OBJS)
 	$(E) "	LD $@"
@@ -338,7 +354,7 @@ filefrag.profiled: $(FILEFRAG_OBJS)
 tst_ismounted: $(srcdir)/ismounted.c $(STATIC_LIBEXT2FS) $(DEPLIBCOM_ERR)
 	$(E) "	LD $@"
 	$(CC) -o tst_ismounted $(srcdir)/ismounted.c -DDEBUG $(ALL_CFLAGS) \
-		$(LIBCOM_ERR)
+		$(LIBCOM_ERR) $(SYSLIBS)
 
 tune2fs.8: $(DEP_SUBSTITUTE) $(srcdir)/tune2fs.8.in
 	$(E) "	SUBST $@"
@@ -632,7 +648,18 @@ mke2fs.o: $(srcdir)/mke2fs.c $(top_build
  $(srcdir)/util.h profile.h prof_err.h $(top_srcdir)/version.h \
  $(srcdir)/nls-enable.h $(top_srcdir)/lib/quota/mkquota.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
+ $(top_srcdir)/lib/quota/quotaio_tree.h $(top_srcdir)/lib/../e2fsck/dict.h \
+ $(srcdir)/mke2fs.h
+mk_hugefiles.o: $(srcdir)/mk_hugefiles.c $(top_builddir)/lib/config.h \
+ $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
+ $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/ext2fs/ext2fsP.h \
+ $(top_srcdir)/lib/ext2fs/ext2fs.h $(top_srcdir)/lib/ext2fs/ext3_extents.h \
+ $(top_srcdir)/lib/et/com_err.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 \
+ $(top_srcdir)/lib/e2p/e2p.h $(top_srcdir)/lib/ext2fs/ext2fs.h \
+ $(srcdir)/util.h profile.h prof_err.h $(srcdir)/nls-enable.h \
+ $(srcdir)/mke2fs.h
 chattr.o: $(srcdir)/chattr.c $(top_builddir)/lib/config.h \
  $(top_builddir)/lib/dirpaths.h $(top_srcdir)/lib/ext2fs/ext2_fs.h \
  $(top_builddir)/lib/ext2fs/ext2_types.h $(top_srcdir)/lib/et/com_err.h \
--- e2fsprogs-1.42.9.orig/misc/badblocks.c
+++ e2fsprogs-1.42.9/misc/badblocks.c
@@ -300,7 +300,8 @@ static void set_o_direct(int dev, unsign
 		flag = fcntl(dev, F_GETFL);
 		if (flag > 0) {
 			flag = (flag & ~O_DIRECT) | new_flag;
-			fcntl(dev, F_SETFL, flag);
+			if (fcntl(dev, F_SETFL, flag) < 0)
+				perror("set_o_direct");
 		}
 		current_O_DIRECT = new_flag;
 	}
--- e2fsprogs-1.42.9.orig/misc/blkid.c
+++ e2fsprogs-1.42.9/misc/blkid.c
@@ -38,7 +38,7 @@ extern int optind;
 #include "ext2fs/ext2fs.h"
 #include "blkid/blkid.h"
 
-const char *progname = "blkid";
+static const char *progname = "blkid";
 
 static void print_version(FILE *out)
 {
@@ -100,19 +100,27 @@ static int get_terminal_width(void)
 	struct winsize	w_win;
 #endif
         const char	*cp;
+	int width = 80;
 
 #ifdef TIOCGSIZE
-	if (ioctl (0, TIOCGSIZE, &t_win) == 0)
-		return (t_win.ts_cols);
+	if (ioctl (0, TIOCGSIZE, &t_win) == 0) {
+		width = t_win.ts_cols;
+		goto got_it;
+	}
 #endif
 #ifdef TIOCGWINSZ
-	if (ioctl (0, TIOCGWINSZ, &w_win) == 0)
-		return (w_win.ws_col);
+	if (ioctl (0, TIOCGWINSZ, &w_win) == 0) {
+		width = w_win.ws_col;
+		goto got_it;
+	}
 #endif
         cp = getenv("COLUMNS");
 	if (cp)
-		return strtol(cp, NULL, 10);
-	return 80;
+		width = atoi(cp);
+got_it:
+	if (width > 4096)
+		return 4096;	/* sanity check */
+	return width;
 }
 
 static int pretty_print_word(const char *str, int max_len,
@@ -127,9 +135,9 @@ static int pretty_print_word(const char
 		len = 0;
 	} else if (len > max_len)
 		ret = len - max_len;
-	do
+	do {
 		fputc(' ', stdout);
-	while (len++ < max_len);
+	} while (len++ < max_len);
 	return ret;
 }
 
@@ -142,20 +150,21 @@ static void pretty_print_line(const char
 	static int term_width = -1;
 	int len, w;
 
-	if (term_width < 0)
+	if (term_width < 0) {
 		term_width = get_terminal_width();
 
-	if (term_width > 80) {
-		term_width -= 80;
-		w = term_width / 10;
-		if (w > 8)
-			w = 8;
-		term_width -= 2*w;
-		label_len += w;
-		fs_type_len += w;
-		w = term_width/2;
-		device_len += w;
-		mtpt_len +=w;
+		if (term_width > 80) {
+			term_width -= 80;
+			w = term_width / 10;
+			if (w > 8)
+				w = 8;
+			term_width -= 2*w;
+			label_len += w;
+			fs_type_len += w;
+			w = term_width/2;
+			device_len += w;
+			mtpt_len +=w;
+		}
 	}
 
 	len = pretty_print_word(device, device_len, 0, 1);
@@ -284,10 +293,7 @@ int main(int argc, char **argv)
 	while ((c = getopt (argc, argv, "c:f:ghlLo:s:t:w:v")) != EOF)
 		switch (c) {
 		case 'c':
-			if (optarg && !*optarg)
-				read = NULL;
-			else
-				read = optarg;
+			read = optarg;
 			if (!write)
 				write = read;
 			break;
@@ -340,13 +346,11 @@ int main(int argc, char **argv)
 			version = 1;
 			break;
 		case 'w':
-			if (optarg && !*optarg)
-				write = NULL;
-			else
-				write = optarg;
+			write = optarg;
 			break;
 		case 'h':
 			err = 0;
+			/* fallthrough */
 		default:
 			usage(err);
 		}
--- e2fsprogs-1.42.9.orig/misc/e2image.c
+++ e2fsprogs-1.42.9/misc/e2image.c
@@ -174,7 +174,7 @@ static void generic_write(int fd, void *
 		printf(_("Writing block %llu\n"), (unsigned long long) block);
 		if (fd != 1)
 			seek_relative(fd, blocksize);
-		return;
+		goto free_and_return;
 	}
 	count = write(fd, buf, blocksize);
 	if (count != blocksize) {
@@ -191,6 +191,7 @@ static void generic_write(int fd, void *
 
 		exit(1);
 	}
+free_and_return:
 	if (free_buf)
 		ext2fs_free_mem(&buf);
 }
@@ -633,7 +634,7 @@ more_blocks:
 			bscount = print_progress(total_written,
 						 meta_blocks_count);
 			duration = time(NULL) - start_time;
-			if (duration > 5) {
+			if (duration > 5 && total_written) {
 				time_t est = (duration * meta_blocks_count /
 					      total_written) - duration;
 				char buff[30];
@@ -703,14 +704,15 @@ more_blocks:
 	if (show_progress) {
 		time_t duration = time(NULL) - start_time;
 		char buff[30];
-		while (bscount--)
-			fputc('\b', stderr);
+		fputc('\r', stderr);
 		strftime(buff, 30, "%T", gmtime(&duration));
-		fprintf(stderr, _("\b\b\b\b\b\b\b\bCopied %llu / %llu "
-			 "blocks (%d%%) in %s at %.2f MB/s       \n"),
-		       total_written, meta_blocks_count,
-		       calc_percent(total_written, meta_blocks_count), buff,
-		       calc_rate(total_written, fs->blocksize, duration));
+		fprintf(stderr, _("Copied %llu / %llu blocks (%d%%) in %s "),
+			total_written, meta_blocks_count,
+			calc_percent(total_written, meta_blocks_count), buff);
+		if (duration)
+			fprintf(stderr, _("at %.2f MB/s"),
+				calc_rate(total_written, fs->blocksize, duration));
+		fputs("       \n", stderr);
 	}
 #ifdef HAVE_FTRUNCATE64
 	if (sparse) {
@@ -1410,7 +1412,7 @@ static void install_image(char *device,
 
 	retval = ext2fs_image_inode_read(fs, fd, 0);
 	if (retval) {
-		com_err(image_fn, 0, "while restoring the image table");
+		com_err(image_fn, 0, _("while restoring the image table"));
 		exit(1);
 	}
 
@@ -1597,7 +1599,7 @@ skip_device:
 	}
 	if (fd != 1) {
 		if (fstat(fd, &st)) {
-			com_err(program_name, 0, "Can not stat output\n");
+			com_err(program_name, 0, _("Can not stat output\n"));
 			exit(1);
 		}
 		if (S_ISBLK(st.st_mode))
--- e2fsprogs-1.42.9.orig/misc/e4defrag.c
+++ e2fsprogs-1.42.9/misc/e4defrag.c
@@ -34,7 +34,6 @@
 #include <unistd.h>
 #include <ext2fs/ext2_types.h>
 #include <ext2fs/ext2fs.h>
-#include <linux/fs.h>
 #include <sys/ioctl.h>
 #include <ext2fs/fiemap.h>
 #include <sys/mman.h>
@@ -183,29 +182,21 @@ static ext4_fsblk_t	files_block_count;
 static struct frag_statistic_ino	frag_rank[SHOW_FRAG_FILES];
 
 
-/* Local definitions of some syscalls glibc may not yet have */
-
-#ifndef HAVE_POSIX_FADVISE
-#warning Using locally defined posix_fadvise interface.
-
-#ifndef __NR_fadvise64_64
-#error Your kernel headers dont define __NR_fadvise64_64
+/*
+ * We prefer posix_fadvise64 when available, as it allows 64bit offset on
+ * 32bit systems
+ */
+#if defined(HAVE_POSIX_FADVISE64)
+#define posix_fadvise	posix_fadvise64
+#elif defined(HAVE_FADVISE64)
+#define posix_fadvise	fadvise64
+#elif !defined(HAVE_POSIX_FADVISE)
+#error posix_fadvise not available!
 #endif
 
 /*
- * fadvise() -		Give advice about file access.
- *
- * @fd:			defrag target file's descriptor.
- * @offset:		file offset.
- * @len:		area length.
- * @advise:		process flag.
+ * Local definitions of some syscalls glibc may not yet have
  */
-static int posix_fadvise(int fd, loff_t offset, size_t len, int advise)
-{
-	return syscall(__NR_fadvise64_64, fd, offset, len, advise);
-}
-#endif /* ! HAVE_FADVISE64_64 */
-
 #ifndef HAVE_SYNC_FILE_RANGE
 #warning Using locally defined sync_file_range interface.
 
--- e2fsprogs-1.42.9.orig/misc/ext4.5.in
+++ e2fsprogs-1.42.9/misc/ext4.5.in
@@ -109,7 +109,6 @@ supported by ext2, ext3, and ext4.
 This feature enables the storage file type information in directory
 entries.  This feature is supported by ext2, ext3, and ext4.
 .TP
-.TP
 .B flex_bg
 .br
 This ext4 feature allows the per-block group metadata (allocation
@@ -172,6 +171,17 @@ kernels from mounting file systems that
 .\" .br
 .\" .B Future feature, available in e2fsprogs 1.43-WIP
 .TP
+.B sparse_super2
+.br
+This feature indicates that there will only at most two backup
+superblock and block group descriptors.  The block groups used to store
+the backup superblock and blockgroup descriptors are stored in the
+superblock, but typically, one will be located at the beginning of block
+group #1, and one in the last block group in the file system.  This is
+feature is essentially a more extreme version of sparse_super and is
+designed to allow the a much larger percentage of the disk to have
+contiguous blocks available for data files.
+.TP
 .B meta_bg
 .br
 This ext4 feature allows file systems to be resized on-line without explicitly
--- /dev/null
+++ e2fsprogs-1.42.9/misc/mk_hugefiles.c
@@ -0,0 +1,429 @@
+/*
+ * mk_hugefiles.c -- create huge files
+ */
+
+#define _XOPEN_SOURCE 600 /* for inclusion of PATH_MAX in Solaris */
+
+#include "config.h"
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <time.h>
+#ifdef __linux__
+#include <sys/utsname.h>
+#endif
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#else
+extern char *optarg;
+extern int optind;
+#endif
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
+#ifdef HAVE_ERRNO_H
+#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 "nls-enable.h"
+#include "mke2fs.h"
+
+static int uid;
+static int gid;
+static blk64_t num_blocks;
+static blk64_t num_slack;
+static unsigned long num_files;
+static blk64_t goal;
+static char *fn_prefix;
+static int idx_digits;
+static char *fn_buf;
+static char *fn_numbuf;
+int zero_hugefile = 1;
+
+static errcode_t create_directory(ext2_filsys fs, char *dir,
+				  ext2_ino_t *ret_ino)
+
+{
+	struct ext2_inode	inode;
+	ext2_ino_t		ino = EXT2_ROOT_INO;
+	ext2_ino_t		newdir;
+	errcode_t		retval = 0;
+	char			*fn, *cp, *next;
+
+	fn = malloc(strlen(dir) + 1);
+	if (fn == NULL)
+		return ENOMEM;
+
+	strcpy(fn, dir);
+	cp = fn;
+	while(1) {
+		next = strchr(cp, '/');
+		if (next)
+			*next++ = 0;
+		if (*cp) {
+			retval = ext2fs_new_inode(fs, ino, LINUX_S_IFDIR,
+						  NULL, &newdir);
+			if (retval)
+				goto errout;
+
+			retval = ext2fs_mkdir(fs, ino, newdir, cp);
+			if (retval)
+				goto errout;
+
+			ino = newdir;
+			retval = ext2fs_read_inode(fs, ino, &inode);
+			if (retval)
+				goto errout;
+
+			inode.i_uid = uid & 0xFFFF;
+			ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
+			inode.i_gid = gid & 0xFFFF;
+			ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);
+			retval = ext2fs_write_inode(fs, ino, &inode);
+			if (retval)
+				goto errout;
+		}
+		if (next == NULL || *next == '\0')
+			break;
+		cp = next;
+	}
+errout:
+	free(fn);
+	if (retval == 0)
+		*ret_ino = ino;
+	return retval;
+}
+
+static errcode_t mk_hugefile(ext2_filsys fs, blk64_t num,
+			     ext2_ino_t dir, unsigned long idx, ext2_ino_t *ino)
+
+{
+	errcode_t		retval;
+	blk64_t			lblk, bend;
+	__u64			size;
+	blk64_t			left;
+	blk64_t			count = 0;
+	struct ext2_inode	inode;
+	ext2_extent_handle_t	handle;
+
+	retval = ext2fs_new_inode(fs, 0, LINUX_S_IFREG, NULL, ino);
+	if (retval)
+		return retval;
+
+	memset(&inode, 0, sizeof(struct ext2_inode));
+	inode.i_mode = LINUX_S_IFREG | (0666 & ~fs->umask);
+	inode.i_links_count = 1;
+	inode.i_uid = uid & 0xFFFF;
+	ext2fs_set_i_uid_high(inode, (uid >> 16) & 0xffff);
+	inode.i_gid = gid & 0xFFFF;
+	ext2fs_set_i_gid_high(inode, (gid >> 16) & 0xffff);
+
+	retval = ext2fs_write_new_inode(fs, *ino, &inode);
+	if (retval)
+		return retval;
+
+	ext2fs_inode_alloc_stats2(fs, *ino, +1, 0);
+
+	retval = ext2fs_extent_open2(fs, *ino, &inode, &handle);
+	if (retval)
+		return retval;
+
+	lblk = 0;
+	left = num ? num : 1;
+	while (left) {
+		blk64_t pblk, end;
+		blk64_t n = left;
+
+		retval =  ext2fs_find_first_zero_block_bitmap2(fs->block_map,
+			goal, ext2fs_blocks_count(fs->super) - 1, &end);
+		if (retval)
+			goto errout;
+		goal = end;
+
+		retval =  ext2fs_find_first_set_block_bitmap2(fs->block_map, goal,
+			       ext2fs_blocks_count(fs->super) - 1, &bend);
+		if (retval == ENOENT) {
+			bend = ext2fs_blocks_count(fs->super);
+			if (num == 0)
+				left = 0;
+		}
+		if (!num || bend - goal < left)
+			n = bend - goal;
+		pblk = goal;
+		if (num)
+			left -= n;
+		goal += n;
+		count += n;
+		ext2fs_block_alloc_stats_range(fs, pblk, n, +1);
+
+		if (zero_hugefile) {
+			blk64_t ret_blk;
+			retval = ext2fs_zero_blocks2(fs, pblk, n,
+						     &ret_blk, NULL);
+
+			if (retval)
+				com_err(program_name, retval,
+					_("while zeroing block %llu "
+					  "for hugefile"), ret_blk);
+		}
+
+		while (n) {
+			blk64_t l = n;
+			struct ext2fs_extent newextent;
+
+			if (l > EXT_INIT_MAX_LEN)
+				l = EXT_INIT_MAX_LEN;
+
+			newextent.e_len = l;
+			newextent.e_pblk = pblk;
+			newextent.e_lblk = lblk;
+			newextent.e_flags = 0;
+
+			retval = ext2fs_extent_insert(handle,
+					EXT2_EXTENT_INSERT_AFTER, &newextent);
+			if (retval)
+				return retval;
+			pblk += l;
+			lblk += l;
+			n -= l;
+		}
+	}
+
+	retval = ext2fs_read_inode(fs, *ino, &inode);
+	if (retval)
+		goto errout;
+
+	retval = ext2fs_iblk_add_blocks(fs, &inode,
+					count / EXT2FS_CLUSTER_RATIO(fs));
+	if (retval)
+		goto errout;
+	size = (__u64) count * fs->blocksize;
+	inode.i_size = size & 0xffffffff;
+	inode.i_size_high = (size >> 32);
+
+	retval = ext2fs_write_new_inode(fs, *ino, &inode);
+	if (retval)
+		goto errout;
+
+	if (idx_digits)
+		sprintf(fn_numbuf, "%0*lu", idx_digits, idx);
+	else if (num_files > 1)
+		sprintf(fn_numbuf, "%lu", idx);
+
+retry:
+	retval = ext2fs_link(fs, dir, fn_buf, *ino, EXT2_FT_REG_FILE);
+	if (retval == EXT2_ET_DIR_NO_SPACE) {
+		retval = ext2fs_expand_dir(fs, dir);
+		if (retval)
+			goto errout;
+		goto retry;
+	}
+
+	if (retval)
+		goto errout;
+
+errout:
+	if (handle)
+		ext2fs_extent_free(handle);
+
+	return retval;
+}
+
+static blk64_t calc_overhead(ext2_filsys fs, blk64_t num)
+{
+	blk64_t e_blocks, e_blocks2, e_blocks3, e_blocks4;
+	int extents_per_block;
+	int extents = (num + EXT_INIT_MAX_LEN - 1) / EXT_INIT_MAX_LEN;
+
+	if (extents <= 4)
+		return 0;
+
+	/*
+	 * This calculation is due to the fact that we are inefficient
+	 * in how handle extent splits when appending to the end of
+	 * the extent tree.  Sigh.  We should fix this so that we can
+	 * actually store 340 extents per 4k block, instead of only 170.
+	 */
+	extents_per_block = ((fs->blocksize -
+			      sizeof(struct ext3_extent_header)) /
+			     sizeof(struct ext3_extent));
+	extents_per_block = (extents_per_block/ 2) - 1;
+
+	e_blocks = (extents + extents_per_block - 1) / extents_per_block;
+	e_blocks2 = (e_blocks + extents_per_block - 1) / extents_per_block;
+	e_blocks3 = (e_blocks2 + extents_per_block - 1) / extents_per_block;
+	e_blocks4 = (e_blocks3 + extents_per_block - 1) / extents_per_block;
+	return e_blocks + e_blocks2 + e_blocks3 + e_blocks4;
+}
+
+/*
+ * Find the place where we should start allocating blocks for the huge
+ * files.  Leave <slack> free blocks at the beginning of the file
+ * system for things like metadata blocks.
+ */
+static blk64_t get_start_block(ext2_filsys fs, blk64_t slack)
+{
+	errcode_t retval;
+	blk64_t blk = fs->super->s_first_data_block, next;
+	blk64_t last_blk = ext2fs_blocks_count(fs->super) - 1;
+
+	while (slack) {
+		retval = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
+						blk, last_blk, &blk);
+		if (retval)
+			break;
+
+		retval = ext2fs_find_first_set_block_bitmap2(fs->block_map,
+						blk, last_blk, &next);
+		if (retval)
+			next = last_blk;
+		next--;
+
+		if (next - blk > slack) {
+			blk += slack;
+			break;
+		}
+
+		slack -= (next - blk);
+		blk = next;
+	}
+	return blk;
+}
+
+static blk64_t round_up_align(blk64_t b, unsigned long align)
+{
+	unsigned long m;
+
+	if (align == 0)
+		return b;
+	m = b % align;
+	if (m)
+		b += align - m;
+	return b;
+}
+
+errcode_t mk_hugefiles(ext2_filsys fs)
+{
+	unsigned long	i;
+	ext2_ino_t	dir;
+	errcode_t	retval;
+	blk64_t		fs_blocks;
+	unsigned long	align;
+	int		d, dsize;
+	char		*t;
+
+	if (!get_bool_from_profile(fs_types, "make_hugefiles", 0))
+		return 0;
+
+	uid = get_int_from_profile(fs_types, "hugefiles_uid", 0);
+	gid = get_int_from_profile(fs_types, "hugefiles_gid", 0);
+	fs->umask = get_int_from_profile(fs_types, "hugefiles_umask", 077);
+	num_files = get_int_from_profile(fs_types, "num_hugefiles", 0);
+	t = get_string_from_profile(fs_types, "hugefiles_slack", "1M");
+	num_slack = parse_num_blocks2(t, fs->super->s_log_block_size);
+	free(t);
+	t = get_string_from_profile(fs_types, "hugefiles_size", "0");
+	num_blocks = parse_num_blocks2(t, fs->super->s_log_block_size);
+	free(t);
+	t = get_string_from_profile(fs_types, "hugefiles_align", "0");
+	align = parse_num_blocks2(t, fs->super->s_log_block_size);
+	free(t);
+	num_blocks = round_up_align(num_blocks, align);
+	zero_hugefile = get_int_from_profile(fs_types, "zero_hugefiles",
+					     zero_hugefile);
+
+	t = get_string_from_profile(fs_types, "hugefiles_dir", "/");
+	retval = create_directory(fs, t, &dir);
+	free(t);
+	if (retval)
+		return retval;
+
+	fn_prefix = get_string_from_profile(fs_types, "hugefiles_name",
+					    "hugefile");
+	idx_digits = get_int_from_profile(fs_types, "hugefiles_digits", 5);
+	d = int_log10(num_files) + 1;
+	if (idx_digits > d)
+		d = idx_digits;
+	dsize = strlen(fn_prefix) + d + 16;
+	fn_buf = malloc(dsize);
+	if (!fn_buf) {
+		free(fn_prefix);
+		return ENOMEM;
+	}
+	strcpy(fn_buf, fn_prefix);
+	fn_numbuf = fn_buf + strlen(fn_prefix);
+	free(fn_prefix);
+
+	fs_blocks = ext2fs_free_blocks_count(fs->super);
+	if (fs_blocks < num_slack + align)
+		return ENOMEM;
+	fs_blocks -= num_slack + align;
+	if (num_blocks && num_blocks > fs_blocks)
+		return ENOMEM;
+	if (num_blocks == 0 && num_files == 0)
+		num_files = 1;
+
+	if (num_files == 0 && num_blocks) {
+		num_files = fs_blocks / num_blocks;
+		fs_blocks -= (num_files / 16) + 1;
+		fs_blocks -= calc_overhead(fs, num_blocks) * num_files;
+		num_files = fs_blocks / num_blocks;
+	}
+
+	if (num_blocks == 0 && num_files > 1) {
+		num_blocks = fs_blocks / num_files;
+		fs_blocks -= (num_files / 16) + 1;
+		fs_blocks -= calc_overhead(fs, num_blocks) * num_files;
+		num_blocks = fs_blocks / num_files;
+	}
+
+	num_slack += calc_overhead(fs, num_blocks) * num_files;
+	num_slack += (num_files / 16) + 1; /* space for dir entries */
+	goal = get_start_block(fs, num_slack);
+	goal = round_up_align(goal, align);
+
+	if (!quiet) {
+		if (zero_hugefile && verbose)
+			printf(_("Huge files will be zero'ed\n"));
+		printf(_("Creating %lu huge file(s) "), num_files);
+		if (num_blocks)
+			printf(_("with %llu blocks each"), num_blocks);
+		fputs(": ", stdout);
+	}
+	for (i=0; i < num_files; i++) {
+		ext2_ino_t ino;
+
+		retval = mk_hugefile(fs, num_blocks, dir, i, &ino);
+		if (retval) {
+			com_err(program_name, retval,
+				_("while creating huge file %lu"), i);
+			goto errout;
+		}
+	}
+	if (!quiet)
+		fputs(_("done\n"), stdout);
+
+errout:
+	free(fn_buf);
+	return retval;
+}
--- e2fsprogs-1.42.9.orig/misc/mke2fs.8.in
+++ e2fsprogs-1.42.9/misc/mke2fs.8.in
@@ -64,7 +64,7 @@ mke2fs \- create an ext2/ext3/ext4 files
 ]
 [
 .B \-O
-.IR feature [,...]
+[^]\fIfeature\fR[,...]
 ]
 [
 .B \-q
@@ -246,6 +246,10 @@ parity disk, so N will be the number of
 This allows the block allocator to prevent read-modify-write of the
 parity in a RAID stripe if possible when the data is written.
 .TP
+.BI offset= offset
+Create the filesystem at an offset from the beginning of the device or
+file.  This can be useful when creating disk images for virtual machines.
+.TP
 .BI resize= max-online-resize
 Reserve enough space so that the block group descriptor table can grow
 to support a filesystem that has
@@ -270,6 +274,22 @@ small risk if the system crashes before
 entirely one time.  If the option value is omitted, it defaults to 1 to
 enable lazy journal inode zeroing.
 .TP
+.BI num_backup_sb= <0|1|2>
+If the
+.B sparse_super2
+file system feature is enabled this option controls whether there will
+be 0, 1, or 2 backup superblocks created in the file system.
+.TP
+.B packed_meta_blocks\fR[\fB= \fI<0 to disable, 1 to enable>\fR]
+Place the allocation bitmaps and the inode table at the beginning of the
+disk.  This option requires that the flex_bg file system feature to be
+enabled in order for it to have effect, and will also create the journal
+at the beginning of the file system.  This option is useful for flash
+devices that use SLC flash at the beginning of the disk.
+It also maximizes the range of contiguous data blocks, which
+can be useful for certain specialized use cases, such as supported
+Shingled Drives.
+.TP
 .BI root_owner [=uid:gid]
 Specify the numeric user and group ID of the root directory.  If no UID:GID
 is specified, use the user and group ID of the user running \fBmke2fs\fR.
@@ -405,6 +425,13 @@ The size of the journal must be at least
 (i.e., 1MB if using 1k blocks, 4MB if using 4k blocks, etc.)
 and may be no more than 10,240,000 filesystem blocks or half the total
 file system size (whichever is smaller)
+.TP
+.BI location =journal-location
+Specify the location of the journal.  The argument
+.I journal-location
+can either be specified as a block number, or if the number has a units
+suffix (e.g., 'M', 'G', etc.) interpret it as the offset from the
+beginning of the file system.
 @JDEV@.TP
 @JDEV@.BI device= external-journal
 @JDEV@Attach the filesystem to the journal block device located on
@@ -508,7 +535,7 @@ filesystem.  The creator field is set by
 .B mke2fs
 executable was compiled for.
 .TP
-.B "\-O \fIfeature\fR[,...]"
+.B "\-O \fR[^]\fIfeature\fR[,...]"
 Create a filesystem with the given features (filesystem options),
 overriding the default filesystem options.  The features that are
 enabled by default are specified by the
@@ -544,7 +571,7 @@ section of the configuration file.
 .sp
 The filesystem feature set is comprised of a list of features, separated
 by commas, that are to be enabled.  To disable a feature, simply
-prefix the feature name with a  caret ('^') or a minus ('-') character.
+prefix the feature name with a caret ('^') character.
 Features with dependencies will not be removed successfully.
 The pseudo-filesystem feature "none" will clear all filesystem features.
 .TP
--- e2fsprogs-1.42.9.orig/misc/mke2fs.c
+++ e2fsprogs-1.42.9/misc/mke2fs.c
@@ -62,6 +62,7 @@ extern int optind;
 #include "../version.h"
 #include "nls-enable.h"
 #include "quota/mkquota.h"
+#include "mke2fs.h"
 
 #define STRIDE_LENGTH 8
 
@@ -76,26 +77,30 @@ extern int optind;
 extern int isatty(int);
 extern FILE *fpopen(const char *cmd, const char *mode);
 
-static const char * program_name = "mke2fs";
+const char * program_name = "mke2fs";
 static const char * device_name /* = NULL */;
 
 /* Command line options */
 static int	cflag;
-static int	verbose;
-static int	quiet;
+int	verbose;
+int	quiet;
 static int	super_only;
 static int	discard = 1;	/* attempt to discard device before fs creation */
 static int	direct_io;
 static int	force;
 static int	noaction;
+static int	num_backups = 2; /* number of backup bg's for sparse_super2 */
 static uid_t	root_uid;
 static gid_t	root_gid;
 int	journal_size;
 int	journal_flags;
 static int	lazy_itable_init;
+static int	packed_meta_blocks;
 static char	*bad_blocks_filename = NULL;
 static __u32	fs_stride;
 static int	quotatype = -1;  /* Initialize both user and group quotas by default */
+static __u64	offset;
+static blk64_t journal_location = ~0LL;
 
 static struct ext2_super_block fs_param;
 static char *fs_uuid = NULL;
@@ -104,7 +109,7 @@ static char *volume_label;
 static char *mount_dir;
 char *journal_device;
 static int sync_kludge;	/* Set using the MKE2FS_SYNC env. option */
-static char **fs_types;
+char **fs_types;
 
 static profile_t	profile;
 
@@ -139,7 +144,7 @@ static int int_log2(unsigned long long a
 	return l;
 }
 
-static int int_log10(unsigned long long arg)
+int int_log10(unsigned long long arg)
 {
 	int	l;
 
@@ -308,6 +313,40 @@ _("Warning: the backup superblock/group
 	ext2fs_badblocks_list_iterate_end(bb_iter);
 }
 
+static errcode_t packed_allocate_tables(ext2_filsys fs)
+{
+	errcode_t	retval;
+	dgrp_t		i;
+	blk64_t		goal = 0;
+
+	for (i = 0; i < fs->group_desc_count; i++) {
+		retval = ext2fs_new_block2(fs, goal, NULL, &goal);
+		if (retval)
+			return retval;
+		ext2fs_block_alloc_stats2(fs, goal, +1);
+		ext2fs_block_bitmap_loc_set(fs, i, goal);
+	}
+	for (i = 0; i < fs->group_desc_count; i++) {
+		retval = ext2fs_new_block2(fs, goal, NULL, &goal);
+		if (retval)
+			return retval;
+		ext2fs_block_alloc_stats2(fs, goal, +1);
+		ext2fs_inode_bitmap_loc_set(fs, i, goal);
+	}
+	for (i = 0; i < fs->group_desc_count; i++) {
+		blk64_t end = ext2fs_blocks_count(fs->super) - 1;
+		retval = ext2fs_get_free_blocks2(fs, goal, end,
+						 fs->inode_blocks_per_group,
+						 fs->block_map, &goal);
+		if (retval)
+			return retval;
+		ext2fs_block_alloc_stats_range(fs, goal,
+					       fs->inode_blocks_per_group, +1);
+		ext2fs_inode_table_loc_set(fs, i, goal);
+	}
+	return 0;
+}
+
 static void write_inode_tables(ext2_filsys fs, int lazy_flag, int itable_zeroed)
 {
 	errcode_t	retval;
@@ -710,6 +749,19 @@ static void parse_extended_opts(struct e
 				continue;
 			}
 			param->s_desc_size = desc_size;
+		} else if (strcmp(token, "offset") == 0) {
+			if (!arg) {
+				r_usage++;
+				badopt = token;
+				continue;
+			}
+			offset = strtoull(arg, &p, 0);
+			if (*p) {
+				fprintf(stderr, _("Invalid offset: %s\n"),
+					arg);
+				r_usage++;
+				continue;
+			}
 		} else if (strcmp(token, "mmp_update_interval") == 0) {
 			if (!arg) {
 				r_usage++;
@@ -724,6 +776,28 @@ static void parse_extended_opts(struct e
 				r_usage++;
 				continue;
 			}
+		} else if (strcmp(token, "num_backup_sb") == 0) {
+			if (!arg) {
+				r_usage++;
+				badopt = token;
+				continue;
+			}
+			num_backups = strtoul(arg, &p, 0);
+			if (*p || num_backups > 2) {
+				fprintf(stderr,
+					_("Invalid # of backup "
+					  "superbocks: %s\n"),
+					arg);
+				r_usage++;
+				continue;
+			}
+		} else if (strcmp(token, "packed_meta_blocks") == 0) {
+			if (arg)
+				packed_meta_blocks = strtoul(arg, &p, 0);
+			else
+				packed_meta_blocks = 1;
+			if (packed_meta_blocks)
+				journal_location = 0;
 		} else if (strcmp(token, "stride") == 0) {
 			if (!arg) {
 				r_usage++;
@@ -879,9 +953,13 @@ static void parse_extended_opts(struct e
 			"and may take an argument which\n"
 			"\tis set off by an equals ('=') sign.\n\n"
 			"Valid extended options are:\n"
+			"\tmmp_update_interval=<interval>\n"
+			"\tnum_backup_sb=<0|1|2>\n"
 			"\tstride=<RAID per-disk data chunk in blocks>\n"
 			"\tstripe-width=<RAID stride * data disks in blocks>\n"
+			"\toffset=<offset to create the file system>\n"
 			"\tresize=<resize maximum size in blocks>\n"
+			"\tpacked_meta_blocks=<0 to disable, 1 to enable>\n"
 			"\tlazy_itable_init=<0 to disable, 1 to enable>\n"
 			"\tlazy_journal_init=<0 to disable, 1 to enable>\n"
 			"\troot_uid=<uid of root directory>\n"
@@ -908,7 +986,8 @@ static __u32 ok_features[3] = {
 	EXT3_FEATURE_COMPAT_HAS_JOURNAL |
 		EXT2_FEATURE_COMPAT_RESIZE_INODE |
 		EXT2_FEATURE_COMPAT_DIR_INDEX |
-		EXT2_FEATURE_COMPAT_EXT_ATTR,
+		EXT2_FEATURE_COMPAT_EXT_ATTR |
+		EXT4_FEATURE_COMPAT_SPARSE_SUPER2,
 	/* Incompat */
 	EXT2_FEATURE_INCOMPAT_FILETYPE|
 		EXT3_FEATURE_INCOMPAT_EXTENTS|
@@ -1165,7 +1244,7 @@ static char **parse_fs_type(const char *
 	return (list.list);
 }
 
-static char *get_string_from_profile(char **types, const char *opt,
+char *get_string_from_profile(char **types, const char *opt,
 				     const char *def_val)
 {
 	char *ret = 0;
@@ -1182,7 +1261,7 @@ static char *get_string_from_profile(cha
 	return (ret);
 }
 
-static int get_int_from_profile(char **types, const char *opt, int def_val)
+int get_int_from_profile(char **types, const char *opt, int def_val)
 {
 	int ret;
 	char **cpp;
@@ -1205,7 +1284,7 @@ static double get_double_from_profile(ch
 	return ret;
 }
 
-static int get_bool_from_profile(char **types, const char *opt, int def_val)
+int get_bool_from_profile(char **types, const char *opt, int def_val)
 {
 	int ret;
 	char **cpp;
@@ -1958,6 +2037,8 @@ profile_error:
 	}
 #endif
 
+	num_backups = get_int_from_profile(fs_types, "num_backup_sb", 2);
+
 	blocksize = EXT2_BLOCK_SIZE(&fs_param);
 
 	/*
@@ -1994,6 +2075,20 @@ profile_error:
 					       EXT2_MKJOURNAL_LAZYINIT : 0;
 	journal_flags |= EXT2_MKJOURNAL_NO_MNT_CHECK;
 
+	if (!journal_location_string)
+		journal_location_string = get_string_from_profile(fs_types,
+						"journal_location", "");
+	if ((journal_location == ~0ULL) && journal_location_string &&
+	    *journal_location_string)
+		journal_location = parse_num_blocks2(journal_location_string,
+						fs_param.s_log_block_size);
+	free(journal_location_string);
+
+	packed_meta_blocks = get_bool_from_profile(fs_types,
+						   "packed_meta_blocks", 0);
+	if (packed_meta_blocks)
+		journal_location = 0;
+
 	/* Get options from profile */
 	for (cpp = fs_types; *cpp; cpp++) {
 		tmp = NULL;
@@ -2145,6 +2240,13 @@ profile_error:
 	ext2fs_r_blocks_count_set(&fs_param, reserved_ratio *
 				  ext2fs_blocks_count(&fs_param) / 100.0);
 
+	if (fs_param.s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+		if (num_backups >= 1)
+			fs_param.s_backup_bgs[0] = 1;
+		if (num_backups >= 2)
+			fs_param.s_backup_bgs[1] = ~0;
+	}
+
 	free(fs_type);
 	free(usage_types);
 }
@@ -2238,11 +2340,9 @@ static int mke2fs_setup_tdb(const char *
 	sprintf(tdb_file, "%s/mke2fs-%s.e2undo", tdb_dir, dev_name);
 	free(tmp_name);
 
-	if (!access(tdb_file, F_OK)) {
-		if (unlink(tdb_file) < 0) {
-			retval = errno;
-			goto errout;
-		}
+	if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
+		retval = errno;
+		goto errout;
 	}
 
 	set_undo_io_backing_manager(*io_ptr);
@@ -2318,30 +2418,43 @@ static int mke2fs_discard_device(ext2_fi
 
 static void fix_cluster_bg_counts(ext2_filsys fs)
 {
-	blk64_t	cluster, num_clusters, tot_free;
-	unsigned num = 0;
-	int	grp_free, num_free, group;
-
-	num_clusters = EXT2FS_B2C(fs, ext2fs_blocks_count(fs->super));
-	tot_free = num_free = group = grp_free = 0;
-	for (cluster = EXT2FS_B2C(fs, fs->super->s_first_data_block);
-	     cluster < num_clusters; cluster++) {
-		if (!ext2fs_test_block_bitmap2(fs->block_map,
-					       EXT2FS_C2B(fs, cluster))) {
-			grp_free++;
-			tot_free++;
-		}
-		num++;
-		if ((num == fs->super->s_clusters_per_group) ||
-		    (cluster == num_clusters-1)) {
+	blk64_t		block, num_blocks, last_block, next;
+	blk64_t		tot_free = 0;
+	errcode_t	retval;
+	dgrp_t		group = 0;
+	int		grp_free = 0;
+
+	num_blocks = ext2fs_blocks_count(fs->super);
+	last_block = ext2fs_group_last_block2(fs, group);
+	block = fs->super->s_first_data_block;
+	while (block < num_blocks) {
+		retval = ext2fs_find_first_zero_block_bitmap2(fs->block_map,
+						block, last_block, &next);
+		if (retval == 0)
+			block = next;
+		else {
+			block = last_block + 1;
+			goto next_bg;
+		}
+
+		retval = ext2fs_find_first_set_block_bitmap2(fs->block_map,
+						block, last_block, &next);
+		if (retval)
+			next = last_block + 1;
+		grp_free += EXT2FS_NUM_B2C(fs, next - block);
+		tot_free += next - block;
+		block = next;
+
+		if (block > last_block) {
+		next_bg:
 			ext2fs_bg_free_blocks_count_set(fs, group, grp_free);
 			ext2fs_group_desc_csum_set(fs, group);
-			num = 0;
 			grp_free = 0;
 			group++;
+			last_block = ext2fs_group_last_block2(fs, group);
 		}
 	}
-	ext2fs_free_blocks_count_set(fs->super, EXT2FS_C2B(fs, tot_free));
+	ext2fs_free_blocks_count_set(fs->super, tot_free);
 }
 
 static int create_quota_inodes(ext2_filsys fs)
@@ -2368,7 +2481,7 @@ int main (int argc, char *argv[])
 	int		flags;
 	int		old_bitmaps;
 	io_manager	io_ptr;
-	char		tdb_string[40];
+	char		opt_string[40];
 	char		*hash_alg_str;
 	int		itable_zeroed = 0;
 
@@ -2435,12 +2548,17 @@ int main (int argc, char *argv[])
 					 "0s - skipping inode table wipe\n"));
 			lazy_itable_init = 1;
 			itable_zeroed = 1;
+			zero_hugefile = 0;
 		}
 	}
 
-	sprintf(tdb_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
+	sprintf(opt_string, "tdb_data_size=%d", fs->blocksize <= 4096 ?
 		32768 : fs->blocksize * 8);
-	io_channel_set_options(fs->io, tdb_string);
+	io_channel_set_options(fs->io, opt_string);
+	if (offset) {
+		sprintf(opt_string, "offset=%llu", offset);
+		io_channel_set_options(fs->io, opt_string);
+	}
 
 	if (fs_param.s_flags & EXT2_FLAGS_TEST_FILESYS)
 		fs->super->s_flags |= EXT2_FLAGS_TEST_FILESYS;
@@ -2562,12 +2680,16 @@ int main (int argc, char *argv[])
 		read_bb_file(fs, &bb_list, bad_blocks_filename);
 	if (cflag)
 		test_disk(fs, &bb_list);
-
 	handle_bad_blocks(fs, bb_list);
+
 	fs->stride = fs_stride = fs->super->s_raid_stride;
 	if (!quiet)
 		printf("%s", _("Allocating group tables: "));
-	retval = ext2fs_allocate_tables(fs);
+	if ((fs->super->s_feature_incompat & EXT4_FEATURE_INCOMPAT_FLEX_BG) &&
+	    packed_meta_blocks)
+		retval = packed_allocate_tables(fs);
+	else
+		retval = ext2fs_allocate_tables(fs);
 	if (retval) {
 		com_err(program_name, retval, "%s",
 			_("while trying to allocate filesystem tables"));
@@ -2693,8 +2815,9 @@ int main (int argc, char *argv[])
 			       journal_blocks);
 			fflush(stdout);
 		}
-		retval = ext2fs_add_journal_inode(fs, journal_blocks,
-						  journal_flags);
+		retval = ext2fs_add_journal_inode2(fs, journal_blocks,
+						   journal_location,
+						   journal_flags);
 		if (retval) {
 			com_err(program_name, retval, "%s",
 				_("\n\twhile trying to create journal"));
@@ -2726,6 +2849,10 @@ no_journal:
 				       EXT4_FEATURE_RO_COMPAT_QUOTA))
 		create_quota_inodes(fs);
 
+	retval = mk_hugefiles(fs);
+	if (retval)
+		com_err(program_name, retval, "while creating huge files");
+
 	if (!quiet)
 		printf("%s", _("Writing superblocks and "
 		       "filesystem accounting information: "));
--- e2fsprogs-1.42.9.orig/misc/mke2fs.conf.5.in
+++ e2fsprogs-1.42.9/misc/mke2fs.conf.5.in
@@ -357,6 +357,18 @@ initialization noticeably, but it requir
 initializing the filesystem in the background when the filesystem is
 first mounted.
 .TP
+.I journal_location
+This relation specifies the location of the journal.
+.TP
+.I num_backup_sb
+This relation indicates whether file systems with the
+.B sparse_super2
+feature enabled should be created with 0, 1, or 2 backup superblocks.
+.TP
+.I packed_meta_blocks
+This boolean relation specifes whether the allocation bitmaps, inode
+table, and journal should be located at the beginning of the file system.
+.TP
 .I inode_ratio
 This relation specifies the default inode ratio if the user does not
 specify one on the command line.
@@ -408,6 +420,71 @@ system feature is enabled.  It can be ov
 .B \-C
 command line option to
 .BR mke2fs (8)
+.TP
+.I make_hugefiles
+This boolean relation enables the creation of pre-allocated files as
+part of formatting the file system.
+.TP
+.I hugefiles_uid
+This relation controls the user ownership for all of the files and
+directories created by the
+.I make_hugefiles
+feature.
+.TP
+.I hugefiles_gid
+This relation controls the group ownership for all of the files and
+directories created by the
+.I make_hugefiles
+feature.
+.TP
+.I hugefiles_umask
+This relation specifies the umask used when creating the files and
+directories by the
+.I make_hugefiles
+feature.
+.TP
+.I num_hugefiles
+This relation specifies the number of huge files to be created.  If this
+relation is not specified, or is set to zero, and the
+.I hugefiles_size
+relation is non-zero, then
+.I make_hugefiles
+will create as many huge files as can fit to fill the entire file system.
+.TP
+.I hugefiles_slack
+This relation specifies how much space should be reserved for other
+files.
+.TP
+.I hugefiles_size
+This relation specifies the size of the huge files.  If this relation is
+not specified, the default is to fill the entire file system.
+.TP
+.I hugefiles_align
+This relation specifies the alignment for the start block of the huge
+files.  It also forces the size of huge files to be a multiple of the
+requested alignment.  If this relation is not specified, no alignment
+requirement will be imposed on the huge files.
+.TP
+.I hugefiles_name
+This relation specifies the base file name for the huge files.
+.TP
+.I hugefiles_digits
+This relation specifies the (zero-padded) width of the field for the
+huge file number.
+.TP
+.I zero_hugefiles
+This boolean relation specifies whether or not zero blocks will be
+written to the hugefiles while
+.BR mke2fs(8)
+is creating them.  By default, zero blocks will be written to the huge
+files to avoid stale data from being made available to potentially
+untrusted user programs, unless the device supports a discard/trim
+operation which will take care of zeroing the device blocks.  By
+.I zero_hugefiles
+to false, this step will always be skipped, which can be useful if it is
+known that the disk has been previously erased, or if the user programs
+that will have access to the huge files are trusted to not reveal stale
+data.
 .SH THE [devices] STANZA
 Each tag in the
 .I [devices] 
--- /dev/null
+++ e2fsprogs-1.42.9/misc/mke2fs.h
@@ -0,0 +1,30 @@
+/*
+ * mke2fs.h
+ *
+ * Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ * 	2003, 2004, 2005 by Theodore Ts'o.
+ *
+ * %Begin-Header%
+ * This file may be redistributed under the terms of the GNU Public
+ * License.
+ * %End-Header%
+ */
+
+/* mke2fs.c */
+extern const char * program_name;
+extern int	quiet;
+extern int	verbose;
+extern int	zero_hugefile;
+extern char **fs_types;
+
+extern char *get_string_from_profile(char **types, const char *opt,
+				     const char *def_val);
+extern int get_int_from_profile(char **types, const char *opt, int def_val);
+extern int get_bool_from_profile(char **types, const char *opt, int def_val);
+extern int int_log10(unsigned long long arg);
+
+/* mk_hugefiles.c */
+extern errcode_t mk_hugefiles(ext2_filsys fs);
+
+
+
--- e2fsprogs-1.42.9.orig/misc/tune2fs.8.in
+++ e2fsprogs-1.42.9/misc/tune2fs.8.in
@@ -333,6 +333,13 @@ megabytes.   The size of the journal mus
 and may be no more than 102,400 filesystem blocks.
 There must be enough free space in the filesystem to create a journal of
 that size.
+.TP
+.BI location =journal-location
+Specify the location of the journal.  The argument
+.I journal-location
+can either be specified as a block number, or if the number has a units
+suffix (e.g., 'M', 'G', etc.) interpret it as the offset from the
+beginning of the file system.
 @JDEV@.TP
 @JDEV@.BI device= external-journal
 @JDEV@Attach the filesystem to the journal block device located on
--- e2fsprogs-1.42.9.orig/misc/tune2fs.c
+++ e2fsprogs-1.42.9/misc/tune2fs.c
@@ -98,6 +98,7 @@ static int usrquota, grpquota;
 
 int journal_size, journal_flags;
 char *journal_device;
+static blk64_t journal_location = ~0LL;
 
 static struct list_head blk_move_list;
 
@@ -694,8 +695,13 @@ static int add_journal(ext2_filsys fs)
 		fflush(stdout);
 		journal_blocks = figure_journal_size(journal_size, fs);
 
-		retval = ext2fs_add_journal_inode(fs, journal_blocks,
-						  journal_flags);
+		if (journal_location_string)
+			journal_location =
+				parse_num_blocks2(journal_location_string,
+						  fs->super->s_log_block_size);
+		retval = ext2fs_add_journal_inode2(fs, journal_blocks,
+						   journal_location,
+						   journal_flags);
 		if (retval) {
 			fprintf(stderr, "\n");
 			com_err(program_name, retval, "%s",
@@ -1856,15 +1862,12 @@ static int tune2fs_setup_tdb(const char
 		goto alloc_fn_fail;
 	sprintf(tdb_file, "%s/tune2fs-%s.e2undo", tdb_dir, dev_name);
 
-	if (!access(tdb_file, F_OK)) {
-		if (unlink(tdb_file) < 0) {
-			retval = errno;
-			com_err(program_name, retval,
-				_("while trying to delete %s"),
-				tdb_file);
-			free(tdb_file);
-			return retval;
-		}
+	if ((unlink(tdb_file) < 0) && (errno != ENOENT)) {
+		retval = errno;
+		com_err(program_name, retval,
+			_("while trying to delete %s"), tdb_file);
+		free(tdb_file);
+		return retval;
 	}
 
 	set_undo_io_backing_manager(*io_ptr);
--- e2fsprogs-1.42.9.orig/misc/util.c
+++ e2fsprogs-1.42.9/misc/util.c
@@ -34,6 +34,8 @@
 #include "blkid/blkid.h"
 #include "util.h"
 
+char *journal_location_string = NULL;
+
 #ifndef HAVE_STRCASECMP
 int strcasecmp (char *s1, char *s2)
 {
@@ -218,6 +220,12 @@ void parse_journal_opts(const char *opts
 			journal_size = strtoul(arg, &p, 0);
 			if (*p)
 				journal_usage++;
+		} else if (!strcmp(token, "location")) {
+			if (!arg) {
+				journal_usage++;
+				continue;
+			}
+			journal_location_string = strdup(arg);
 		} else if (strcmp(token, "v1_superblock") == 0) {
 			journal_flags |= EXT2_MKJOURNAL_V1_SUPER;
 			continue;
@@ -231,7 +239,8 @@ void parse_journal_opts(const char *opts
 			"\tis set off by an equals ('=') sign.\n\n"
 			"Valid journal options are:\n"
 			"\tsize=<journal size in megabytes>\n"
-			"\tdevice=<journal device>\n\n"
+			"\tdevice=<journal device>\n"
+			"\tlocation=<journal location>\n\n"
 			"The journal size must be between "
 			"1024 and 10240000 filesystem blocks.\n\n"), stderr);
 		free(buf);
--- e2fsprogs-1.42.9.orig/misc/util.h
+++ e2fsprogs-1.42.9/misc/util.h
@@ -13,6 +13,7 @@
 extern int	 journal_size;
 extern int	 journal_flags;
 extern char	*journal_device;
+extern char	*journal_location_string;
 
 #ifndef HAVE_STRCASECMP
 extern int strcasecmp (char *s1, char *s2);
--- e2fsprogs-1.42.9.orig/resize/Makefile.in
+++ e2fsprogs-1.42.9/resize/Makefile.in
@@ -28,11 +28,11 @@ SRCS= $(srcdir)/extent.c \
 	$(srcdir)/resource_track.c \
 	$(srcdir)/sim_progress.c
 
-LIBS= $(LIBE2P) $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBINTL)
+LIBS= $(LIBE2P) $(LIBEXT2FS) $(LIBCOM_ERR) $(LIBINTL) $(SYSLIBS)
 DEPLIBS= $(LIBE2P) $(LIBEXT2FS) $(DEPLIBCOM_ERR)
 
 STATIC_LIBS= $(STATIC_LIBE2P) $(STATIC_LIBEXT2FS) $(STATIC_LIBCOM_ERR) \
-	$(LIBINTL)
+	$(LIBINTL) $(SYSLIBS)
 DEPSTATIC_LIBS= $(STATIC_LIBE2P) $(STATIC_LIBEXT2FS) $(DEPSTATIC_LIBCOM_ERR) 
 
 .c.o:
--- e2fsprogs-1.42.9.orig/resize/online.c
+++ e2fsprogs-1.42.9/resize/online.c
@@ -76,6 +76,14 @@ errcode_t online_resize_fs(ext2_filsys f
 			no_resize_ioctl = 1;
 	}
 
+	if (EXT2_HAS_COMPAT_FEATURE(fs->super,
+				    EXT4_FEATURE_COMPAT_SPARSE_SUPER2) &&
+	    (access("/sys/fs/ext4/features/sparse_super2", R_OK) != 0)) {
+		com_err(program_name, 0, _("kernel does not support online "
+					   "resize with sparse_super2"));
+		exit(1);
+	}
+
 	printf(_("Filesystem at %s is mounted on %s; "
 		 "on-line resizing required\n"), fs->device_name, mtpt);
 
--- e2fsprogs-1.42.9.orig/resize/resize2fs.c
+++ e2fsprogs-1.42.9/resize/resize2fs.c
@@ -53,6 +53,9 @@ static errcode_t ext2fs_calculate_summar
 static errcode_t fix_sb_journal_backup(ext2_filsys fs);
 static errcode_t mark_table_blocks(ext2_filsys fs,
 				   ext2fs_block_bitmap bmap);
+static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs);
+static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
+						 ext2fs_block_bitmap meta_bmap);
 
 /*
  * Some helper CPP macros
@@ -191,6 +194,10 @@ errcode_t resize_fs(ext2_filsys fs, blk6
 		goto errout;
 	print_resource_track(rfs, &rtrack, fs->io);
 
+	retval = clear_sparse_super2_last_group(rfs);
+	if (retval)
+		goto errout;
+
 	rfs->new_fs->super->s_state &= ~EXT2_ERROR_FS;
 	rfs->new_fs->flags &= ~EXT2_FLAG_MASTER_SB_ONLY;
 
@@ -460,6 +467,33 @@ retry:
 	}
 
 	/*
+	 * Update the location of the backup superblocks if the
+	 * sparse_super2 feature is enabled.
+	 */
+	if (fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2) {
+		dgrp_t last_bg = fs->group_desc_count - 1;
+		dgrp_t old_last_bg = old_fs->group_desc_count - 1;
+
+		if (last_bg > old_last_bg) {
+			if (old_fs->group_desc_count == 1)
+				fs->super->s_backup_bgs[0] = 1;
+			if (old_fs->group_desc_count == 1 &&
+			    fs->super->s_backup_bgs[0])
+				fs->super->s_backup_bgs[0] = last_bg;
+			else if (fs->super->s_backup_bgs[1])
+				fs->super->s_backup_bgs[1] = last_bg;
+		} else if (last_bg < old_last_bg) {
+			if (fs->super->s_backup_bgs[0] > last_bg)
+				fs->super->s_backup_bgs[0] = 0;
+			if (fs->super->s_backup_bgs[1] > last_bg)
+				fs->super->s_backup_bgs[1] = 0;
+			if (last_bg > 1 &&
+			    old_fs->super->s_backup_bgs[1] == old_last_bg)
+				fs->super->s_backup_bgs[1] = last_bg;
+		}
+	}
+
+	/*
 	 * If we are shrinking the number of block groups, we're done
 	 * and can exit now.
 	 */
@@ -615,14 +649,13 @@ errout:
  */
 static errcode_t adjust_superblock(ext2_resize_t rfs, blk64_t new_size)
 {
-	ext2_filsys fs;
+	ext2_filsys	fs = rfs->new_fs;
 	int		adj = 0;
 	errcode_t	retval;
 	blk64_t		group_block;
 	unsigned long	i;
 	unsigned long	max_group;
 
-	fs = rfs->new_fs;
 	ext2fs_mark_super_dirty(fs);
 	ext2fs_mark_bb_dirty(fs);
 	ext2fs_mark_ib_dirty(fs);
@@ -952,6 +985,10 @@ static errcode_t blocks_to_move(ext2_res
 		new_blocks = fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
 	}
 
+	retval = reserve_sparse_super2_last_group(rfs, meta_bmap);
+	if (retval)
+		goto errout;
+
 	if (old_blocks == new_blocks) {
 		retval = 0;
 		goto errout;
@@ -1840,6 +1877,147 @@ errout:
 }
 
 /*
+ * This function is used when expanding a file system.  It frees the
+ * superblock and block group descriptor blocks from the block group
+ * which is no longer the last block group.
+ */
+static errcode_t clear_sparse_super2_last_group(ext2_resize_t rfs)
+{
+	ext2_filsys	fs = rfs->new_fs;
+	ext2_filsys	old_fs = rfs->old_fs;
+	errcode_t	retval;
+	dgrp_t		old_last_bg = rfs->old_fs->group_desc_count - 1;
+	dgrp_t		last_bg = fs->group_desc_count - 1;
+	blk64_t		sb, old_desc;
+	blk_t		num;
+
+	if (!(fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2))
+		return 0;
+
+	if (last_bg <= old_last_bg)
+		return 0;
+
+	if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] &&
+	    fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1])
+		return 0;
+
+	if (old_fs->super->s_backup_bgs[0] != old_last_bg &&
+	    old_fs->super->s_backup_bgs[1] != old_last_bg)
+		return 0;
+
+	if (fs->super->s_backup_bgs[0] == old_last_bg ||
+	    fs->super->s_backup_bgs[1] == old_last_bg)
+		return 0;
+
+	retval = ext2fs_super_and_bgd_loc2(rfs->old_fs, old_last_bg,
+					   &sb, &old_desc, NULL, &num);
+	if (retval)
+		return retval;
+
+	if (sb)
+		ext2fs_unmark_block_bitmap2(fs->block_map, sb);
+	if (old_desc)
+		ext2fs_unmark_block_bitmap_range2(fs->block_map, old_desc, num);
+	return 0;
+}
+
+/*
+ * This function is used when shrinking a file system.  We need to
+ * utilize blocks from what will be the new last block group for the
+ * backup superblock and block group descriptor blocks.
+ * Unfortunately, those blocks may be used by other files or fs
+ * metadata blocks.  We need to mark them as being in use.
+ */
+static errcode_t reserve_sparse_super2_last_group(ext2_resize_t rfs,
+						 ext2fs_block_bitmap meta_bmap)
+{
+	ext2_filsys	fs = rfs->new_fs;
+	ext2_filsys	old_fs = rfs->old_fs;
+	errcode_t	retval;
+	dgrp_t		old_last_bg = rfs->old_fs->group_desc_count - 1;
+	dgrp_t		last_bg = fs->group_desc_count - 1;
+	dgrp_t		g;
+	blk64_t		blk, sb, old_desc;
+	blk_t		i, num;
+	int		realloc = 0;
+
+	if (!(fs->super->s_feature_compat & EXT4_FEATURE_COMPAT_SPARSE_SUPER2))
+		return 0;
+
+	if (last_bg >= old_last_bg)
+		return 0;
+
+	if (fs->super->s_backup_bgs[0] == old_fs->super->s_backup_bgs[0] &&
+	    fs->super->s_backup_bgs[1] == old_fs->super->s_backup_bgs[1])
+		return 0;
+
+	if (fs->super->s_backup_bgs[0] != last_bg &&
+	    fs->super->s_backup_bgs[1] != last_bg)
+		return 0;
+
+	if (old_fs->super->s_backup_bgs[0] == last_bg ||
+	    old_fs->super->s_backup_bgs[1] == last_bg)
+		return 0;
+
+	retval = ext2fs_super_and_bgd_loc2(rfs->new_fs, last_bg,
+					   &sb, &old_desc, NULL, &num);
+	if (retval)
+		return retval;
+
+	if (!sb) {
+		fputs(_("Should never happen!  No sb in last super_sparse bg?\n"),
+		      stderr);
+		exit(1);
+	}
+	if (old_desc != sb+1) {
+		fputs(_("Should never happen!  Unexpected old_desc in "
+			"super_sparse bg?\n"),
+		      stderr);
+		exit(1);
+	}
+	num = (old_desc) ? num : 1;
+
+	/* Reserve the backup blocks */
+	ext2fs_mark_block_bitmap_range2(fs->block_map, sb, num);
+
+	for (g = 0; g < fs->group_desc_count; g++) {
+		blk64_t mb;
+
+		mb = ext2fs_block_bitmap_loc(fs, g);
+		if ((mb >= sb) && (mb < sb + num)) {
+			ext2fs_block_bitmap_loc_set(fs, g, 0);
+			realloc = 1;
+		}
+		mb = ext2fs_inode_bitmap_loc(fs, g);
+		if ((mb >= sb) && (mb < sb + num)) {
+			ext2fs_inode_bitmap_loc_set(fs, g, 0);
+			realloc = 1;
+		}
+		mb = ext2fs_inode_table_loc(fs, g);
+		if ((mb < sb + num) &&
+		    (sb < mb + fs->inode_blocks_per_group)) {
+			ext2fs_inode_table_loc_set(fs, g, 0);
+			realloc = 1;
+		}
+		if (realloc) {
+			retval = ext2fs_allocate_group_table(fs, g, 0);
+			if (retval)
+				return retval;
+		}
+	}
+
+	for (blk = sb, i = 0; i < num; blk++, i++) {
+		if (ext2fs_test_block_bitmap2(old_fs->block_map, blk) &&
+		    !ext2fs_test_block_bitmap2(meta_bmap, blk)) {
+			ext2fs_mark_block_bitmap2(rfs->move_blocks, blk);
+			rfs->needed_blocks++;
+		}
+		ext2fs_mark_block_bitmap2(rfs->reserve_blocks, blk);
+	}
+	return 0;
+}
+
+/*
  * Fix the resize inode
  */
 static errcode_t fix_resize_inode(ext2_filsys fs)
--- e2fsprogs-1.42.9.orig/resize/test_extent.c
+++ e2fsprogs-1.42.9/resize/test_extent.c
@@ -109,6 +109,8 @@ void do_test(FILE *in, FILE *out)
 		} else
 			fputs("# Syntax error\n", out);
 	}
+	if (extent)
+		ext2fs_free_extent_table(extent);
 }
 
 #ifdef __GNUC__
--- e2fsprogs-1.42.9.orig/tests/d_special_files/script
+++ e2fsprogs-1.42.9/tests/d_special_files/script
@@ -18,7 +18,7 @@ status=$?
 echo Exit status is $status >> $OUT
 
 $DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
-set_current_time 201301151400
+set_current_time 20130115140000
 set_super_value lastcheck 0
 set_super_value hash_seed null
 set_super_value mkfs_time 0
--- e2fsprogs-1.42.9.orig/tests/f_crashdisk/expect.1
+++ e2fsprogs-1.42.9/tests/f_crashdisk/expect.1
@@ -2,10 +2,12 @@ ext2fs_open2: The ext2 superblock is cor
 ../e2fsck/e2fsck: Superblock invalid, trying backup blocks...
 ../e2fsck/e2fsck: The ext2 superblock is corrupt while trying to open test.img
 
-The superblock could not be read or does not describe a correct ext2
-filesystem.  If the device is valid and it really contains an ext2
+The superblock could not be read or does not describe a valid ext2/ext3/ext4
+filesystem.  If the device is valid and it really contains an ext2/ext3/ext4
 filesystem (and not swap or ufs or something else), then the superblock
 is corrupt, and you might try running e2fsck with an alternate superblock:
     e2fsck -b 8193 <device>
+ or
+    e2fsck -b 32768 <device>
 
 Exit status is 8
--- e2fsprogs-1.42.9.orig/tests/f_dup4/script
+++ e2fsprogs-1.42.9/tests/f_dup4/script
@@ -8,7 +8,7 @@ echo "/ Murphy Magic.  The SeCrEt of the
 touch $TMPFILE
 $MKE2FS -N 32 -F -o Linux -b 1024 $TMPFILE 100 > /dev/null 2>&1 
 $DEBUGFS -w $TMPFILE << EOF > /dev/null 2>&1
-set_current_time 200704102100
+set_current_time 20070410210000
 set_super_value lastcheck 0
 set_super_value hash_seed null
 set_super_value mkfs_time 0
--- e2fsprogs-1.42.9.orig/tests/f_dup_resize/script
+++ e2fsprogs-1.42.9/tests/f_dup_resize/script
@@ -11,8 +11,8 @@ $DEBUGFS -w $TMPFILE << EOF > /dev/null
 freeb 4 4
 freeb 8195 4
 write $TEST_DATA debugfs
-set_current_time 200504110000
-set_inode_field debugfs mtime 200504110000
+set_current_time 20050411000000
+set_inode_field debugfs mtime 2005041100000000
 q
 EOF
 
--- e2fsprogs-1.42.9.orig/tests/m_bigjournal/expect.1
+++ e2fsprogs-1.42.9/tests/m_bigjournal/expect.1
@@ -55,7 +55,7 @@ Group 0: (Blocks 0-32767)
   31836 free blocks, 5 free inodes, 2 directories, 5 unused inodes
   Free blocks: 764-1184, 1269-1696, 1781-32767
   Free inodes: 12-16
-Group 1: (Blocks 32768-65535) [INODE_UNINIT]
+Group 1: (Blocks 32768-65535) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 32768, Group descriptors at 32769-32769
   Reserved GDT blocks at 32770-33440
   Block bitmap at 674 (bg #0 + 674), Inode bitmap at 1186 (bg #0 + 1186)
@@ -69,7 +69,7 @@ Group 2: (Blocks 65536-98303) [INODE_UNI
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 65536-98303
   Free inodes: 33-48
-Group 3: (Blocks 98304-131071) [INODE_UNINIT]
+Group 3: (Blocks 98304-131071) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 98304, Group descriptors at 98305-98305
   Reserved GDT blocks at 98306-98976
   Block bitmap at 676 (bg #0 + 676), Inode bitmap at 1188 (bg #0 + 1188)
@@ -83,7 +83,7 @@ Group 4: (Blocks 131072-163839) [INODE_U
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 131072-163839
   Free inodes: 65-80
-Group 5: (Blocks 163840-196607) [INODE_UNINIT]
+Group 5: (Blocks 163840-196607) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 163840, Group descriptors at 163841-163841
   Reserved GDT blocks at 163842-164512
   Block bitmap at 678 (bg #0 + 678), Inode bitmap at 1190 (bg #0 + 1190)
@@ -97,7 +97,7 @@ Group 6: (Blocks 196608-229375) [INODE_U
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 196608-229375
   Free inodes: 97-112
-Group 7: (Blocks 229376-262143) [INODE_UNINIT]
+Group 7: (Blocks 229376-262143) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 229376, Group descriptors at 229377-229377
   Reserved GDT blocks at 229378-230048
   Block bitmap at 680 (bg #0 + 680), Inode bitmap at 1192 (bg #0 + 1192)
@@ -111,7 +111,7 @@ Group 8: (Blocks 262144-294911) [INODE_U
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 262144-294911
   Free inodes: 129-144
-Group 9: (Blocks 294912-327679) [INODE_UNINIT]
+Group 9: (Blocks 294912-327679) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 294912, Group descriptors at 294913-294913
   Reserved GDT blocks at 294914-295584
   Block bitmap at 682 (bg #0 + 682), Inode bitmap at 1194 (bg #0 + 1194)
@@ -209,7 +209,7 @@ Group 24: (Blocks 786432-819199) [INODE_
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 786432-819199
   Free inodes: 385-400
-Group 25: (Blocks 819200-851967) [INODE_UNINIT]
+Group 25: (Blocks 819200-851967) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 819200, Group descriptors at 819201-819201
   Reserved GDT blocks at 819202-819872
   Block bitmap at 698 (bg #0 + 698), Inode bitmap at 1210 (bg #0 + 1210)
@@ -223,7 +223,7 @@ Group 26: (Blocks 851968-884735) [INODE_
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 851968-884735
   Free inodes: 417-432
-Group 27: (Blocks 884736-917503) [INODE_UNINIT]
+Group 27: (Blocks 884736-917503) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 884736, Group descriptors at 884737-884737
   Reserved GDT blocks at 884738-885408
   Block bitmap at 700 (bg #0 + 700), Inode bitmap at 1212 (bg #0 + 1212)
@@ -551,7 +551,7 @@ Group 80: (Blocks 2621440-2654207) [INOD
   32768 free blocks, 16 free inodes, 0 directories, 16 unused inodes
   Free blocks: 2621440-2654207
   Free inodes: 1281-1296
-Group 81: (Blocks 2654208-2686975) [INODE_UNINIT]
+Group 81: (Blocks 2654208-2686975) [INODE_UNINIT, BLOCK_UNINIT]
   Backup superblock at 2654208, Group descriptors at 2654209-2654209
   Reserved GDT blocks at 2654210-2654880
   Block bitmap at 754 (bg #0 + 754), Inode bitmap at 1266 (bg #0 + 1266)
--- e2fsprogs-1.42.9.orig/tests/m_uninit/expect.1
+++ e2fsprogs-1.42.9/tests/m_uninit/expect.1
@@ -64,7 +64,7 @@ Group 0: (Blocks 1-8192) [ITABLE_ZEROED]
   7662 free blocks, 2037 free inodes, 2 directories, 2037 unused inodes
   Free blocks: 531-8192
   Free inodes: 12-2048
-Group 1: (Blocks 8193-16384) [INODE_UNINIT, ITABLE_ZEROED]
+Group 1: (Blocks 8193-16384) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Backup superblock at 8193, Group descriptors at 8194-8194
   Reserved GDT blocks at 8195-8450
   Block bitmap at 8451 (+258), Inode bitmap at 8452 (+259)
@@ -76,9 +76,9 @@ Group 2: (Blocks 16385-24576) [INODE_UNI
   Block bitmap at 16385 (+0), Inode bitmap at 16386 (+1)
   Inode table at 16387-16642 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 16385-24576
+  Free blocks: 16643-24576
   Free inodes: 4097-6144
-Group 3: (Blocks 24577-32768) [INODE_UNINIT, ITABLE_ZEROED]
+Group 3: (Blocks 24577-32768) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Backup superblock at 24577, Group descriptors at 24578-24578
   Reserved GDT blocks at 24579-24834
   Block bitmap at 24835 (+258), Inode bitmap at 24836 (+259)
@@ -90,9 +90,9 @@ Group 4: (Blocks 32769-40960) [INODE_UNI
   Block bitmap at 32769 (+0), Inode bitmap at 32770 (+1)
   Inode table at 32771-33026 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 32769-40960
+  Free blocks: 33027-40960
   Free inodes: 8193-10240
-Group 5: (Blocks 40961-49152) [INODE_UNINIT, ITABLE_ZEROED]
+Group 5: (Blocks 40961-49152) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Backup superblock at 40961, Group descriptors at 40962-40962
   Reserved GDT blocks at 40963-41218
   Block bitmap at 41219 (+258), Inode bitmap at 41220 (+259)
@@ -104,9 +104,9 @@ Group 6: (Blocks 49153-57344) [INODE_UNI
   Block bitmap at 49153 (+0), Inode bitmap at 49154 (+1)
   Inode table at 49155-49410 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 49153-57344
+  Free blocks: 49411-57344
   Free inodes: 12289-14336
-Group 7: (Blocks 57345-65536) [INODE_UNINIT, ITABLE_ZEROED]
+Group 7: (Blocks 57345-65536) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Backup superblock at 57345, Group descriptors at 57346-57346
   Reserved GDT blocks at 57347-57602
   Block bitmap at 57603 (+258), Inode bitmap at 57604 (+259)
@@ -118,9 +118,9 @@ Group 8: (Blocks 65537-73728) [INODE_UNI
   Block bitmap at 65537 (+0), Inode bitmap at 65538 (+1)
   Inode table at 65539-65794 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 65537-73728
+  Free blocks: 65795-73728
   Free inodes: 16385-18432
-Group 9: (Blocks 73729-81920) [INODE_UNINIT, ITABLE_ZEROED]
+Group 9: (Blocks 73729-81920) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Backup superblock at 73729, Group descriptors at 73730-73730
   Reserved GDT blocks at 73731-73986
   Block bitmap at 73987 (+258), Inode bitmap at 73988 (+259)
@@ -132,31 +132,31 @@ Group 10: (Blocks 81921-90112) [INODE_UN
   Block bitmap at 81921 (+0), Inode bitmap at 81922 (+1)
   Inode table at 81923-82178 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 81921-90112
+  Free blocks: 82179-90112
   Free inodes: 20481-22528
 Group 11: (Blocks 90113-98304) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Block bitmap at 90113 (+0), Inode bitmap at 90114 (+1)
   Inode table at 90115-90370 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 90113-98304
+  Free blocks: 90371-98304
   Free inodes: 22529-24576
 Group 12: (Blocks 98305-106496) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Block bitmap at 98305 (+0), Inode bitmap at 98306 (+1)
   Inode table at 98307-98562 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 98305-106496
+  Free blocks: 98563-106496
   Free inodes: 24577-26624
 Group 13: (Blocks 106497-114688) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Block bitmap at 106497 (+0), Inode bitmap at 106498 (+1)
   Inode table at 106499-106754 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 106497-114688
+  Free blocks: 106755-114688
   Free inodes: 26625-28672
 Group 14: (Blocks 114689-122880) [INODE_UNINIT, BLOCK_UNINIT, ITABLE_ZEROED]
   Block bitmap at 114689 (+0), Inode bitmap at 114690 (+1)
   Inode table at 114691-114946 (+2)
   7934 free blocks, 2048 free inodes, 0 directories, 2048 unused inodes
-  Free blocks: 114689-122880
+  Free blocks: 114947-122880
   Free inodes: 28673-30720
 Group 15: (Blocks 122881-131071) [INODE_UNINIT, ITABLE_ZEROED]
   Block bitmap at 122881 (+0), Inode bitmap at 122882 (+1)
--- e2fsprogs-1.42.9.orig/tests/progs/Makefile.in
+++ e2fsprogs-1.42.9/tests/progs/Makefile.in
@@ -21,7 +21,7 @@ TEST_ICOUNT_OBJS=	test_icount.o test_ico
 
 SRCS=	$(srcdir)/test_rel.c 
 
-LIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR)
+LIBS= $(LIBEXT2FS) $(LIBSS) $(LIBCOM_ERR) $(SYSLIBS)
 DEPLIBS= $(LIBEXT2FS) $(DEPLIBSS) $(DEPLIBCOM_ERR)
 
 .c.o:
--- e2fsprogs-1.42.9.orig/util/Makefile.in
+++ e2fsprogs-1.42.9/util/Makefile.in
@@ -22,6 +22,12 @@ PROGS=		subst symlinks
 
 all:: $(PROGS) gen-tarball
 
+dirpaths.h:
+	$(E) "	CREATE dirpaths.h"
+	$(Q) echo "/* fake dirpaths.h for config.h */" > dirpaths.h
+
+subst.o: dirpaths.h
+
 subst: subst.o
 	$(E) "	LD $@"
 	$(Q) $(BUILD_CC) $(BUILD_LDFLAGS) -o subst subst.o
@@ -46,7 +52,7 @@ tarballs: gen-tarball
 
 clean:
 	$(RM) -f $(PROGS) \#* *.s *.o *.a *~ core *.tar.gz gen-tarball \
-		copy-sparse
+		copy-sparse dirpaths.h
 
 mostlyclean: clean
 
@@ -58,4 +64,4 @@ distclean: clean
 # Makefile dependencies follow.  This must be the last section in
 # the Makefile.in file
 #
-subst.o: $(srcdir)/subst.c
+subst.o: $(srcdir)/subst.c $(top_builddir)/lib/config.h dirpaths.h
--- e2fsprogs-1.42.9.orig/util/subst.c
+++ e2fsprogs-1.42.9/util/subst.c
@@ -5,6 +5,7 @@
  *
  */
 
+#include "config.h"
 #include <stdio.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -13,6 +14,7 @@
 #include <ctype.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <fcntl.h>
 #include <time.h>
 #include <utime.h>
 
@@ -264,21 +266,11 @@ static void parse_config_file(FILE *f)
 /*
  * Return 0 if the files are different, 1 if the files are the same.
  */
-static int compare_file(const char *outfn, const char *newfn)
+static int compare_file(FILE *old_f, FILE *new_f)
 {
-	FILE	*old_f, *new_f;
 	char	oldbuf[2048], newbuf[2048], *oldcp, *newcp;
 	int	retval;
 
-	old_f = fopen(outfn, "r");
-	if (!old_f)
-		return 0;
-	new_f = fopen(newfn, "r");
-	if (!new_f) {
-		fclose(old_f);
-		return 0;
-	}
-
 	while (1) {
 		oldcp = fgets(oldbuf, sizeof(oldbuf), old_f);
 		newcp = fgets(newbuf, sizeof(newbuf), new_f);
@@ -291,8 +283,6 @@ static int compare_file(const char *outf
 			break;
 		}
 	}
-	fclose(old_f);
-	fclose(new_f);
 	return retval;
 }
 
@@ -302,12 +292,14 @@ int main(int argc, char **argv)
 {
 	char	line[2048];
 	int	c;
-	FILE	*in, *out;
+	int	fd;
+	FILE	*in, *out, *old = NULL;
 	char	*outfn = NULL, *newfn = NULL;
 	int	verbose = 0;
 	int	adjust_timestamp = 0;
+	int	got_atime = 0;
 	struct stat stbuf;
-	struct utimbuf ut;
+	struct timeval tv[2];
 
 	while ((c = getopt (argc, argv, "f:tv")) != EOF) {
 		switch (c) {
@@ -351,11 +343,34 @@ int main(int argc, char **argv)
 		}
 		strcpy(newfn, outfn);
 		strcat(newfn, ".new");
-		out = fopen(newfn, "w");
-		if (!out) {
+		fd = open(newfn, O_CREAT|O_TRUNC|O_RDWR, 0444);
+		if (fd < 0) {
 			perror(newfn);
 			exit(1);
 		}
+		out = fdopen(fd, "w+");
+		if (!out) {
+			perror("fdopen");
+			exit(1);
+		}
+
+		fd = open(outfn, O_RDONLY);
+		if (fd > 0) {
+			/* save the original atime, if possible */
+			if (fstat(fd, &stbuf) == 0) {
+#if HAVE_STRUCT_STAT_ST_ATIM
+				tv[0].tv_sec = stbuf.st_atim.tv_sec;
+				tv[0].tv_usec = stbuf.st_atim.tv_nsec / 1000;
+#else
+				tv[0].tv_sec = stbuf.st_atime;
+				tv[0].tv_usec = 0;
+#endif
+				got_atime = 1;
+			}
+			old = fdopen(fd, "r");
+			if (!old)
+				close(fd);
+		}
 	} else {
 		out = stdout;
 		outfn = 0;
@@ -368,32 +383,49 @@ int main(int argc, char **argv)
 		fputs(line, out);
 	}
 	fclose(in);
-	fclose(out);
 	if (outfn) {
-		struct stat st;
-		if (compare_file(outfn, newfn)) {
+		fflush(out);
+		rewind(out);
+		if (old && compare_file(old, out)) {
 			if (verbose)
 				printf("No change, keeping %s.\n", outfn);
 			if (adjust_timestamp) {
-				if (stat(outfn, &stbuf) == 0) {
-					if (verbose)
-						printf("Updating modtime for %s\n", outfn);
-					ut.actime = stbuf.st_atime;
-					ut.modtime = time(0);
-					if (utime(outfn, &ut) < 0)
-						perror("utime");
+				if (verbose)
+					printf("Updating modtime for %s\n", outfn);
+				if (gettimeofday(&tv[1], NULL) < 0) {
+					perror("gettimeofday");
+					exit(1);
 				}
+				if (got_atime == 0)
+					tv[0] = tv[1];
+				else if (verbose)
+					printf("Using original atime\n");
+#ifdef HAVE_FUTIMES
+				if (futimes(fileno(old), tv) < 0)
+					perror("futimes");
+#else
+				if (utimes(outfn, tv) < 0)
+					perror("utimes");
+#endif
 			}
-			unlink(newfn);
+			fclose(out);
+			if (unlink(newfn) < 0)
+				perror("unlink");
 		} else {
 			if (verbose)
 				printf("Creating or replacing %s.\n", outfn);
-			rename(newfn, outfn);
+			fclose(out);
+			if (old)
+				fclose(old);
+			old = NULL;
+			if (rename(newfn, outfn) < 0) {
+				perror("rename");
+				exit(1);
+			}
 		}
-		/* set read-only to alert user it is a generated file */
-		if (stat(outfn, &st) == 0)
-			chmod(outfn, st.st_mode & ~0222);
 	}
+	if (old)
+		fclose(old);
 	return (0);
 }
 
--- e2fsprogs-1.42.9.orig/version.h
+++ e2fsprogs-1.42.9/version.h
@@ -8,4 +8,4 @@
  */
 
 #define E2FSPROGS_VERSION "1.42.9"
-#define E2FSPROGS_DATE "28-Dec-2013"
+#define E2FSPROGS_DATE "4-Feb-2014"
