diff --git a/0001-agetty-keep-freed-issue-file-pointer-zeroized.patch b/0001-agetty-keep-freed-issue-file-pointer-zeroized.patch
deleted file mode 100644
index a5441b1..0000000
--- a/0001-agetty-keep-freed-issue-file-pointer-zeroized.patch
+++ /dev/null
@@ -1,55 +0,0 @@
-From 9418ba6d05feed6061f5343741b1bc56e7bde663 Mon Sep 17 00:00:00 2001
-From: Karel Zak <kzak@redhat.com>
-Date: Fri, 20 Dec 2019 15:05:33 +0100
-Subject: [PATCH] agetty: keep freed issue file pointer zeroized
-
-References: https://bugzilla.redhat.com/show_bug.cgi?id=1784536
-Signed-off-by: Karel Zak <kzak@redhat.com>
----
- term-utils/agetty.c | 15 +++++++++++----
- 1 file changed, 11 insertions(+), 4 deletions(-)
-
-diff --git a/term-utils/agetty.c b/term-utils/agetty.c
-index 3c20acc98..dfc4921f5 100644
---- a/term-utils/agetty.c
-+++ b/term-utils/agetty.c
-@@ -1820,8 +1820,12 @@ static int issuefile_read_stream(
- 	if (fstat(fileno(f), &st) || !S_ISREG(st.st_mode))
- 		return 1;
- 
--	if (!ie->output)
--	       ie->output = open_memstream(&ie->mem, &ie->mem_sz);
-+	if (!ie->output) {
-+		free(ie->mem);
-+		ie->mem_sz = 0;
-+		ie->mem = NULL;
-+		ie->output = open_memstream(&ie->mem, &ie->mem_sz);
-+	}
- 
- 	while ((c = getc(f)) != EOF) {
- 		if (c == '\\')
-@@ -1965,8 +1969,10 @@ done:
- 	if (netlink_groups != 0)
- 		open_netlink();
- #endif
--	if (ie->output)
-+	if (ie->output) {
- 		fclose(ie->output);
-+		ie->output = NULL;
-+	}
- }
- 
- /* This is --show-issue backend, executed by normal user on the current
-@@ -1985,7 +1991,8 @@ static void show_issue(struct options *op)
- 
- 	if (ie.mem_sz)
- 		write_all(STDOUT_FILENO, ie.mem, ie.mem_sz);
--
-+	if (ie.output)
-+		fclose(ie.output);
- 	free(ie.mem);
- }
- 
--- 
-2.21.0
-
diff --git a/0002-libmount-remove-read-mountinfo-workaround.patch b/0002-libmount-remove-read-mountinfo-workaround.patch
deleted file mode 100644
index 38f8e34..0000000
--- a/0002-libmount-remove-read-mountinfo-workaround.patch
+++ /dev/null
@@ -1,396 +0,0 @@
-From 57898c3a7ee8fc5933cddd4526bb3980bef85a02 Mon Sep 17 00:00:00 2001
-From: Karel Zak <kzak@redhat.com>
-Date: Tue, 1 Sep 2020 10:15:14 +0200
-Subject: [PATCH] libmount: remove read-mountinfo workaround
-
-This workaround has been introduced by
-http://github.com/karelzak/util-linux/commit/e4925f591c1bfb83719418b56b952830d15b77eb
-
-And originally requested by https://github.com/systemd/systemd/issues/10872
-
-It seems we do not need it anymore as the problem should be fixed in kernel since 5.8
-(kernel commit 9f6c61f96f2d97cbb5f7fa85607bc398f843ff0f).
-
-Note that the libmount solution is very expensive as it repeats read()
-many times (until we get consistent result) if kernel is busy with
-mount table modification. This behaviour makes events management in
-systemd (or other places) pretty difficult as read mountinfo takes
-time on busy systems.
-
-Addresses: https://github.com/systemd/systemd/pull/16537
-Signed-off-by: Karel Zak <kzak@redhat.com>
----
- configure.ac             |   1 -
- libmount/src/mountP.h    |   2 -
- libmount/src/tab_parse.c |  87 ++++----------------
- libmount/src/utils.c     | 166 ---------------------------------------
- 4 files changed, 15 insertions(+), 241 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 2d178f3af..1e31ca3e2 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -504,7 +504,6 @@ AC_CHECK_FUNCS([ \
- 	err \
- 	errx \
- 	explicit_bzero \
--	fmemopen \
- 	fsync \
- 	utimensat \
- 	getdomainname \
-diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
-index d8ba0abad..ee97c6b4a 100644
---- a/libmount/src/mountP.h
-+++ b/libmount/src/mountP.h
-@@ -98,7 +98,6 @@ extern int mnt_valid_tagname(const char *tagname);
- extern int append_string(char **a, const char *b);
- 
- extern const char *mnt_statfs_get_fstype(struct statfs *vfs);
--extern int is_procfs_fd(int fd);
- extern int is_file_empty(const char *name);
- 
- extern int mnt_is_readonly(const char *path)
-@@ -124,7 +123,6 @@ extern void mnt_free_filesystems(char **filesystems);
- extern char *mnt_get_kernel_cmdline_option(const char *name);
- extern int mnt_stat_mountpoint(const char *target, struct stat *st);
- extern int mnt_lstat_mountpoint(const char *target, struct stat *st);
--extern FILE *mnt_get_procfs_memstream(int fd, char **membuf);
- 
- /* tab.c */
- extern int is_mountinfo(struct libmnt_table *tb);
-diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
-index 329987bcb..ac12dce54 100644
---- a/libmount/src/tab_parse.c
-+++ b/libmount/src/tab_parse.c
-@@ -694,7 +694,15 @@ static int kernel_fs_postparse(struct libmnt_table *tb,
- 	return rc;
- }
- 
--static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
-+/**
-+ * mnt_table_parse_stream:
-+ * @tb: tab pointer
-+ * @f: file stream
-+ * @filename: filename used for debug and error messages
-+ *
-+ * Returns: 0 on success, negative number in case of error.
-+ */
-+int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
- {
- 	int rc = -1;
- 	int flags = 0;
-@@ -773,40 +781,6 @@ err:
- 	return rc;
- }
- 
--/**
-- * mnt_table_parse_stream:
-- * @tb: tab pointer
-- * @f: file stream
-- * @filename: filename used for debug and error messages
-- *
-- * Returns: 0 on success, negative number in case of error.
-- */
--int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
--{
--	int fd, rc;
--	FILE *memf = NULL;
--	char *membuf = NULL;
--
--	/*
--	 * For /proc/#/{mountinfo,mount} we read all file to memory and use it
--	 * as memory stream. For more details see mnt_read_procfs_file().
--	 */
--	if ((fd = fileno(f)) >= 0
--	    && (tb->fmt == MNT_FMT_GUESS ||
--		tb->fmt == MNT_FMT_MOUNTINFO ||
--		tb->fmt == MNT_FMT_MTAB)
--	    && is_procfs_fd(fd)
--	    && (memf = mnt_get_procfs_memstream(fd, &membuf))) {
--
--		rc = __table_parse_stream(tb, memf, filename);
--		fclose(memf);
--		free(membuf);
--	} else
--		rc = __table_parse_stream(tb, f, filename);
--
--	return rc;
--}
--
- /**
-  * mnt_table_parse_file:
-  * @tb: tab pointer
-@@ -822,49 +796,18 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
- int mnt_table_parse_file(struct libmnt_table *tb, const char *filename)
- {
- 	FILE *f;
--	int rc, fd = -1;
-+	int rc;
- 
- 	if (!filename || !tb)
- 		return -EINVAL;
- 
--	/*
--	 * Try to use read()+poll() to realiably read all
--	 * /proc/#/{mount,mountinfo} file to memory
--	 */
--	if (tb->fmt != MNT_FMT_SWAPS
--	    && strncmp(filename, "/proc/", 6) == 0) {
--
--		FILE *memf;
--		char *membuf = NULL;
--
--		fd = open(filename, O_RDONLY|O_CLOEXEC);
--		if (fd < 0) {
--			rc = -errno;
--			goto done;
--		}
--		memf = mnt_get_procfs_memstream(fd, &membuf);
--		if (memf) {
--			rc = __table_parse_stream(tb, memf, filename);
--
--			fclose(memf);
--			free(membuf);
--			close(fd);
--			goto done;
--		}
--		/* else fallback to fopen/fdopen() */
--	}
--
--	if (fd >= 0)
--		f = fdopen(fd, "r" UL_CLOEXECSTR);
--	else
--		f = fopen(filename, "r" UL_CLOEXECSTR);
--
-+	f = fopen(filename, "r" UL_CLOEXECSTR);
- 	if (f) {
--		rc = __table_parse_stream(tb, f, filename);
-+		rc = mnt_table_parse_stream(tb, f, filename);
- 		fclose(f);
- 	} else
- 		rc = -errno;
--done:
-+
- 	DBG(TAB, ul_debugobj(tb, "parsing done [filename=%s, rc=%d]", filename, rc));
- 	return rc;
- }
-@@ -921,7 +864,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
- 
- 		f = fopen_at(dd, d->d_name, O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
- 		if (f) {
--			__table_parse_stream(tb, f, d->d_name);
-+			mnt_table_parse_stream(tb, f, d->d_name);
- 			fclose(f);
- 		}
- 	}
-@@ -962,7 +905,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
- 		f = fopen_at(dirfd(dir), d->d_name,
- 				O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
- 		if (f) {
--			__table_parse_stream(tb, f, d->d_name);
-+			mnt_table_parse_stream(tb, f, d->d_name);
- 			fclose(f);
- 		}
- 	}
-diff --git a/libmount/src/utils.c b/libmount/src/utils.c
-index 92829ebb0..40b45f11d 100644
---- a/libmount/src/utils.c
-+++ b/libmount/src/utils.c
-@@ -19,7 +19,6 @@
- #include <fcntl.h>
- #include <pwd.h>
- #include <grp.h>
--#include <poll.h>
- #include <blkid.h>
- 
- #include "strutils.h"
-@@ -448,13 +447,6 @@ const char *mnt_statfs_get_fstype(struct statfs *vfs)
- 	return NULL;
- }
- 
--int is_procfs_fd(int fd)
--{
--	struct statfs sfs;
--
--	return fstatfs(fd, &sfs) == 0 && sfs.f_type == STATFS_PROC_MAGIC;
--}
--
- /**
-  * mnt_match_fstype:
-  * @type: filesystem type
-@@ -1174,164 +1166,7 @@ done:
- 	return 1;
- }
- 
--#if defined(HAVE_FMEMOPEN) || defined(TEST_PROGRAM)
--
--/*
-- * This function tries to minimize possible races when we read
-- * /proc/#/{mountinfo,mount} files.
-- *
-- * The idea is to minimize number of read()s and check by poll() that during
-- * the read the mount table has not been modified. If yes, than re-read it
-- * (with some limitations to avoid never ending loop).
-- *
-- * Returns: <0 error, 0 success, 1 too many attempts
-- */
--static int read_procfs_file(int fd, char **buf, size_t *bufsiz)
--{
--	size_t bufmax = 0;
--	int rc = 0, tries = 0, ninters = 0;
--	char *bufptr = NULL;
--
--	assert(buf);
--	assert(bufsiz);
--
--	*bufsiz = 0;
--	*buf = NULL;
--
--	do {
--		ssize_t ret;
--
--		if (!bufptr || bufmax == *bufsiz) {
--			char *tmp;
--
--			bufmax = bufmax ? bufmax * 2 : (16 * 1024);
--			tmp = realloc(*buf, bufmax);
--			if (!tmp)
--				break;
--			*buf = tmp;
--			bufptr = tmp + *bufsiz;
--		}
--
--		errno = 0;
--		ret = read(fd, bufptr, bufmax - *bufsiz);
--
--		if (ret < 0) {
--			/* error */
--			if ((errno == EAGAIN || errno == EINTR) && (ninters++ < 5)) {
--				xusleep(200000);
--				continue;
--			}
--			break;
--
--		} if (ret > 0) {
--			/* success -- verify no event during read */
--			struct pollfd fds[] = {
--				{ .fd = fd, .events = POLLPRI }
--			};
--
--			rc = poll(fds, 1, 0);
--			if (rc < 0)
--				break;		/* poll() error */
--			if (rc > 0) {
--				/* event -- read all again */
--				if (lseek(fd, 0, SEEK_SET) != 0)
--					break;
--				*bufsiz = 0;
--				bufptr = *buf;
--				tries++;
--
--				if (tries > 10)
--					/* busy system? -- wait */
--					xusleep(10000);
--				continue;
--			}
--
--			/* successful read() without active poll() */
--			(*bufsiz) += (size_t) ret;
--			bufptr += ret;
--			tries = ninters = 0;
--		} else {
--			/* end-of-file */
--			goto success;
--		}
--	} while (tries <= 100);
--
--	rc = errno ? -errno : 1;
--	free(*buf);
--	return rc;
--
--success:
--	return 0;
--}
--
--/*
-- * Create FILE stream for data from read_procfs_file()
-- */
--FILE *mnt_get_procfs_memstream(int fd, char **membuf)
--{
--	size_t sz = 0;
--	off_t cur;
--
--	*membuf = NULL;
--
--	/* in case of error, rewind to the original position */
--	cur = lseek(fd, 0, SEEK_CUR);
--
--	if (read_procfs_file(fd, membuf, &sz) == 0 && sz > 0) {
--		FILE *memf = fmemopen(*membuf, sz, "r");
--		if (memf)
--			return memf;	/* success */
--
--		free(*membuf);
--		*membuf = NULL;
--	}
--
--	/* error */
--	if (cur != (off_t) -1)
--		lseek(fd, cur, SEEK_SET);
--	return NULL;
--}
--#else
--FILE *mnt_get_procfs_memstream(int fd __attribute((__unused__)),
--		               char **membuf __attribute((__unused__)))
--{
--	return NULL;
--}
--#endif /* HAVE_FMEMOPEN */
--
--
- #ifdef TEST_PROGRAM
--static int test_proc_read(struct libmnt_test *ts, int argc, char *argv[])
--{
--	char *buf = NULL;
--	char *filename = argv[1];
--	size_t bufsiz = 0;
--	int rc = 0, fd = open(filename, O_RDONLY);
--
--	if (fd <= 0) {
--		warn("%s: cannot open", filename);
--		return -errno;
--	}
--
--	rc = read_procfs_file(fd, &buf, &bufsiz);
--	close(fd);
--
--	switch (rc) {
--	case 0:
--		fwrite(buf, 1, bufsiz, stdout);
--		free(buf);
--		break;
--	case 1:
--		warnx("too many attempts");
--		break;
--	default:
--		warn("%s: cannot read", filename);
--		break;
--	}
--
--	return rc;
--}
--
- static int test_match_fstype(struct libmnt_test *ts, int argc, char *argv[])
- {
- 	char *type = argv[1];
-@@ -1513,7 +1348,6 @@ int main(int argc, char *argv[])
- 	{ "--guess-root",    test_guess_root,      "[<maj:min>]" },
- 	{ "--mkdir",         test_mkdir,           "<path>" },
- 	{ "--statfs-type",   test_statfs_type,     "<path>" },
--	{ "--read-procfs",   test_proc_read,       "<path>" },
- 
- 	{ NULL }
- 	};
--- 
-2.25.4
-
diff --git a/2.36-login-lastlog-create.patch b/2.36-login-lastlog-create.patch
deleted file mode 100644
index e2523d3..0000000
--- a/2.36-login-lastlog-create.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-diff -up util-linux-2.36/login-utils/login.c.kzak util-linux-2.36/login-utils/login.c
---- util-linux-2.36/login-utils/login.c.kzak	2020-07-23 14:13:26.777030764 +0200
-+++ util-linux-2.36/login-utils/login.c	2020-07-23 14:11:22.793686983 +0200
-@@ -585,7 +585,7 @@ static void log_lastlog(struct login_con
- 	sa.sa_handler = SIG_IGN;
- 	sigaction(SIGXFSZ, &sa, &oldsa_xfsz);
- 
--	fd = open(_PATH_LASTLOG, O_RDWR, 0);
-+	fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0);
- 	if (fd < 0)
- 		goto done;
- 	offset = cxt->pwd->pw_uid * sizeof(ll);
diff --git a/column-fix-leading-space-characters-bug.patch b/column-fix-leading-space-characters-bug.patch
deleted file mode 100644
index e612d34..0000000
--- a/column-fix-leading-space-characters-bug.patch
+++ /dev/null
@@ -1,148 +0,0 @@
-From 651c5d428c2ef103ee8c5b1a310d6f29f0304744 Mon Sep 17 00:00:00 2001
-From: Karel Zak <kzak@redhat.com>
-Date: Tue, 27 Mar 2018 10:40:13 +0200
-Subject: [PATCH] column: fix leading space characters bug
-
-The bug has been introduced during column(1) rewrite. The function
-read_input() need to skip leading space only temporary to detect empty
-lines, but the rest of the code has to use the original buffer (line).
-I've tried to fix one of the symptoms by 5c7b67fbbf41c973ca8d49b1e8bdba22dbb917aa
-(alter), but this solution is unnecessary and too complex.
-
-Changes:
-
-* don't ignore leading space
-* remove unnecessary stuff introduced by 5c7b67fbbf41c973ca8d49b1e8bdba22dbb917aa
-* fix regression test with incorrect separator
-
-Addresses: https://github.com/karelzak/util-linux/issues/575
-Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=1560283
-Signed-off-by: Karel Zak <kzak@redhat.com>
----
- tests/expected/column/table-input-separator-space |  2 +-
- tests/ts/column/table                             |  2 +-
- text-utils/column.c                               | 36 ++---------------------
- 4 files changed, 5 insertions(+), 38 deletions(-)
-
-diff --git a/tests/expected/column/table-input-separator-space b/tests/expected/column/table-input-separator-space
-index 8a6513c11..25d9b5ab0 100644
---- a/tests/expected/column/table-input-separator-space
-+++ b/tests/expected/column/table-input-separator-space
-@@ -1,5 +1,5 @@
- AAA	BBBB	C	DDDD
--BBB	CCCC	DDD
-+	BBB	CCCC	DDD
- AA	BB		DD
- AAAA	B	CC	D
- AA		CC	DD
-diff --git a/tests/ts/column/table b/tests/ts/column/table
-index 27b52e7c8..5c89d5eaf 100755
---- a/tests/ts/column/table
-+++ b/tests/ts/column/table
-@@ -37,7 +37,7 @@ $TS_CMD_COLUMN --separator ',' --table $TS_SELF/files/table-sep >> $TS_OUTPUT 2>
- ts_finalize_subtest
- 
- ts_init_subtest "input-separator-space"
--$TS_CMD_COLUMN --separator ',' --table $TS_SELF/files/table-sep-space >> $TS_OUTPUT 2>&1
-+$TS_CMD_COLUMN --separator "$(echo -e '\t')" --table $TS_SELF/files/table-sep-space >> $TS_OUTPUT 2>&1
- ts_finalize_subtest
- 
- ts_init_subtest "long"
-diff --git a/text-utils/column.c b/text-utils/column.c
-index 89d46d280..195814328 100644
---- a/text-utils/column.c
-+++ b/text-utils/column.c
-@@ -86,7 +86,6 @@ struct column_control {
- 	const char *tree_parent;
- 
- 	wchar_t *input_separator;
--	char *input_separator_raw;
- 	const char *output_separator;
- 
- 	wchar_t	**ents;		/* input entries */
-@@ -96,7 +95,6 @@ struct column_control {
- 	unsigned int greedy :1,
- 		     json :1,
- 		     header_repeat :1,
--		     input_sep_space : 1,	/* input separator contains space chars */
- 		     tab_noheadings :1;
- };
- 
-@@ -470,19 +468,7 @@ static int read_input(struct column_control *ctl, FILE *fp)
- 	char *buf = NULL;
- 	size_t bufsz = 0;
- 	size_t maxents = 0;
--	int rc = 0, is_space_sep = 0;
--
--	/* Check if columns separator contains spaces chars */
--	if (ctl->mode == COLUMN_MODE_TABLE && ctl->input_separator_raw) {
--		char *p;
--
--		for (p = ctl->input_separator_raw; *p; p++) {
--			if (isspace(*p)) {
--				is_space_sep = 1;
--				break;
--			}
--		}
--	}
-+	int rc = 0;
- 
- 	/* Read input */
- 	do {
-@@ -496,19 +482,6 @@ static int read_input(struct column_control *ctl, FILE *fp)
- 			err(EXIT_FAILURE, _("read failed"));
- 		}
- 		str = (char *) skip_space(buf);
--
--		/* The table columns separator could be a space. In this case
--		 * don't skip the separator if at begin of the line. For example:
--		 *
--		 * echo -e "\tcol1\tcol2\nrow\t1\t2" \
--		 *	| column -t -s "$(echo -e '\t')" --table-columns A,B,C
--		 */
--		if (is_space_sep && str > buf) {
--			char *x = strpbrk(buf, ctl->input_separator_raw);
--			if (x && x < str)
--				str = x;
--		}
--
- 		if (str) {
- 			p = strchr(str, '\n');
- 			if (p)
-@@ -517,13 +490,13 @@ static int read_input(struct column_control *ctl, FILE *fp)
- 		if (!str || !*str)
- 			continue;
- 
--		wcs = mbs_to_wcs(str);
-+		wcs = mbs_to_wcs(buf);
- 		if (!wcs) {
- 			/*
- 			 * Convert broken sequences to \x<hex> and continue.
- 			 */
- 			size_t tmpsz = 0;
--			char *tmp = mbs_invalid_encode(str, &tmpsz);
-+			char *tmp = mbs_invalid_encode(buf, &tmpsz);
- 
- 			if (!tmp)
- 				err(EXIT_FAILURE, _("read failed"));
-@@ -720,7 +693,6 @@ int main(int argc, char **argv)
- 
- 	ctl.output_separator = "  ";
- 	ctl.input_separator = mbs_to_wcs("\t ");
--	ctl.input_separator_raw = xstrdup("\t ");
- 
- 	while ((c = getopt_long(argc, argv, "c:dE:eH:hi:JN:n:O:o:p:R:r:s:T:tVW:x", longopts, NULL)) != -1) {
- 
-@@ -775,9 +747,7 @@ int main(int argc, char **argv)
- 			break;
- 		case 's':
- 			free(ctl.input_separator);
--			free(ctl.input_separator_raw);
- 			ctl.input_separator = mbs_to_wcs(optarg);
--			ctl.input_separator_raw = xstrdup(optarg);
- 			ctl.greedy = 0;
- 			break;
- 		case 'T':
--- 
-2.14.3
-
diff --git a/libmount-don-t-use-symfollow-for-helpers-on-user-mou.patch b/libmount-don-t-use-symfollow-for-helpers-on-user-mou.patch
new file mode 100644
index 0000000..edc7477
--- /dev/null
+++ b/libmount-don-t-use-symfollow-for-helpers-on-user-mou.patch
@@ -0,0 +1,40 @@
+From 76bb9b30cfcf54b59591a57a3d2a747e514469b2 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Thu, 19 Nov 2020 09:49:16 +0100
+Subject: [PATCH] libmount: don't use "symfollow" for helpers on user mounts
+
+Addresses: https://github.com/karelzak/util-linux/issues/1193
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ libmount/src/context_mount.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libmount/src/context_mount.c b/libmount/src/context_mount.c
+index 8c394c1ff..dd1786176 100644
+--- a/libmount/src/context_mount.c
++++ b/libmount/src/context_mount.c
+@@ -415,6 +415,9 @@ static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr)
+ 		 * string, because there is nothing like MS_EXEC (we only have
+ 		 * MS_NOEXEC in mount flags and we don't care about the original
+ 		 * mount string in libmount for VFS options).
++		 *
++		 * This use-case makes sense for MS_SECURE flags only (see
++		 * mnt_optstr_get_flags() and mnt_context_merge_mflags()).
+ 		 */
+ 		if (!(cxt->mountflags & MS_NOEXEC))
+ 			mnt_optstr_append_option(optstr, "exec", NULL);
+@@ -422,11 +425,8 @@ static int generate_helper_optstr(struct libmnt_context *cxt, char **optstr)
+ 			mnt_optstr_append_option(optstr, "suid", NULL);
+ 		if (!(cxt->mountflags & MS_NODEV))
+ 			mnt_optstr_append_option(optstr, "dev", NULL);
+-		if (!(cxt->mountflags & MS_NOSYMFOLLOW))
+-			mnt_optstr_append_option(optstr, "symfollow", NULL);
+ 	}
+ 
+-
+ 	if (cxt->flags & MNT_FL_SAVED_USER)
+ 		rc = mnt_optstr_set_option(optstr, "user", cxt->orig_user);
+ 	if (rc)
+-- 
+2.25.4
+
diff --git a/libmount-remove-read-mountinfo-workaround.patch b/libmount-remove-read-mountinfo-workaround.patch
new file mode 100644
index 0000000..38f8e34
--- /dev/null
+++ b/libmount-remove-read-mountinfo-workaround.patch
@@ -0,0 +1,396 @@
+From 57898c3a7ee8fc5933cddd4526bb3980bef85a02 Mon Sep 17 00:00:00 2001
+From: Karel Zak <kzak@redhat.com>
+Date: Tue, 1 Sep 2020 10:15:14 +0200
+Subject: [PATCH] libmount: remove read-mountinfo workaround
+
+This workaround has been introduced by
+http://github.com/karelzak/util-linux/commit/e4925f591c1bfb83719418b56b952830d15b77eb
+
+And originally requested by https://github.com/systemd/systemd/issues/10872
+
+It seems we do not need it anymore as the problem should be fixed in kernel since 5.8
+(kernel commit 9f6c61f96f2d97cbb5f7fa85607bc398f843ff0f).
+
+Note that the libmount solution is very expensive as it repeats read()
+many times (until we get consistent result) if kernel is busy with
+mount table modification. This behaviour makes events management in
+systemd (or other places) pretty difficult as read mountinfo takes
+time on busy systems.
+
+Addresses: https://github.com/systemd/systemd/pull/16537
+Signed-off-by: Karel Zak <kzak@redhat.com>
+---
+ configure.ac             |   1 -
+ libmount/src/mountP.h    |   2 -
+ libmount/src/tab_parse.c |  87 ++++----------------
+ libmount/src/utils.c     | 166 ---------------------------------------
+ 4 files changed, 15 insertions(+), 241 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 2d178f3af..1e31ca3e2 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -504,7 +504,6 @@ AC_CHECK_FUNCS([ \
+ 	err \
+ 	errx \
+ 	explicit_bzero \
+-	fmemopen \
+ 	fsync \
+ 	utimensat \
+ 	getdomainname \
+diff --git a/libmount/src/mountP.h b/libmount/src/mountP.h
+index d8ba0abad..ee97c6b4a 100644
+--- a/libmount/src/mountP.h
++++ b/libmount/src/mountP.h
+@@ -98,7 +98,6 @@ extern int mnt_valid_tagname(const char *tagname);
+ extern int append_string(char **a, const char *b);
+ 
+ extern const char *mnt_statfs_get_fstype(struct statfs *vfs);
+-extern int is_procfs_fd(int fd);
+ extern int is_file_empty(const char *name);
+ 
+ extern int mnt_is_readonly(const char *path)
+@@ -124,7 +123,6 @@ extern void mnt_free_filesystems(char **filesystems);
+ extern char *mnt_get_kernel_cmdline_option(const char *name);
+ extern int mnt_stat_mountpoint(const char *target, struct stat *st);
+ extern int mnt_lstat_mountpoint(const char *target, struct stat *st);
+-extern FILE *mnt_get_procfs_memstream(int fd, char **membuf);
+ 
+ /* tab.c */
+ extern int is_mountinfo(struct libmnt_table *tb);
+diff --git a/libmount/src/tab_parse.c b/libmount/src/tab_parse.c
+index 329987bcb..ac12dce54 100644
+--- a/libmount/src/tab_parse.c
++++ b/libmount/src/tab_parse.c
+@@ -694,7 +694,15 @@ static int kernel_fs_postparse(struct libmnt_table *tb,
+ 	return rc;
+ }
+ 
+-static int __table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
++/**
++ * mnt_table_parse_stream:
++ * @tb: tab pointer
++ * @f: file stream
++ * @filename: filename used for debug and error messages
++ *
++ * Returns: 0 on success, negative number in case of error.
++ */
++int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
+ {
+ 	int rc = -1;
+ 	int flags = 0;
+@@ -773,40 +781,6 @@ err:
+ 	return rc;
+ }
+ 
+-/**
+- * mnt_table_parse_stream:
+- * @tb: tab pointer
+- * @f: file stream
+- * @filename: filename used for debug and error messages
+- *
+- * Returns: 0 on success, negative number in case of error.
+- */
+-int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filename)
+-{
+-	int fd, rc;
+-	FILE *memf = NULL;
+-	char *membuf = NULL;
+-
+-	/*
+-	 * For /proc/#/{mountinfo,mount} we read all file to memory and use it
+-	 * as memory stream. For more details see mnt_read_procfs_file().
+-	 */
+-	if ((fd = fileno(f)) >= 0
+-	    && (tb->fmt == MNT_FMT_GUESS ||
+-		tb->fmt == MNT_FMT_MOUNTINFO ||
+-		tb->fmt == MNT_FMT_MTAB)
+-	    && is_procfs_fd(fd)
+-	    && (memf = mnt_get_procfs_memstream(fd, &membuf))) {
+-
+-		rc = __table_parse_stream(tb, memf, filename);
+-		fclose(memf);
+-		free(membuf);
+-	} else
+-		rc = __table_parse_stream(tb, f, filename);
+-
+-	return rc;
+-}
+-
+ /**
+  * mnt_table_parse_file:
+  * @tb: tab pointer
+@@ -822,49 +796,18 @@ int mnt_table_parse_stream(struct libmnt_table *tb, FILE *f, const char *filenam
+ int mnt_table_parse_file(struct libmnt_table *tb, const char *filename)
+ {
+ 	FILE *f;
+-	int rc, fd = -1;
++	int rc;
+ 
+ 	if (!filename || !tb)
+ 		return -EINVAL;
+ 
+-	/*
+-	 * Try to use read()+poll() to realiably read all
+-	 * /proc/#/{mount,mountinfo} file to memory
+-	 */
+-	if (tb->fmt != MNT_FMT_SWAPS
+-	    && strncmp(filename, "/proc/", 6) == 0) {
+-
+-		FILE *memf;
+-		char *membuf = NULL;
+-
+-		fd = open(filename, O_RDONLY|O_CLOEXEC);
+-		if (fd < 0) {
+-			rc = -errno;
+-			goto done;
+-		}
+-		memf = mnt_get_procfs_memstream(fd, &membuf);
+-		if (memf) {
+-			rc = __table_parse_stream(tb, memf, filename);
+-
+-			fclose(memf);
+-			free(membuf);
+-			close(fd);
+-			goto done;
+-		}
+-		/* else fallback to fopen/fdopen() */
+-	}
+-
+-	if (fd >= 0)
+-		f = fdopen(fd, "r" UL_CLOEXECSTR);
+-	else
+-		f = fopen(filename, "r" UL_CLOEXECSTR);
+-
++	f = fopen(filename, "r" UL_CLOEXECSTR);
+ 	if (f) {
+-		rc = __table_parse_stream(tb, f, filename);
++		rc = mnt_table_parse_stream(tb, f, filename);
+ 		fclose(f);
+ 	} else
+ 		rc = -errno;
+-done:
++
+ 	DBG(TAB, ul_debugobj(tb, "parsing done [filename=%s, rc=%d]", filename, rc));
+ 	return rc;
+ }
+@@ -921,7 +864,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
+ 
+ 		f = fopen_at(dd, d->d_name, O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
+ 		if (f) {
+-			__table_parse_stream(tb, f, d->d_name);
++			mnt_table_parse_stream(tb, f, d->d_name);
+ 			fclose(f);
+ 		}
+ 	}
+@@ -962,7 +905,7 @@ static int __mnt_table_parse_dir(struct libmnt_table *tb, const char *dirname)
+ 		f = fopen_at(dirfd(dir), d->d_name,
+ 				O_RDONLY|O_CLOEXEC, "r" UL_CLOEXECSTR);
+ 		if (f) {
+-			__table_parse_stream(tb, f, d->d_name);
++			mnt_table_parse_stream(tb, f, d->d_name);
+ 			fclose(f);
+ 		}
+ 	}
+diff --git a/libmount/src/utils.c b/libmount/src/utils.c
+index 92829ebb0..40b45f11d 100644
+--- a/libmount/src/utils.c
++++ b/libmount/src/utils.c
+@@ -19,7 +19,6 @@
+ #include <fcntl.h>
+ #include <pwd.h>
+ #include <grp.h>
+-#include <poll.h>
+ #include <blkid.h>
+ 
+ #include "strutils.h"
+@@ -448,13 +447,6 @@ const char *mnt_statfs_get_fstype(struct statfs *vfs)
+ 	return NULL;
+ }
+ 
+-int is_procfs_fd(int fd)
+-{
+-	struct statfs sfs;
+-
+-	return fstatfs(fd, &sfs) == 0 && sfs.f_type == STATFS_PROC_MAGIC;
+-}
+-
+ /**
+  * mnt_match_fstype:
+  * @type: filesystem type
+@@ -1174,164 +1166,7 @@ done:
+ 	return 1;
+ }
+ 
+-#if defined(HAVE_FMEMOPEN) || defined(TEST_PROGRAM)
+-
+-/*
+- * This function tries to minimize possible races when we read
+- * /proc/#/{mountinfo,mount} files.
+- *
+- * The idea is to minimize number of read()s and check by poll() that during
+- * the read the mount table has not been modified. If yes, than re-read it
+- * (with some limitations to avoid never ending loop).
+- *
+- * Returns: <0 error, 0 success, 1 too many attempts
+- */
+-static int read_procfs_file(int fd, char **buf, size_t *bufsiz)
+-{
+-	size_t bufmax = 0;
+-	int rc = 0, tries = 0, ninters = 0;
+-	char *bufptr = NULL;
+-
+-	assert(buf);
+-	assert(bufsiz);
+-
+-	*bufsiz = 0;
+-	*buf = NULL;
+-
+-	do {
+-		ssize_t ret;
+-
+-		if (!bufptr || bufmax == *bufsiz) {
+-			char *tmp;
+-
+-			bufmax = bufmax ? bufmax * 2 : (16 * 1024);
+-			tmp = realloc(*buf, bufmax);
+-			if (!tmp)
+-				break;
+-			*buf = tmp;
+-			bufptr = tmp + *bufsiz;
+-		}
+-
+-		errno = 0;
+-		ret = read(fd, bufptr, bufmax - *bufsiz);
+-
+-		if (ret < 0) {
+-			/* error */
+-			if ((errno == EAGAIN || errno == EINTR) && (ninters++ < 5)) {
+-				xusleep(200000);
+-				continue;
+-			}
+-			break;
+-
+-		} if (ret > 0) {
+-			/* success -- verify no event during read */
+-			struct pollfd fds[] = {
+-				{ .fd = fd, .events = POLLPRI }
+-			};
+-
+-			rc = poll(fds, 1, 0);
+-			if (rc < 0)
+-				break;		/* poll() error */
+-			if (rc > 0) {
+-				/* event -- read all again */
+-				if (lseek(fd, 0, SEEK_SET) != 0)
+-					break;
+-				*bufsiz = 0;
+-				bufptr = *buf;
+-				tries++;
+-
+-				if (tries > 10)
+-					/* busy system? -- wait */
+-					xusleep(10000);
+-				continue;
+-			}
+-
+-			/* successful read() without active poll() */
+-			(*bufsiz) += (size_t) ret;
+-			bufptr += ret;
+-			tries = ninters = 0;
+-		} else {
+-			/* end-of-file */
+-			goto success;
+-		}
+-	} while (tries <= 100);
+-
+-	rc = errno ? -errno : 1;
+-	free(*buf);
+-	return rc;
+-
+-success:
+-	return 0;
+-}
+-
+-/*
+- * Create FILE stream for data from read_procfs_file()
+- */
+-FILE *mnt_get_procfs_memstream(int fd, char **membuf)
+-{
+-	size_t sz = 0;
+-	off_t cur;
+-
+-	*membuf = NULL;
+-
+-	/* in case of error, rewind to the original position */
+-	cur = lseek(fd, 0, SEEK_CUR);
+-
+-	if (read_procfs_file(fd, membuf, &sz) == 0 && sz > 0) {
+-		FILE *memf = fmemopen(*membuf, sz, "r");
+-		if (memf)
+-			return memf;	/* success */
+-
+-		free(*membuf);
+-		*membuf = NULL;
+-	}
+-
+-	/* error */
+-	if (cur != (off_t) -1)
+-		lseek(fd, cur, SEEK_SET);
+-	return NULL;
+-}
+-#else
+-FILE *mnt_get_procfs_memstream(int fd __attribute((__unused__)),
+-		               char **membuf __attribute((__unused__)))
+-{
+-	return NULL;
+-}
+-#endif /* HAVE_FMEMOPEN */
+-
+-
+ #ifdef TEST_PROGRAM
+-static int test_proc_read(struct libmnt_test *ts, int argc, char *argv[])
+-{
+-	char *buf = NULL;
+-	char *filename = argv[1];
+-	size_t bufsiz = 0;
+-	int rc = 0, fd = open(filename, O_RDONLY);
+-
+-	if (fd <= 0) {
+-		warn("%s: cannot open", filename);
+-		return -errno;
+-	}
+-
+-	rc = read_procfs_file(fd, &buf, &bufsiz);
+-	close(fd);
+-
+-	switch (rc) {
+-	case 0:
+-		fwrite(buf, 1, bufsiz, stdout);
+-		free(buf);
+-		break;
+-	case 1:
+-		warnx("too many attempts");
+-		break;
+-	default:
+-		warn("%s: cannot read", filename);
+-		break;
+-	}
+-
+-	return rc;
+-}
+-
+ static int test_match_fstype(struct libmnt_test *ts, int argc, char *argv[])
+ {
+ 	char *type = argv[1];
+@@ -1513,7 +1348,6 @@ int main(int argc, char *argv[])
+ 	{ "--guess-root",    test_guess_root,      "[<maj:min>]" },
+ 	{ "--mkdir",         test_mkdir,           "<path>" },
+ 	{ "--statfs-type",   test_statfs_type,     "<path>" },
+-	{ "--read-procfs",   test_proc_read,       "<path>" },
+ 
+ 	{ NULL }
+ 	};
+-- 
+2.25.4
+
diff --git a/login-lastlog-create.patch b/login-lastlog-create.patch
new file mode 100644
index 0000000..e2523d3
--- /dev/null
+++ b/login-lastlog-create.patch
@@ -0,0 +1,12 @@
+diff -up util-linux-2.36/login-utils/login.c.kzak util-linux-2.36/login-utils/login.c
+--- util-linux-2.36/login-utils/login.c.kzak	2020-07-23 14:13:26.777030764 +0200
++++ util-linux-2.36/login-utils/login.c	2020-07-23 14:11:22.793686983 +0200
+@@ -585,7 +585,7 @@ static void log_lastlog(struct login_con
+ 	sa.sa_handler = SIG_IGN;
+ 	sigaction(SIGXFSZ, &sa, &oldsa_xfsz);
+ 
+-	fd = open(_PATH_LASTLOG, O_RDWR, 0);
++	fd = open(_PATH_LASTLOG, O_RDWR | O_CREAT, 0);
+ 	if (fd < 0)
+ 		goto done;
+ 	offset = cxt->pwd->pw_uid * sizeof(ll);
diff --git a/util-linux.spec b/util-linux.spec
index 85cf53a..4541839 100644
--- a/util-linux.spec
+++ b/util-linux.spec
@@ -2,7 +2,7 @@
 Summary: A collection of basic system utilities
 Name: util-linux
 Version: 2.36.1
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: GPLv2 and GPLv2+ and LGPLv2+ and BSD with advertising and Public Domain
 URL: http://en.wikipedia.org/wiki/Util-linux
 
@@ -103,10 +103,12 @@ Requires: libfdisk = %{version}-%{release}
 ### Ready for upstream?
 ###
 # 151635 - makeing /var/log/lastlog
-Patch0: 2.36-login-lastlog-create.patch
+Patch0: login-lastlog-create.patch
 # https://github.com/karelzak/util-linux/commit/57898c3a7ee8fc5933cddd4526bb3980bef85a02
 # The workaround is unnecessary on Fedora with kernel >= 5.8.
-Patch1: 0002-libmount-remove-read-mountinfo-workaround.patch
+Patch1: libmount-remove-read-mountinfo-workaround.patch
+# usptream patch, https://github.com/karelzak/util-linux/issues/1193
+Patch2: libmount-don-t-use-symfollow-for-helpers-on-user-mou.patch
 
 %description
 The util-linux package contains a large variety of low-level system
@@ -939,6 +941,11 @@ fi
 %{_libdir}/python*/site-packages/libmount/
 
 %changelog
+* Thu Nov 19 2020 Karel Zak <kzak@redhat.com> - 2.36.1-2
+- remove unused patches
+- remove versions and seq.numbers from patch names
+- fix mount "symfollow" issue (upstream patch)
+
 * Mon Nov 16 2020 Karel Zak <kzak@redhat.com> - 2.36.1-1
 - upgrade to stable upstream 2.36.1
   https://www.kernel.org/pub/linux/utils/util-linux/v2.36/v2.36.1-ReleaseNotes