Commit 06f08dab authored by Samuel Cabrero's avatar Samuel Cabrero Committed by Steve French
Browse files

cifs: Register generic netlink family



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

Signed-off-by: default avatarSamuel Cabrero <scabrero@suse.de>
Reviewed-by: default avatarAurelien Aptel <aaptel@suse.com>
Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 047092ff
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -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
+16 −1
Original line number Diff line number Diff line
@@ -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

fs/cifs/netlink.c

0 → 100644
+69 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
/*
 * Netlink routines for CIFS
 *
 * Copyright (c) 2020 Samuel Cabrero <scabrero@suse.de>
 */

#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__);
	}
}

fs/cifs/netlink.h

0 → 100644
+16 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0 */
/*
 * Netlink routines for CIFS
 *
 * Copyright (c) 2020 Samuel Cabrero <scabrero@suse.de>
 */

#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 */
Loading