--- /dev/null
+Description: tune2fs: after replaying the journal, fix up s_lastcheck
+ If the file system needs to have the journal replayed, but definition
+ it can't be freshly checked. So if the time when the file system was
+ last checked (s_lastcheck) is before the time it was last mounted
+ (s_mtime), force s_lastcheck to be before s_mtime.
+ .
+ This is necessary to make sure some of tune2fs's safety checks work
+ correctly after replaying the journal, since some of tune2fs's
+ operations really require that the file system be self-consistent or
+ grave damage can result.
+From: Theodore Ts'o <tytso@mit.edu>
+Origin: upstream, commit:60f032bbc167
+---
+ debugfs/journal.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/debugfs/journal.c b/debugfs/journal.c
+index 56a68be52..c16daa5b7 100644
+--- a/debugfs/journal.c
++++ b/debugfs/journal.c
+@@ -250,6 +250,12 @@ static void ext2fs_clear_recover(ext2_filsys fs, int error)
+ /* if we had an error doing journal recovery, we need a full fsck */
+ if (error)
+ fs->super->s_state &= ~EXT2_VALID_FS;
++ /*
++ * If we replayed the journal by definition the file system
++ * was mounted since the last time it was checked
++ */
++ if (fs->super->s_lastcheck >= fs->super->s_mtime)
++ fs->super->s_lastcheck = fs->super->s_mtime - 1;
+ ext2fs_mark_super_dirty(fs);
+ }
+
+--
+2.16.1.72.g5be1f00a9a
+
--- /dev/null
+Description: fsck: avoid buffer overflow if user passes in an insanely
+ long fs type
+From: Theodore Ts'o <tytso@mit.edu>
+Origin: upstream, commit:d8e5da0a3b94
+---
+ misc/fsck.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/misc/fsck.c b/misc/fsck.c
+index de5ae256d..a2e0dfba5 100644
+--- a/misc/fsck.c
++++ b/misc/fsck.c
+@@ -408,7 +408,8 @@ static char *find_fsck(char *type)
+ tpl = (strncmp(type, "fsck.", 5) ? "%s/fsck.%s" : "%s/%s");
+
+ for(s = strtok(p, ":"); s; s = strtok(NULL, ":")) {
+- sprintf(prog, tpl, s, type);
++ if (snprintf(prog, sizeof(prog), tpl, s, type) >= sizeof(prog))
++ continue;
+ if (stat(prog, &st) == 0) break;
+ }
+ free(p);
+@@ -435,7 +436,7 @@ static int progress_active(NOARGS)
+ static int execute(const char *type, const char *device, const char *mntpt,
+ int interactive)
+ {
+- char *s, *argv[80], prog[80];
++ char *s, *argv[80], prog[256];
+ int argc, i;
+ struct fsck_instance *inst, *p;
+ pid_t pid;
+@@ -445,7 +446,8 @@ static int execute(const char *type, const char *device, const char *mntpt,
+ return ENOMEM;
+ memset(inst, 0, sizeof(struct fsck_instance));
+
+- sprintf(prog, "fsck.%s", type);
++ if (snprintf(prog, sizeof(prog), "fsck.%s", type) >= sizeof(prog))
++ return EINVAL;
+ argv[0] = string_copy(prog);
+ argc = 1;
+
+--
+2.16.1.72.g5be1f00a9a
+
--- /dev/null
+Description: libss: add newer libreadline.so.7 to dlopen path
+From: Lukas Czerner <lczerner@redhat.com>
+Origin: upstream, commit:cb6d45fb1cd0
+---
+ lib/ss/get_readline.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/ss/get_readline.c b/lib/ss/get_readline.c
+index 9365be062..11c72b338 100644
+--- a/lib/ss/get_readline.c
++++ b/lib/ss/get_readline.c
+@@ -37,7 +37,7 @@ static void ss_release_readline(ss_data *info)
+ #endif
+
+ /* Libraries we will try to use for readline/editline functionality */
+-#define DEFAULT_LIBPATH "libreadline.so.6:libreadline.so.5:libreadline.so.4:libreadline.so:libedit.so.2:libedit.so:libeditline.so.0:libeditline.so"
++#define DEFAULT_LIBPATH "libreadline.so.7:libreadline.so.6:libreadline.so.5:libreadline.so.4:libreadline.so:libedit.so.2:libedit.so:libeditline.so.0:libeditline.so"
+
+ #ifdef HAVE_DLOPEN
+ void ss_get_readline(int sci_idx)
+--
+2.16.1.72.g5be1f00a9a
+
--- /dev/null
+Description: libuuid: fix UBSAN issue in get_random_fd()
+From: Theodore Ts'o <tytso@mit.edu>
+Origin: upstream, commit:6074cf36b9fa
+---
+ lib/uuid/gen_uuid.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/lib/uuid/gen_uuid.c b/lib/uuid/gen_uuid.c
+index 0028c7caf..af5509352 100644
+--- a/lib/uuid/gen_uuid.c
++++ b/lib/uuid/gen_uuid.c
+@@ -154,7 +154,7 @@ static int get_random_fd(void)
+ fcntl(fd, F_SETFD, i | FD_CLOEXEC);
+ }
+ #endif
+- srand((getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
++ srand(((unsigned)getpid() << 16) ^ getuid() ^ tv.tv_sec ^ tv.tv_usec);
+ #ifdef DO_JRAND_MIX
+ jrand_seed[0] = getpid() ^ (tv.tv_sec & 0xFFFF);
+ jrand_seed[1] = getppid() ^ (tv.tv_usec & 0xFFFF);
+--
+2.16.1.72.g5be1f00a9a
+
--- /dev/null
+Description: tune2fs: require fsck if turning off csum_seed and the
+ UUID has changed
+ .
+ In the case where the UUID has changed and the user wants to turn off
+ the csum_seed feature, it's important that file system be freshly
+ checked. That's also the only case when it's necessary to recalculate
+ all of the metadata file systems.
+From: Theodore Ts'o <tytso@mit.edu>
+Origin: upstream, commit:1dc5c3928d27
+---
+ misc/tune2fs.c | 20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+diff --git a/misc/tune2fs.c b/misc/tune2fs.c
+index 9c8b6e43d..b11b2e3f3 100644
+--- a/misc/tune2fs.c
++++ b/misc/tune2fs.c
+@@ -1366,16 +1366,18 @@ mmp_error:
+
+ uuid_seed = ext2fs_crc32c_le(~0, fs->super->s_uuid,
+ sizeof(fs->super->s_uuid));
+- if (fs->super->s_checksum_seed != uuid_seed &&
+- (mount_flags & EXT2_MF_MOUNTED)) {
+- fputs(_("UUID has changed since enabling "
+- "metadata_csum. Filesystem must be unmounted "
+- "\nto safely rewrite all metadata to "
+- "match the new UUID.\n"), stderr);
+- return 1;
++ if (fs->super->s_checksum_seed != uuid_seed) {
++ if (mount_flags & (EXT2_MF_BUSY|EXT2_MF_MOUNTED)) {
++ fputs(_("UUID has changed since enabling "
++ "metadata_csum. Filesystem must be unmounted "
++ "\nto safely rewrite all metadata to match the new UUID.\n"),
++ stderr);
++ return 1;
++ }
++ check_fsck_needed(fs, _("Recalculating checksums "
++ "could take some time."));
++ rewrite_checksums = 1;
+ }
+-
+- rewrite_checksums = 1;
+ }
+
+ if (sb->s_rev_level == EXT2_GOOD_OLD_REV &&
+--
+2.16.1.72.g5be1f00a9a
+
enable-metadata_csum-by-default
+libuuid-fix-UBSAN-issue-in-get_random_fd
+fsck-avoid-buffer-overflow
+libss-add-newer-libreadline.so.7-to-dlopen-path
+tune2fs-dont-recover-journal-if-device-is-busy
+tune2fs-move-the-journal-recovery
+fix-up-s_lastcheck
+require-fsck-when-turning-off-csum_seed-and-uuid-changed
--- /dev/null
+Description: tune2fs: don't recover journal if device is busy.
+ tune2fs currently replays the journal if it needs
+ recovery and the filesystem isn't mounted.
+ .
+ The test for "is the filesystem mounted" isn't completely robust.
+ Lustre makes use of ext4 filesystems in a way that they are mounted
+ without being visible in /proc/mounts or similar.
+ This usage can easily be detected by attempting to open the device
+ with O_EXCL. tune2fs already does this and the EXT2_MF_BUSY flag
+ is set if open(O_EXCL) fails.
+ Several uses other than lustre mounts could cause O_EXCL to fail,
+ but in any case it seems unwise to recover the journal when something
+ else is keeping the device busy.
+ .
+ So add an extra test to avoid journal recovery when the device
+ is busy. This fixes some problems with lustre usage.
+From: NeilBrown <neilb@suse.com>
+Origin: upstream, commit:ee8b61e9b0ac
+---
+ misc/tune2fs.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/misc/tune2fs.c b/misc/tune2fs.c
+index 7bbd61088..a3374ab9d 100644
+--- a/misc/tune2fs.c
++++ b/misc/tune2fs.c
+@@ -3226,7 +3226,7 @@ _("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
+ }
+ #else
+ /* Recover the journal if possible. */
+- if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
++ if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
+ ext2fs_has_feature_journal_needs_recovery(fs->super)) {
+ errcode_t err;
+
+--
+2.16.1.72.g5be1f00a9a
+
--- /dev/null
+Description: tune2fs: perform journal recovery before modifying the superblock
+From: Theodore Ts'o <tytso@mit.edu>
+Origin: upstream, commit:f5eb38e816c0
+---
+ misc/tune2fs.c | 61 +++++++++++++++++++++----------------------
+ tests/t_replay_and_set/expect | 2 +-
+ tests/t_replay_and_set/script | 4 +--
+ 3 files changed, 33 insertions(+), 34 deletions(-)
+
+diff --git a/misc/tune2fs.c b/misc/tune2fs.c
+index a3374ab9d..9c8b6e43d 100644
+--- a/misc/tune2fs.c
++++ b/misc/tune2fs.c
+@@ -2910,6 +2910,36 @@ retry_open:
+ rc = 1;
+ goto closefs;
+ }
++
++#ifdef NO_RECOVERY
++ /* Warn if file system needs recovery and it is opened for writing. */
++ if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
++ (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
++ (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
++ fprintf(stderr,
++_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
++ "\te2fsck -E journal_only %s\n\n"
++ "then rerun this command. Otherwise, any changes made may be overwritten\n"
++ "by journal recovery.\n"), device_name);
++ }
++#else
++ /* Recover the journal if possible. */
++ if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
++ ext2fs_has_feature_journal_needs_recovery(fs->super)) {
++ errcode_t err;
++
++ printf(_("Recovering journal.\n"));
++ err = ext2fs_run_ext3_journal(&fs);
++ if (err) {
++ com_err("tune2fs", err, "while recovering journal.\n");
++ printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
++ if (fs)
++ ext2fs_close_free(&fs);
++ exit(1);
++ }
++ }
++#endif
++
+ /* Normally we only need to write out the superblock */
+ fs->flags |= EXT2_FLAG_SUPER_ONLY;
+
+@@ -3213,37 +3243,6 @@ retry_open:
+ free(ext_mount_opts);
+ }
+
+-#ifdef NO_RECOVERY
+- /* Warn if file system needs recovery and it is opened for writing. */
+- if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & EXT2_MF_MOUNTED) &&
+- (sb->s_feature_compat & EXT3_FEATURE_COMPAT_HAS_JOURNAL) &&
+- (sb->s_feature_incompat & EXT3_FEATURE_INCOMPAT_RECOVER)) {
+- fprintf(stderr,
+-_("Warning: The journal is dirty. You may wish to replay the journal like:\n\n"
+- "\te2fsck -E journal_only %s\n\n"
+- "then rerun this command. Otherwise, any changes made may be overwritten\n"
+- "by journal recovery.\n"), device_name);
+- }
+-#else
+- /* Recover the journal if possible. */
+- if ((open_flag & EXT2_FLAG_RW) && !(mount_flags & (EXT2_MF_BUSY | EXT2_MF_MOUNTED)) &&
+- ext2fs_has_feature_journal_needs_recovery(fs->super)) {
+- errcode_t err;
+-
+- printf(_("Recovering journal.\n"));
+- err = ext2fs_run_ext3_journal(&fs);
+- if (err) {
+- com_err("tune2fs", err, "while recovering journal.\n");
+- printf(_("Please run e2fsck -fy %s.\n"), argv[1]);
+- if (fs)
+- ext2fs_close_free(&fs);
+- exit(1);
+- }
+- ext2fs_clear_feature_journal_needs_recovery(fs->super);
+- ext2fs_mark_super_dirty(fs);
+- }
+-#endif
+-
+ free(device_name);
+ remove_error_table(&et_ext2_error_table);
+
+diff --git a/tests/t_replay_and_set/expect b/tests/t_replay_and_set/expect
+index f4919372a..f63a73af5 100644
+--- a/tests/t_replay_and_set/expect
++++ b/tests/t_replay_and_set/expect
+@@ -16,7 +16,7 @@ Pass 5: Checking group summary information
+ test_filesys: 11/16384 files (0.0% non-contiguous), 5164/65536 blocks
+ Exit status is 0
+ debugfs write journal
+-disable metadata_csum on a dirty-journal fs
++set the label on a dirty-journal fs
+ Recovering journal.
+ fsck the whole mess
+ Pass 1: Checking inodes, blocks, and sizes
+diff --git a/tests/t_replay_and_set/script b/tests/t_replay_and_set/script
+index 0be10ea80..36411fcfe 100644
+--- a/tests/t_replay_and_set/script
++++ b/tests/t_replay_and_set/script
+@@ -29,8 +29,8 @@ $DEBUGFS_EXE -w -f $TMPFILE.cmd $TMPFILE 2>> $OUT.new > /dev/null
+ sed -f $cmd_dir/filter.sed < $OUT.new >> $OUT
+ rm -rf $OUT.new
+
+-echo "disable metadata_csum on a dirty-journal fs" >> $OUT
+-$TUNE2FS -O ^metadata_csum $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed >> $OUT 2>&1
++echo "set the label on a dirty-journal fs" >> $OUT
++$TUNE2FS -L testing $TMPFILE 2>&1 | sed -f $cmd_dir/filter.sed >> $OUT 2>&1
+
+ echo "fsck the whole mess" >> $OUT
+ $FSCK -fy -N test_filesys $TMPFILE > $OUT.new 2>&1
+--
+2.16.1.72.g5be1f00a9a
+