Re: [PATCH] libmount: Special handling of root comparison for cifs in mnt_table_is_fs_mounted()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Stanislav,

I've looked more into it and I found some issues with the patch:

Stanislav Brabec <sbrabec@xxxxxxx> writes:
> +	while ((c = *subpath++))
                      ^^^ subpath is always post-incremented
> +	{
> +		if (c == '/') {
> +			if (!last_is_slash) {
> +				component_no++;
> +				if (component_no == 3)
> +					break;
                                         ^^^ when we break subpath
                                             actually 1 past the /
> +			}
> +			last_is_slash = true;
> +		} else
> +			last_is_slash = false;
> +	}
> +	if (component_no == 3) {
> +		int subpath_len = strlen(subpath);
> +		if (strncmp(root, subpath, subpath_len)) {
                             ^^^  ^^^ hence why here
with //localhost/share/dir in fstab we never get here
p root    => $1 = 0x7f28aa9977d0 "/dir"
p subpath => $2 = 0x7f28aa9979a2 "dir"

> +			if (*(root + subpath_len + 1) == 0)
> +				return "/";
> +			return root + subpath_len + 1;
> +		}
> +	}
> +	DBG(FS, ul_debugobj(fs, "cifs: leading part of root \"%s\" does
> not equal to mounted source subdir \"%s\"; should not happen", root,
> src));
^^^ this message gets printed with //localhost/share //localhost/share/ 

That being said, I could not make your patch fail i.e. make mount -a
mount the fs twice. So I'm not sure what happens there... I thought I
would give it a try.

I'm attaching a simpler patch that makes uses of streq_paths() in
lib/strutils.c (Note: streq_paths() and next_path_segment() have to be
backported for older versions of util-linux).

From a29acba1a7c71cdbfc1cc98f2905bfaf19b97a29 Mon Sep 17 00:00:00 2001
From: Aurelien Aptel <aaptel@xxxxxxxx>
Date: Thu, 1 Sep 2016 13:57:42 +0200
Subject: [PATCH] libmount/src/tab.c: fix mount -a for cifs

when mounting a cifs share, the src is actually an UNC path which can in
in several forms:

simple:            //host/share, //host/share/
including subpath: //host/share/sub/path

to check if the cifs fs is mounted we have to extract the subpath and
compare *that* to the root.

Signed-off-by: Aurelien Aptel <aaptel@xxxxxxxx>
---
 libmount/src/tab.c | 27 ++++++++++++++++++++++++---
 1 file changed, 24 insertions(+), 3 deletions(-)

diff --git a/libmount/src/tab.c b/libmount/src/tab.c
index 341e5e3..9c49ec8 100644
--- a/libmount/src/tab.c
+++ b/libmount/src/tab.c
@@ -1329,6 +1329,20 @@ err:
 }
 #endif /* HAVE_BTRFS_SUPPORT */
 
+static const char *get_cifs_unc_subdir_path (const char *unc)
+{
+	/*
+	 *  1 or more slash:     %*[/]
+	 *  1 or more non-slash: %*[^/]
+	 *  number of byte read: %n
+	 */
+	int share_end = 0;
+	int r = sscanf(unc, "%*[/]%*[^/]%*[/]%*[^/]%n", &share_end);
+	if (r == EOF || share_end == 0)
+		return NULL;
+	return unc + share_end;
+}
+
 /*
  * tb: /proc/self/mountinfo
  * fs: filesystem
@@ -1563,9 +1577,16 @@ int mnt_table_is_fs_mounted(struct libmnt_table *tb, struct libmnt_fs *fstab_fs)
 		}
 
 		if (root) {
-			const char *r = mnt_fs_get_root(fs);
-			if (!r || strcmp(r, root) != 0)
-				continue;
+			if (strcmp(mnt_fs_get_fstype(fs), "cifs") == 0) {
+				const char *unc_subdir = get_cifs_unc_subdir_path(src);
+				const char *path_on_fs = mnt_fs_get_root(fs);
+				if (!unc_subdir || !path_on_fs || !streq_paths(unc_subdir, path_on_fs))
+					continue;
+			} else {
+				const char *r = mnt_fs_get_root(fs);
+				if (!r || strcmp(r, root) != 0)
+					continue;
+			}
 		}
 
 		/*
-- 
2.1.4

Attachment: signature.asc
Description: PGP signature


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux