Commit bf80e5d4 authored by Samuel Cabrero's avatar Samuel Cabrero Committed by Steve French

cifs: Send witness register and unregister commands to userspace daemon

+ Define the generic netlink family commands and message attributes to
  communicate with the userspace daemon

+ The register and unregister commands are sent when connecting or
  disconnecting a tree. The witness registration keeps a pointer to
  the tcon and has the same lifetime.

+ Each registration has an id allocated by an IDR. This id is sent to the
  userspace daemon in the register command, and will be included in the
  notification messages from the userspace daemon to retrieve from the
  IDR the matching registration.

+ The authentication information is bundled in the register message.
  If kerberos is used the message just carries a flag.
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 e68f4a7b
......@@ -18,7 +18,7 @@ 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_SWN_UPCALL) += netlink.o cifs_swn.o
cifs-$(CONFIG_CIFS_FSCACHE) += fscache.o cache.o
......
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Witness Service client for CIFS
*
* Copyright (c) 2020 Samuel Cabrero <scabrero@suse.de>
*/
#ifndef _CIFS_SWN_H
#define _CIFS_SWN_H
struct cifs_tcon;
extern int cifs_swn_register(struct cifs_tcon *tcon);
extern int cifs_swn_unregister(struct cifs_tcon *tcon);
#endif /* _CIFS_SWN_H */
......@@ -62,6 +62,9 @@
#include "dfs_cache.h"
#endif
#include "fs_context.h"
#ifdef CONFIG_CIFS_SWN_UPCALL
#include "cifs_swn.h"
#endif
extern mempool_t *cifs_req_poolp;
extern bool disable_legacy_dialects;
......@@ -1944,7 +1947,17 @@ cifs_put_tcon(struct cifs_tcon *tcon)
return;
}
/* TODO witness unregister */
#ifdef CONFIG_CIFS_SWN_UPCALL
if (tcon->use_witness) {
int rc;
rc = cifs_swn_unregister(tcon);
if (rc < 0) {
cifs_dbg(VFS, "%s: Failed to unregister for witness notifications: %d\n",
__func__, rc);
}
}
#endif
list_del_init(&tcon->tcon_list);
spin_unlock(&cifs_tcp_ses_lock);
......@@ -2111,8 +2124,17 @@ cifs_get_tcon(struct cifs_ses *ses, struct smb3_fs_context *ctx)
if (ctx->witness) {
if (ses->server->vals->protocol_id >= SMB30_PROT_ID) {
if (tcon->capabilities & SMB2_SHARE_CAP_CLUSTER) {
/* TODO witness register */
/*
* Set witness in use flag in first place
* to retry registration in the echo task
*/
tcon->use_witness = true;
/* And try to register immediately */
rc = cifs_swn_register(tcon);
if (rc < 0) {
cifs_dbg(VFS, "Failed to register for witness notifications: %d\n", rc);
goto out_fail;
}
} else {
/* TODO: try to extend for non-cluster uses (eg multichannel) */
cifs_dbg(VFS, "witness requested on mount but no CLUSTER capability on share\n");
......
......@@ -13,6 +13,17 @@
#include "cifs_debug.h"
static const struct nla_policy cifs_genl_policy[CIFS_GENL_ATTR_MAX + 1] = {
[CIFS_GENL_ATTR_SWN_REGISTRATION_ID] = { .type = NLA_U32 },
[CIFS_GENL_ATTR_SWN_NET_NAME] = { .type = NLA_STRING },
[CIFS_GENL_ATTR_SWN_SHARE_NAME] = { .type = NLA_STRING },
[CIFS_GENL_ATTR_SWN_IP] = { .len = sizeof(struct sockaddr_storage) },
[CIFS_GENL_ATTR_SWN_NET_NAME_NOTIFY] = { .type = NLA_FLAG },
[CIFS_GENL_ATTR_SWN_SHARE_NAME_NOTIFY] = { .type = NLA_FLAG },
[CIFS_GENL_ATTR_SWN_IP_NOTIFY] = { .type = NLA_FLAG },
[CIFS_GENL_ATTR_SWN_KRB_AUTH] = { .type = NLA_FLAG },
[CIFS_GENL_ATTR_SWN_USER_NAME] = { .type = NLA_STRING },
[CIFS_GENL_ATTR_SWN_PASSWORD] = { .type = NLA_STRING },
[CIFS_GENL_ATTR_SWN_DOMAIN_NAME] = { .type = NLA_STRING },
};
static struct genl_ops cifs_genl_ops[] = {
......
......@@ -19,11 +19,26 @@ enum cifs_genl_multicast_groups {
};
enum cifs_genl_attributes {
CIFS_GENL_ATTR_UNSPEC,
CIFS_GENL_ATTR_SWN_REGISTRATION_ID,
CIFS_GENL_ATTR_SWN_NET_NAME,
CIFS_GENL_ATTR_SWN_SHARE_NAME,
CIFS_GENL_ATTR_SWN_IP,
CIFS_GENL_ATTR_SWN_NET_NAME_NOTIFY,
CIFS_GENL_ATTR_SWN_SHARE_NAME_NOTIFY,
CIFS_GENL_ATTR_SWN_IP_NOTIFY,
CIFS_GENL_ATTR_SWN_KRB_AUTH,
CIFS_GENL_ATTR_SWN_USER_NAME,
CIFS_GENL_ATTR_SWN_PASSWORD,
CIFS_GENL_ATTR_SWN_DOMAIN_NAME,
__CIFS_GENL_ATTR_MAX,
};
#define CIFS_GENL_ATTR_MAX (__CIFS_GENL_ATTR_MAX - 1)
enum cifs_genl_commands {
CIFS_GENL_CMD_UNSPEC,
CIFS_GENL_CMD_SWN_REGISTER,
CIFS_GENL_CMD_SWN_UNREGISTER,
__CIFS_GENL_CMD_MAX
};
#define CIFS_GENL_CMD_MAX (__CIFS_GENL_CMD_MAX - 1)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment