File util-linux-libmount-btrfs-is-mounted.patch of Package util-linux.2662

From 352740e88e2c9cb180fe845ce210b1c7b5ad88c7 Mon Sep 17 00:00:00 2001
From: Karel Zak <kzak@redhat.com>
Date: Wed, 2 Dec 2015 13:38:51 +0100
Subject: [PATCH] libmount: fix is-mounted check for btrfs

fstab:
  /dev/sdc        /mnt/test       btrfs   subvol=/anydir
  /mnt/test       /mnt/test2      auto    bind

and "mount -a" does not detect that /mnt/test2 is already mounted.

Reported-by: Stanislav Brabec <sbrabec@suse.cz>
Signed-off-by: Karel Zak <kzak@redhat.com>
---
 libmount/src/tab.c | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

Index: util-linux-2.25/libmount/src/tab.c
===================================================================
--- util-linux-2.25.orig/libmount/src/tab.c
+++ util-linux-2.25/libmount/src/tab.c
@@ -1295,21 +1295,33 @@ struct libmnt_fs *mnt_table_get_fs_root(
 			goto dflt;
 		}
 
-		/* on btrfs the subvolume is used as fs-root in
-		 * /proc/self/mountinfo, so we have to get the original subvolume
-		 * name from src_fs and prepend the subvolume name to the
-		 * fs-root path
+		/* It's possible that fstab_fs source is subdirectory on btrfs
+		 * subvolume or anothe bind mount. For example:
+		 *
+		 * /dev/sdc        /mnt/test       btrfs   subvol=/anydir
+		 * /mnt/test/foo   /mnt/test2      auto    bind
+		 *
+		 * in this case, the root for /mnt/test2 will be /anydir/foo on
+		 * /dev/sdc. It means we have to compose the final root from
+		 * root and src_root.
 		 */
 		src_root = mnt_fs_get_root(src_fs);
-		if (src_root && !startswith(root, src_root)) {
-			size_t sz = strlen(root) + strlen(src_root) + 1;
-			char *tmp = malloc(sz);
 
-			if (!tmp)
-				goto err;
-			snprintf(tmp, sz, "%s%s", src_root, root);
-			free(root);
-			root = tmp;
+		DBG(FS, ul_debugobj(fs, "source root: %s, source FS root: %s", root, src_root));
+
+		if (src_root && !startswith(root, src_root)) {
+			if (strcmp(root, "/") == 0) {
+				free(root);
+				root = strdup(src_root);
+				if (!root)
+					goto err;
+			} else {
+				char *tmp;
+				if (asprintf(&tmp, "%s%s", src_root, root) < 0)
+					goto err;
+				free(root);
+				root = tmp;
+			}
 		}
 	}
 
@@ -1430,6 +1442,8 @@ int mnt_table_is_fs_mounted(struct libmn
 	}
 	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
 
+	DBG(FS, ul_debugobj(fstab_fs, "is mounted: src=%s, tgt=%s, root=%s", src, tgt, root));
+
 	while (mnt_table_next_fs(tb, &itr, &fs) == 0) {
 
 		int eq = mnt_fs_streq_srcpath(fs, src);
openSUSE Build Service is sponsored by