File util-linux-fstrim-A-3.patch of Package util-linux.27340

From 402006fa6e4dd1ce52758f9be91caaffffb3f337 Mon Sep 17 00:00:00 2001
From: Stanislav Brabec <sbrabec@suse.cz>
Date: Mon, 10 Jun 2019 21:59:17 +0200
Subject: [PATCH 3/4] fstrim: properly de-duplicate fstrim -A

fstab can contain tag based mounts. De-duplication by source has to be
done after resolving the full source path.

Perform the table iteration twice. First time, prepare for
de-duplication, second time perform the TRIM itself.

Signed-off-by: Stanislav Brabec <sbrabec@suse.cz>
---
 sys-utils/fstrim.c | 43 ++++++++++++++++++++++++++++++-------------
 1 file changed, 30 insertions(+), 13 deletions(-)

Index: util-linux-2.33.1/sys-utils/fstrim.c
===================================================================
--- util-linux-2.33.1.orig/sys-utils/fstrim.c
+++ util-linux-2.33.1/sys-utils/fstrim.c
@@ -224,10 +224,6 @@ static int fstrim_all(struct fstrim_cont
 	mnt_init_debug(0);
 	ul_path_init_debug();
 
-	itr = mnt_new_iter(MNT_ITER_BACKWARD);
-	if (!itr)
-		err(MNT_EX_FAIL, _("failed to initialize libmount iterator"));
-
 	if (ctl->fstab)
 		filename = mnt_get_fstab_path();
 
@@ -238,35 +234,56 @@ static int fstrim_all(struct fstrim_cont
 	/* de-duplicate by mountpoints */
 	mnt_table_uniq_fs(tab, 0, uniq_fs_target_cmp);
 
-	/* de-duplicate by source */
-	mnt_table_uniq_fs(tab, MNT_UNIQ_FORWARD, uniq_fs_source_cmp);
-
 	if (ctl->fstab) {
 		cache = mnt_new_cache();
 		if (!cache)
 			err(MNT_EX_FAIL, _("failed to initialize libmount cache"));
 	}
 
+	itr = mnt_new_iter(MNT_ITER_BACKWARD);
+	if (!itr)
+		err(MNT_EX_FAIL, _("failed to initialize libmount iterator"));
+
 	while (mnt_table_next_fs(tab, itr, &fs) == 0) {
 		const char *src = mnt_fs_get_srcpath(fs),
 			   *tgt = mnt_fs_get_target(fs);
-		char *path;
-		int rc = 1;
 
-		if (!tgt || mnt_fs_is_pseudofs(fs) || mnt_fs_is_netfs(fs))
+		if (!tgt || mnt_fs_is_pseudofs(fs) || mnt_fs_is_netfs(fs)) {
+			mnt_table_remove_fs(tab, fs);
 			continue;
+		}
 
 		/* convert LABEL= (etc.) from fstab to paths */
 		if (!src && cache) {
 			const char *spec = mnt_fs_get_source(fs);
 
-			if (!spec)
+			if (!spec) {
+				mnt_table_remove_fs(tab, fs);
 				continue;
+			}
 			src = mnt_resolve_spec(spec, cache);
+			mnt_fs_set_source(fs, src);
 		}
 
-		if (!src || *src != '/')
+		if (!src || *src != '/') {
+			mnt_table_remove_fs(tab, fs);
 			continue;
+		}
+	}
+	mnt_free_iter(itr);
+
+	/* de-duplicate by source */
+	mnt_table_uniq_fs(tab, MNT_UNIQ_FORWARD, uniq_fs_source_cmp);
+
+	itr = mnt_new_iter(MNT_ITER_BACKWARD);
+	if (!itr)
+		err(MNT_EX_FAIL, _("failed to initialize libmount iterator"));
+
+	while (mnt_table_next_fs(tab, itr, &fs) == 0) {
+		const char *src = mnt_fs_get_srcpath(fs),
+			   *tgt = mnt_fs_get_target(fs);
+		char *path;
+		int rc = 1;
 
 		/* Is it really accessible mountpoint? Not all mountpoints are
 		 * accessible (maybe over mounted by another filesystem) */
@@ -300,10 +317,10 @@ static int fstrim_all(struct fstrim_cont
 		if (fstrim_filesystem(ctl, tgt, src) < 0)
 		       cnt_err++;
 	}
+	mnt_free_iter(itr);
 
 	ul_unref_path(wholedisk);
 	mnt_unref_table(tab);
-	mnt_free_iter(itr);
 	mnt_unref_cache(cache);
 
 	if (cnt && cnt == cnt_err)
openSUSE Build Service is sponsored by