Re: [PATCH v4 01/11] cifs: Make extract_hostname function public

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

 



I have fixed up (various merge conflicts etc.) and merged the first
three in the series (see attached), as well as added a patch for some
comment cleanups, and a patch to move (following Rafal's suggestion) a
few of the functions from fs/cifs/misc.c to a new file fs/cifs/unc.c

The first three in the series are very low risk and can be merged
independent of the others to make review/cleanup of the final patches
easier.  I will fixup patch 4 (which add a mount parm and thus
requires rebasing on Ronnie's mount API series).  Am planning
reviewing the final seven in the series, let me know if changes needed
to the remaining (ie patches 5 through 11).


On Mon, Nov 30, 2020 at 12:04 PM Samuel Cabrero <scabrero@xxxxxxx> wrote:
>
> Move the function to misc.c and give it a public header.
>
> Signed-off-by: Samuel Cabrero <scabrero@xxxxxxx>
> ---
>  fs/cifs/cifsproto.h |  1 +
>  fs/cifs/connect.c   | 34 ----------------------------------
>  fs/cifs/misc.c      | 32 ++++++++++++++++++++++++++++++++
>  3 files changed, 33 insertions(+), 34 deletions(-)
>
> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
> index 24c6f36177ba..d716e81d86fa 100644
> --- a/fs/cifs/cifsproto.h
> +++ b/fs/cifs/cifsproto.h
> @@ -620,6 +620,7 @@ int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov,
>  struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server);
>  void cifs_put_tcp_super(struct super_block *sb);
>  int update_super_prepath(struct cifs_tcon *tcon, char *prefix);
> +char *extract_hostname(const char *unc);
>
>  #ifdef CONFIG_CIFS_DFS_UPCALL
>  static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 28c1459fb0fc..a938371af6ef 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -284,7 +284,6 @@ static int ip_connect(struct TCP_Server_Info *server);
>  static int generic_ip_connect(struct TCP_Server_Info *server);
>  static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
>  static void cifs_prune_tlinks(struct work_struct *work);
> -static char *extract_hostname(const char *unc);
>
>  /*
>   * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may
> @@ -1232,39 +1231,6 @@ cifs_demultiplex_thread(void *p)
>         module_put_and_exit(0);
>  }
>
> -/* extract the host portion of the UNC string */
> -static char *
> -extract_hostname(const char *unc)
> -{
> -       const char *src;
> -       char *dst, *delim;
> -       unsigned int len;
> -
> -       /* skip double chars at beginning of string */
> -       /* BB: check validity of these bytes? */
> -       if (strlen(unc) < 3)
> -               return ERR_PTR(-EINVAL);
> -       for (src = unc; *src && *src == '\\'; src++)
> -               ;
> -       if (!*src)
> -               return ERR_PTR(-EINVAL);
> -
> -       /* delimiter between hostname and sharename is always '\\' now */
> -       delim = strchr(src, '\\');
> -       if (!delim)
> -               return ERR_PTR(-EINVAL);
> -
> -       len = delim - src;
> -       dst = kmalloc((len + 1), GFP_KERNEL);
> -       if (dst == NULL)
> -               return ERR_PTR(-ENOMEM);
> -
> -       memcpy(dst, src, len);
> -       dst[len] = '\0';
> -
> -       return dst;
> -}
> -
>  static int get_option_ul(substring_t args[], unsigned long *option)
>  {
>         int rc;
> diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
> index 1c14cf01dbef..3d5cc25c167f 100644
> --- a/fs/cifs/misc.c
> +++ b/fs/cifs/misc.c
> @@ -1195,3 +1195,35 @@ int update_super_prepath(struct cifs_tcon *tcon, char *prefix)
>         cifs_put_tcon_super(sb);
>         return rc;
>  }
> +
> +/* extract the host portion of the UNC string */
> +char *extract_hostname(const char *unc)
> +{
> +       const char *src;
> +       char *dst, *delim;
> +       unsigned int len;
> +
> +       /* skip double chars at beginning of string */
> +       /* BB: check validity of these bytes? */
> +       if (strlen(unc) < 3)
> +               return ERR_PTR(-EINVAL);
> +       for (src = unc; *src && *src == '\\'; src++)
> +               ;
> +       if (!*src)
> +               return ERR_PTR(-EINVAL);
> +
> +       /* delimiter between hostname and sharename is always '\\' now */
> +       delim = strchr(src, '\\');
> +       if (!delim)
> +               return ERR_PTR(-EINVAL);
> +
> +       len = delim - src;
> +       dst = kmalloc((len + 1), GFP_KERNEL);
> +       if (dst == NULL)
> +               return ERR_PTR(-ENOMEM);
> +
> +       memcpy(dst, src, len);
> +       dst[len] = '\0';
> +
> +       return dst;
> +}
> --
> 2.29.2
>


--
Thanks,

Steve
From 749765e260720d332eb8f03c3be28557b8ceb954 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@xxxxxxx>
Date: Mon, 30 Nov 2020 19:02:48 +0100
Subject: [PATCH 2/5] cifs: Make extract_sharename function public

Move the function to misc.c

Signed-off-by: Samuel Cabrero <scabrero@xxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/cache.c     | 24 ------------------------
 fs/cifs/cifsproto.h |  1 +
 fs/cifs/fscache.c   |  1 +
 fs/cifs/fscache.h   |  1 -
 fs/cifs/misc.c      | 24 ++++++++++++++++++++++++
 5 files changed, 26 insertions(+), 25 deletions(-)

diff --git a/fs/cifs/cache.c b/fs/cifs/cache.c
index 0f2adecb94f2..488fe0ffc1ef 100644
--- a/fs/cifs/cache.c
+++ b/fs/cifs/cache.c
@@ -53,30 +53,6 @@ const struct fscache_cookie_def cifs_fscache_server_index_def = {
 	.type = FSCACHE_COOKIE_TYPE_INDEX,
 };
 
-char *extract_sharename(const char *treename)
-{
-	const char *src;
-	char *delim, *dst;
-	int len;
-
-	/* skip double chars at the beginning */
-	src = treename + 2;
-
-	/* share name is always preceded by '\\' now */
-	delim = strchr(src, '\\');
-	if (!delim)
-		return ERR_PTR(-EINVAL);
-	delim++;
-	len = strlen(delim);
-
-	/* caller has to free the memory */
-	dst = kstrndup(delim, len, GFP_KERNEL);
-	if (!dst)
-		return ERR_PTR(-ENOMEM);
-
-	return dst;
-}
-
 static enum
 fscache_checkaux cifs_fscache_super_check_aux(void *cookie_netfs_data,
 					      const void *data,
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 3fe0c4a0d36d..b80b57a66804 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -618,6 +618,7 @@ struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server);
 void cifs_put_tcp_super(struct super_block *sb);
 int update_super_prepath(struct cifs_tcon *tcon, char *prefix);
 char *extract_hostname(const char *unc);
+char *extract_sharename(const char *unc);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
diff --git a/fs/cifs/fscache.c b/fs/cifs/fscache.c
index da688185403c..20d24af33ee2 100644
--- a/fs/cifs/fscache.c
+++ b/fs/cifs/fscache.c
@@ -22,6 +22,7 @@
 #include "cifsglob.h"
 #include "cifs_debug.h"
 #include "cifs_fs_sb.h"
+#include "cifsproto.h"
 
 /*
  * Key layout of CIFS server cache index object
diff --git a/fs/cifs/fscache.h b/fs/cifs/fscache.h
index 1091633d2adb..e811f2dd7619 100644
--- a/fs/cifs/fscache.h
+++ b/fs/cifs/fscache.h
@@ -57,7 +57,6 @@ extern const struct fscache_cookie_def cifs_fscache_inode_object_def;
 
 extern int cifs_fscache_register(void);
 extern void cifs_fscache_unregister(void);
-extern char *extract_sharename(const char *);
 
 /*
  * fscache.c
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 3d5cc25c167f..f0a1c24751b2 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1227,3 +1227,27 @@ char *extract_hostname(const char *unc)
 
 	return dst;
 }
+
+char *extract_sharename(const char *unc)
+{
+	const char *src;
+	char *delim, *dst;
+	int len;
+
+	/* skip double chars at the beginning */
+	src = unc + 2;
+
+	/* share name is always preceded by '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+	delim++;
+	len = strlen(delim);
+
+	/* caller has to free the memory */
+	dst = kstrndup(delim, len, GFP_KERNEL);
+	if (!dst)
+		return ERR_PTR(-ENOMEM);
+
+	return dst;
+}
-- 
2.27.0

From bcbee8cbe271b8af465cdc66efe9c1620ea25dbb Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@xxxxxxxxxxxxx>
Date: Fri, 11 Dec 2020 19:48:26 -0600
Subject: [PATCH 3/5] cifs: minor kernel style fixes for comments

Trivial fix for a few comments which didn't follow kernel style

Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/connect.c | 25 +++++++++++++++----------
 1 file changed, 15 insertions(+), 10 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index d3836db33e7c..ec80b6c3e20f 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1024,9 +1024,9 @@ cifs_demultiplex_thread(void *p)
 	module_put_and_exit(0);
 }
 
-/** Returns true if srcaddr isn't specified and rhs isn't
- * specified, or if srcaddr is specified and
- * matches the IP address of the rhs argument.
+/**
+ * Returns true if srcaddr isn't specified and rhs isn't specified, or
+ * if srcaddr is specified and matches the IP address of the rhs argument
  */
 bool
 cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs)
@@ -2544,7 +2544,8 @@ ip_connect(struct TCP_Server_Info *server)
 void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 			  struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 {
-	/* if we are reconnecting then should we check to see if
+	/*
+	 * If we are reconnecting then should we check to see if
 	 * any requested capabilities changed locally e.g. via
 	 * remount but we can not do much about it here
 	 * if they have (even if we could detect it by the following)
@@ -2552,7 +2553,8 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 	 * or if we change to make all sb to same share the same
 	 * sb as NFS - then we only have one backpointer to sb.
 	 * What if we wanted to mount the server share twice once with
-	 * and once without posixacls or posix paths? */
+	 * and once without posixacls or posix paths?
+	 */
 	__u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
 
 	if (ctx && ctx->no_linux_ext) {
@@ -2571,11 +2573,15 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 	if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
 		__u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
 		cifs_dbg(FYI, "unix caps which server supports %lld\n", cap);
-		/* check for reconnect case in which we do not
-		   want to change the mount behavior if we can avoid it */
+		/*
+		 * check for reconnect case in which we do not
+		 * want to change the mount behavior if we can avoid it
+		 */
 		if (ctx == NULL) {
-			/* turn off POSIX ACL and PATHNAMES if not set
-			   originally at mount time */
+			/*
+			 * turn off POSIX ACL and PATHNAMES if not set
+			 * originally at mount time
+			 */
 			if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
 				cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
 			if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
@@ -2977,7 +2983,6 @@ build_unc_path_to_root(const struct smb3_fs_context *ctx,
 /**
  * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
  *
- *
  * If a referral is found, cifs_sb->ctx->mount_options will be (re-)allocated
  * to a string containing updated options for the submount.  Otherwise it
  * will be left untouched.
-- 
2.27.0

From b69c063066231af65879321fd53cd371c106fa82 Mon Sep 17 00:00:00 2001
From: Steve French <stfrench@xxxxxxxxxxxxx>
Date: Fri, 11 Dec 2020 20:22:04 -0600
Subject: [PATCH 4/5] cifs: cleanup misc.c

misc.c was getting a little large, move two of the UNC parsing relating
functions to a new C file unc.c which makes the coding of the
upcoming witness protocol patch series a little cleaner as well.

Suggested-by: Rafal Szczesniak <rafal@xxxxxxxxxxxxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/Makefile |  2 +-
 fs/cifs/misc.c   | 56 ----------------------------------------
 fs/cifs/unc.c    | 67 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 68 insertions(+), 57 deletions(-)
 create mode 100644 fs/cifs/unc.c

diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index cd17d0e50f2a..848ebad6af7d 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -8,7 +8,7 @@ obj-$(CONFIG_CIFS) += cifs.o
 cifs-y := trace.o cifsfs.o cifssmb.o cifs_debug.o connect.o dir.o file.o \
 	  inode.o link.o misc.o netmisc.o smbencrypt.o transport.o asn1.o \
 	  cifs_unicode.o nterr.o cifsencrypt.o \
-	  readdir.o ioctl.o sess.o export.o smb1ops.o winucase.o \
+	  readdir.o ioctl.o sess.o export.o smb1ops.o unc.o winucase.o \
 	  smb2ops.o smb2maperror.o smb2transport.o \
 	  smb2misc.o smb2pdu.o smb2inode.o smb2file.o cifsacl.o fs_context.o
 
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index f0a1c24751b2..1c14cf01dbef 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1195,59 +1195,3 @@ int update_super_prepath(struct cifs_tcon *tcon, char *prefix)
 	cifs_put_tcon_super(sb);
 	return rc;
 }
-
-/* extract the host portion of the UNC string */
-char *extract_hostname(const char *unc)
-{
-	const char *src;
-	char *dst, *delim;
-	unsigned int len;
-
-	/* skip double chars at beginning of string */
-	/* BB: check validity of these bytes? */
-	if (strlen(unc) < 3)
-		return ERR_PTR(-EINVAL);
-	for (src = unc; *src && *src == '\\'; src++)
-		;
-	if (!*src)
-		return ERR_PTR(-EINVAL);
-
-	/* delimiter between hostname and sharename is always '\\' now */
-	delim = strchr(src, '\\');
-	if (!delim)
-		return ERR_PTR(-EINVAL);
-
-	len = delim - src;
-	dst = kmalloc((len + 1), GFP_KERNEL);
-	if (dst == NULL)
-		return ERR_PTR(-ENOMEM);
-
-	memcpy(dst, src, len);
-	dst[len] = '\0';
-
-	return dst;
-}
-
-char *extract_sharename(const char *unc)
-{
-	const char *src;
-	char *delim, *dst;
-	int len;
-
-	/* skip double chars at the beginning */
-	src = unc + 2;
-
-	/* share name is always preceded by '\\' now */
-	delim = strchr(src, '\\');
-	if (!delim)
-		return ERR_PTR(-EINVAL);
-	delim++;
-	len = strlen(delim);
-
-	/* caller has to free the memory */
-	dst = kstrndup(delim, len, GFP_KERNEL);
-	if (!dst)
-		return ERR_PTR(-ENOMEM);
-
-	return dst;
-}
diff --git a/fs/cifs/unc.c b/fs/cifs/unc.c
new file mode 100644
index 000000000000..2c5665f5543a
--- /dev/null
+++ b/fs/cifs/unc.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ *   Copyright (C) 2020, Microsoft Corporation.
+ *
+ *   Author(s): Steve French <stfrench@xxxxxxxxxxxxx>
+ *              Suresh Jayaraman <sjayaraman@xxxxxxx>
+ *              Jeff Layton <jlayton@xxxxxxxxxx>
+ */
+
+#include <linux/slab.h>
+#include "cifsproto.h"
+
+/* extract the host portion of the UNC string */
+char *extract_hostname(const char *unc)
+{
+	const char *src;
+	char *dst, *delim;
+	unsigned int len;
+
+	/* skip double chars at beginning of string */
+	/* BB: check validity of these bytes? */
+	if (strlen(unc) < 3)
+		return ERR_PTR(-EINVAL);
+	for (src = unc; *src && *src == '\\'; src++)
+		;
+	if (!*src)
+		return ERR_PTR(-EINVAL);
+
+	/* delimiter between hostname and sharename is always '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+
+	len = delim - src;
+	dst = kmalloc((len + 1), GFP_KERNEL);
+	if (dst == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(dst, src, len);
+	dst[len] = '\0';
+
+	return dst;
+}
+
+char *extract_sharename(const char *unc)
+{
+	const char *src;
+	char *delim, *dst;
+	int len;
+
+	/* skip double chars at the beginning */
+	src = unc + 2;
+
+	/* share name is always preceded by '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+	delim++;
+	len = strlen(delim);
+
+	/* caller has to free the memory */
+	dst = kstrndup(delim, len, GFP_KERNEL);
+	if (!dst)
+		return ERR_PTR(-ENOMEM);
+
+	return dst;
+}
-- 
2.27.0

From cf6a6c0841bc125a9ede50000c22f0110eea805b Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@xxxxxxx>
Date: Mon, 30 Nov 2020 19:02:49 +0100
Subject: [PATCH 5/5] cifs: Register generic netlink family

Register a new generic netlink family to talk to the witness service
userspace daemon.

Signed-off-by: Samuel Cabrero <scabrero@xxxxxxx>
---
 fs/cifs/Kconfig                        | 11 ++++
 fs/cifs/Makefile                       |  2 +
 fs/cifs/cifsfs.c                       | 17 ++++++-
 fs/cifs/netlink.c                      | 69 ++++++++++++++++++++++++++
 fs/cifs/netlink.h                      | 16 ++++++
 include/uapi/linux/cifs/cifs_netlink.h | 31 ++++++++++++
 6 files changed, 145 insertions(+), 1 deletion(-)
 create mode 100644 fs/cifs/netlink.c
 create mode 100644 fs/cifs/netlink.h
 create mode 100644 include/uapi/linux/cifs/cifs_netlink.h

diff --git a/fs/cifs/Kconfig b/fs/cifs/Kconfig
index 604f65f4b6c5..664ac5c63d39 100644
--- a/fs/cifs/Kconfig
+++ b/fs/cifs/Kconfig
@@ -190,6 +190,17 @@ config CIFS_DFS_UPCALL
 	  servers if their addresses change or for implicit mounts of
 	  DFS junction points. If unsure, say Y.
 
+config CIFS_SWN_UPCALL
+	bool "SWN feature support"
+	depends on CIFS
+	help
+	  The Service Witness Protocol (SWN) is used to get notifications
+	  from a highly available server of resource state changes. This
+	  feature enables an upcall mechanism for CIFS which contacts an
+	  userspace daemon to establish the DCE/RPC connection to retrieve
+	  the cluster available interfaces and resource change notifications.
+	  If unsure, say Y.
+
 config CIFS_NFSD_EXPORT
 	bool "Allow nfsd to export CIFS file system"
 	depends on CIFS && BROKEN
diff --git a/fs/cifs/Makefile b/fs/cifs/Makefile
index 848ebad6af7d..9e398d227b0e 100644
--- a/fs/cifs/Makefile
+++ b/fs/cifs/Makefile
@@ -18,6 +18,8 @@ cifs-$(CONFIG_CIFS_UPCALL) += cifs_spnego.o
 
 cifs-$(CONFIG_CIFS_DFS_UPCALL) += dns_resolve.o cifs_dfs_ref.o dfs_cache.o
 
+cifs-$(CONFIG_CIFS_SWN_UPCALL) += netlink.o
+
 cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
 
 cifs-$(CONFIG_CIFS_SMB_DIRECT) += smbdirect.o
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4f27f77d3053..5d32561ae2ed 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -55,6 +55,9 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dfs_cache.h"
 #endif
+#ifdef CONFIG_CIFS_SWN_UPCALL
+#include "netlink.h"
+#endif
 #include "fs_context.h"
 
 /*
@@ -1601,10 +1604,15 @@ init_cifs(void)
 	if (rc)
 		goto out_destroy_dfs_cache;
 #endif /* CONFIG_CIFS_UPCALL */
+#ifdef CONFIG_CIFS_SWN_UPCALL
+	rc = cifs_genl_init();
+	if (rc)
+		goto out_register_key_type;
+#endif /* CONFIG_CIFS_SWN_UPCALL */
 
 	rc = init_cifs_idmap();
 	if (rc)
-		goto out_register_key_type;
+		goto out_cifs_swn_init;
 
 	rc = register_filesystem(&cifs_fs_type);
 	if (rc)
@@ -1620,7 +1628,11 @@ init_cifs(void)
 
 out_init_cifs_idmap:
 	exit_cifs_idmap();
+out_cifs_swn_init:
+#ifdef CONFIG_CIFS_SWN_UPCALL
+	cifs_genl_exit();
 out_register_key_type:
+#endif
 #ifdef CONFIG_CIFS_UPCALL
 	exit_cifs_spnego();
 out_destroy_dfs_cache:
@@ -1657,6 +1669,9 @@ exit_cifs(void)
 	unregister_filesystem(&smb3_fs_type);
 	cifs_dfs_release_automount_timer();
 	exit_cifs_idmap();
+#ifdef CONFIG_CIFS_SWN_UPCALL
+	cifs_genl_exit();
+#endif
 #ifdef CONFIG_CIFS_UPCALL
 	exit_cifs_spnego();
 #endif
diff --git a/fs/cifs/netlink.c b/fs/cifs/netlink.c
new file mode 100644
index 000000000000..b9154661fa85
--- /dev/null
+++ b/fs/cifs/netlink.c
@@ -0,0 +1,69 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Netlink routines for CIFS
+ *
+ * Copyright (c) 2020 Samuel Cabrero <scabrero@xxxxxxx>
+ */
+
+#include <net/genetlink.h>
+#include <uapi/linux/cifs/cifs_netlink.h>
+
+#include "netlink.h"
+#include "cifsglob.h"
+#include "cifs_debug.h"
+
+static const struct nla_policy cifs_genl_policy[CIFS_GENL_ATTR_MAX + 1] = {
+};
+
+static struct genl_ops cifs_genl_ops[] = {
+};
+
+static const struct genl_multicast_group cifs_genl_mcgrps[] = {
+	[CIFS_GENL_MCGRP_SWN] = { .name = CIFS_GENL_MCGRP_SWN_NAME },
+};
+
+struct genl_family cifs_genl_family = {
+	.name		= CIFS_GENL_NAME,
+	.version	= CIFS_GENL_VERSION,
+	.hdrsize	= 0,
+	.maxattr	= CIFS_GENL_ATTR_MAX,
+	.module		= THIS_MODULE,
+	.policy		= cifs_genl_policy,
+	.ops		= cifs_genl_ops,
+	.n_ops		= ARRAY_SIZE(cifs_genl_ops),
+	.mcgrps		= cifs_genl_mcgrps,
+	.n_mcgrps	= ARRAY_SIZE(cifs_genl_mcgrps),
+};
+
+/**
+ * cifs_genl_init - Register generic netlink family
+ *
+ * Return zero if initialized successfully, otherwise non-zero.
+ */
+int cifs_genl_init(void)
+{
+	int ret;
+
+	ret = genl_register_family(&cifs_genl_family);
+	if (ret < 0) {
+		cifs_dbg(VFS, "%s: failed to register netlink family\n",
+				__func__);
+		return ret;
+	}
+
+	return 0;
+}
+
+/**
+ * cifs_genl_exit - Unregister generic netlink family
+ */
+void cifs_genl_exit(void)
+{
+	int ret;
+
+	ret = genl_unregister_family(&cifs_genl_family);
+	if (ret < 0) {
+		cifs_dbg(VFS, "%s: failed to unregister netlink family\n",
+				__func__);
+	}
+}
diff --git a/fs/cifs/netlink.h b/fs/cifs/netlink.h
new file mode 100644
index 000000000000..e2fa8ed24c54
--- /dev/null
+++ b/fs/cifs/netlink.h
@@ -0,0 +1,16 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Netlink routines for CIFS
+ *
+ * Copyright (c) 2020 Samuel Cabrero <scabrero@xxxxxxx>
+ */
+
+#ifndef _CIFS_NETLINK_H
+#define _CIFS_NETLINK_H
+
+extern struct genl_family cifs_genl_family;
+
+extern int cifs_genl_init(void);
+extern void cifs_genl_exit(void);
+
+#endif /* _CIFS_NETLINK_H */
diff --git a/include/uapi/linux/cifs/cifs_netlink.h b/include/uapi/linux/cifs/cifs_netlink.h
new file mode 100644
index 000000000000..cdb1bd78fbc7
--- /dev/null
+++ b/include/uapi/linux/cifs/cifs_netlink.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: LGPL-2.1+ WITH Linux-syscall-note */
+/*
+ * Netlink routines for CIFS
+ *
+ * Copyright (c) 2020 Samuel Cabrero <scabrero@xxxxxxx>
+ */
+
+
+#ifndef _UAPILINUX_CIFS_NETLINK_H
+#define _UAPILINUX_CIFS_NETLINK_H
+
+#define CIFS_GENL_NAME			"cifs"
+#define CIFS_GENL_VERSION		0x1
+
+#define CIFS_GENL_MCGRP_SWN_NAME	"cifs_mcgrp_swn"
+
+enum cifs_genl_multicast_groups {
+	CIFS_GENL_MCGRP_SWN,
+};
+
+enum cifs_genl_attributes {
+	__CIFS_GENL_ATTR_MAX,
+};
+#define CIFS_GENL_ATTR_MAX (__CIFS_GENL_ATTR_MAX - 1)
+
+enum cifs_genl_commands {
+	__CIFS_GENL_CMD_MAX
+};
+#define CIFS_GENL_CMD_MAX (__CIFS_GENL_CMD_MAX - 1)
+
+#endif /* _UAPILINUX_CIFS_NETLINK_H */
-- 
2.27.0

From 855b7b6a65b954944f2f8801925196fa62599528 Mon Sep 17 00:00:00 2001
From: Samuel Cabrero <scabrero@xxxxxxx>
Date: Mon, 30 Nov 2020 19:02:47 +0100
Subject: [PATCH 1/5] cifs: Make extract_hostname function public

Move the function to misc.c and give it a public header.

Signed-off-by: Samuel Cabrero <scabrero@xxxxxxx>
Signed-off-by: Steve French <stfrench@xxxxxxxxxxxxx>
---
 fs/cifs/cifsproto.h |  1 +
 fs/cifs/connect.c   | 34 ----------------------------------
 fs/cifs/misc.c      | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 33 insertions(+), 34 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index aa7a717c34ab..3fe0c4a0d36d 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -617,6 +617,7 @@ int smb2_parse_query_directory(struct cifs_tcon *tcon, struct kvec *rsp_iov,
 struct super_block *cifs_get_tcp_super(struct TCP_Server_Info *server);
 void cifs_put_tcp_super(struct super_block *sb);
 int update_super_prepath(struct cifs_tcon *tcon, char *prefix);
+char *extract_hostname(const char *unc);
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 static inline int get_dfs_path(const unsigned int xid, struct cifs_ses *ses,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 95b12f148735..d3836db33e7c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -77,7 +77,6 @@ static int ip_connect(struct TCP_Server_Info *server);
 static int generic_ip_connect(struct TCP_Server_Info *server);
 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
 static void cifs_prune_tlinks(struct work_struct *work);
-static char *extract_hostname(const char *unc);
 
 /*
  * Resolve hostname and set ip addr in tcp ses. Useful for hostnames that may
@@ -1025,39 +1024,6 @@ cifs_demultiplex_thread(void *p)
 	module_put_and_exit(0);
 }
 
-/* extract the host portion of the UNC string */
-static char *
-extract_hostname(const char *unc)
-{
-	const char *src;
-	char *dst, *delim;
-	unsigned int len;
-
-	/* skip double chars at beginning of string */
-	/* BB: check validity of these bytes? */
-	if (strlen(unc) < 3)
-		return ERR_PTR(-EINVAL);
-	for (src = unc; *src && *src == '\\'; src++)
-		;
-	if (!*src)
-		return ERR_PTR(-EINVAL);
-
-	/* delimiter between hostname and sharename is always '\\' now */
-	delim = strchr(src, '\\');
-	if (!delim)
-		return ERR_PTR(-EINVAL);
-
-	len = delim - src;
-	dst = kmalloc((len + 1), GFP_KERNEL);
-	if (dst == NULL)
-		return ERR_PTR(-ENOMEM);
-
-	memcpy(dst, src, len);
-	dst[len] = '\0';
-
-	return dst;
-}
-
 /** Returns true if srcaddr isn't specified and rhs isn't
  * specified, or if srcaddr is specified and
  * matches the IP address of the rhs argument.
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1c14cf01dbef..3d5cc25c167f 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -1195,3 +1195,35 @@ int update_super_prepath(struct cifs_tcon *tcon, char *prefix)
 	cifs_put_tcon_super(sb);
 	return rc;
 }
+
+/* extract the host portion of the UNC string */
+char *extract_hostname(const char *unc)
+{
+	const char *src;
+	char *dst, *delim;
+	unsigned int len;
+
+	/* skip double chars at beginning of string */
+	/* BB: check validity of these bytes? */
+	if (strlen(unc) < 3)
+		return ERR_PTR(-EINVAL);
+	for (src = unc; *src && *src == '\\'; src++)
+		;
+	if (!*src)
+		return ERR_PTR(-EINVAL);
+
+	/* delimiter between hostname and sharename is always '\\' now */
+	delim = strchr(src, '\\');
+	if (!delim)
+		return ERR_PTR(-EINVAL);
+
+	len = delim - src;
+	dst = kmalloc((len + 1), GFP_KERNEL);
+	if (dst == NULL)
+		return ERR_PTR(-ENOMEM);
+
+	memcpy(dst, src, len);
+	dst[len] = '\0';
+
+	return dst;
+}
-- 
2.27.0


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

  Powered by Linux