From: Samuel Cabrero <scabrero@suse.com>
To: linux-cifs@vger.kernel.org
Cc: smfrench@gmail.com, pc@manguebit.com, ronniesahlberg@gmail.com,
sprasad@microsoft.com, tom@talpey.com, bharathsm@microsoft.com,
henrique.carvalho@suse.com, ematsumiya@suse.de,
Samuel Cabrero <scabrero@suse.com>
Subject: [PATCH 13/18] smb:client: Introduce swn_notification struct
Date: Fri, 10 Jul 2026 11:16:32 +0200 [thread overview]
Message-ID: <20260710091637.58873-14-scabrero@suse.com> (raw)
In-Reply-To: <20260710091637.58873-1-scabrero@suse.com>
This is a helper struct to contain all necessary data to process a
notification.
Signed-off-by: Samuel Cabrero <scabrero@suse.com>
---
fs/smb/client/cifs_swn.c | 129 ++++++++++++++++++++++++++++++---------
1 file changed, 99 insertions(+), 30 deletions(-)
diff --git a/fs/smb/client/cifs_swn.c b/fs/smb/client/cifs_swn.c
index 0a45be8f36d7..7e665b657f8d 100644
--- a/fs/smb/client/cifs_swn.c
+++ b/fs/smb/client/cifs_swn.c
@@ -36,6 +36,24 @@ struct cifs_swn_reg {
struct delayed_work check;
};
+struct cifs_swn_notification {
+ int type;
+ union {
+ struct {
+ const char *name;
+ int state;
+ } resource_name_changed;
+ struct {
+ struct sockaddr_storage *addr;
+ } client_move;
+ struct {
+ struct sockaddr_storage *addr;
+ } share_move;
+ } data;
+
+ struct cifs_swn_reg *swnreg;
+};
+
static int cifs_swn_auth_info_krb(struct cifs_tcon *tcon, struct sk_buff *skb)
{
int ret;
@@ -620,71 +638,122 @@ static int cifs_swn_client_move(struct cifs_tcon *tcon,
return cifs_swn_reconnect(tcon, addr);
}
+static int cifs_swn_handle_notification(const struct cifs_swn_notification *not)
+{
+ switch (not->type) {
+ case CIFS_SWN_NOTIFICATION_RESOURCE_CHANGE:
+ return cifs_swn_resource_state_changed(
+ not->swnreg->tcon, not->data.resource_name_changed.name,
+ not->data.resource_name_changed.state);
+ case CIFS_SWN_NOTIFICATION_CLIENT_MOVE:
+ return cifs_swn_client_move(not->swnreg->tcon,
+ not->data.client_move.addr);
+ default:
+ cifs_dbg(FYI, "%s: unknown notification type %d\n", __func__,
+ not->type);
+ break;
+ }
+ return 0;
+}
+
int cifs_swn_notify(struct sk_buff *skb, struct genl_info *info)
{
- struct cifs_swn_reg *swnreg;
- char name[256];
- int type;
+ int swnreg_id;
+ struct cifs_swn_notification not;
+ int ret;
+ /* Get the registration ID */
if (info->attrs[CIFS_GENL_ATTR_SWN_REGISTRATION_ID]) {
- int swnreg_id;
-
- swnreg_id = nla_get_u32(info->attrs[CIFS_GENL_ATTR_SWN_REGISTRATION_ID]);
- mutex_lock(&cifs_swnreg_idr_mutex);
- swnreg = idr_find(&cifs_swnreg_idr, swnreg_id);
- mutex_unlock(&cifs_swnreg_idr_mutex);
- if (swnreg == NULL) {
- cifs_dbg(FYI, "%s: registration id %d not found\n", __func__, swnreg_id);
- return -EINVAL;
- }
+ swnreg_id = nla_get_u32(
+ info->attrs[CIFS_GENL_ATTR_SWN_REGISTRATION_ID]);
} else {
cifs_dbg(FYI, "%s: missing registration id attribute\n", __func__);
return -EINVAL;
}
+ /* Fill the notification struct */
if (info->attrs[CIFS_GENL_ATTR_SWN_NOTIFICATION_TYPE]) {
- type = nla_get_u32(info->attrs[CIFS_GENL_ATTR_SWN_NOTIFICATION_TYPE]);
+ not.type = nla_get_u32(
+ info->attrs[CIFS_GENL_ATTR_SWN_NOTIFICATION_TYPE]);
} else {
cifs_dbg(FYI, "%s: missing notification type attribute\n", __func__);
return -EINVAL;
}
- switch (type) {
+ switch (not.type) {
case CIFS_SWN_NOTIFICATION_RESOURCE_CHANGE: {
- int state;
-
if (info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_NAME]) {
- nla_strscpy(name, info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_NAME],
- sizeof(name));
+ not.data.resource_name_changed
+ .name = (const char *)nla_data(
+ info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_NAME]);
} else {
cifs_dbg(FYI, "%s: missing resource name attribute\n", __func__);
return -EINVAL;
}
+
if (info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_STATE]) {
- state = nla_get_u32(info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_STATE]);
+ not.data.resource_name_changed.state = nla_get_u32(
+ info->attrs[CIFS_GENL_ATTR_SWN_RESOURCE_STATE]);
} else {
cifs_dbg(FYI, "%s: missing resource state attribute\n", __func__);
return -EINVAL;
}
- return cifs_swn_resource_state_changed(swnreg->tcon, name,
- state);
- }
+ } break;
case CIFS_SWN_NOTIFICATION_CLIENT_MOVE: {
- struct sockaddr_storage addr;
-
if (info->attrs[CIFS_GENL_ATTR_SWN_IP]) {
- nla_memcpy(&addr, info->attrs[CIFS_GENL_ATTR_SWN_IP], sizeof(addr));
+ not.data.client_move.addr =
+ nla_data(info->attrs[CIFS_GENL_ATTR_SWN_IP]);
} else {
cifs_dbg(FYI, "%s: missing IP address attribute\n", __func__);
return -EINVAL;
}
- return cifs_swn_client_move(swnreg->tcon, &addr);
- }
+ } break;
default:
- cifs_dbg(FYI, "%s: unknown notification type %d\n", __func__, type);
- break;
+ cifs_dbg(FYI, "%s: unknown notification type %d\n", __func__,
+ not.type);
+ return 0;
+ }
+
+ /*
+ * Get the registration.
+ */
+ mutex_lock(&cifs_swnreg_idr_mutex);
+ not.swnreg = idr_find(&cifs_swnreg_idr, swnreg_id);
+ if (not.swnreg == NULL) {
+ mutex_unlock(&cifs_swnreg_idr_mutex);
+ cifs_dbg(FYI, "%s: registration id %d not found\n", __func__,
+ swnreg_id);
+ return 0;
+ }
+
+ /*
+ * Increment the refcount under the lock while processing the notification
+ * and release the swnreg_idr_mutex because processing will take
+ * cifs_tcp_ses_lock.
+ */
+ if (!kref_get_unless_zero(¬.swnreg->ref_count)) {
+ /* The registration is being released, ignore the notificaiton */
+ mutex_unlock(&cifs_swnreg_idr_mutex);
+ return 0;
+ }
+ mutex_unlock(&cifs_swnreg_idr_mutex);
+
+ ret = cifs_swn_handle_notification(¬);
+ if (ret) {
+ cifs_dbg(FYI,
+ "%s: Failed to process notification for registration id %d: %d\n",
+ __func__, swnreg_id, ret);
}
+ mutex_lock(&cifs_swnreg_idr_mutex);
+ if (kref_put(¬.swnreg->ref_count, cifs_swn_reg_idr_remove)) {
+ mutex_unlock(&cifs_swnreg_idr_mutex);
+ cancel_delayed_work_sync(¬.swnreg->check);
+ cifs_swn_reg_release(not.swnreg);
+ return 0;
+ }
+ mutex_unlock(&cifs_swnreg_idr_mutex);
+
return 0;
}
--
2.54.0
next prev parent reply other threads:[~2026-07-10 9:17 UTC|newest]
Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-10 9:16 [PATCH 00/18] SWN: Decouple witness registrations and tcons Samuel Cabrero
2026-07-10 9:16 ` [PATCH 01/18] Revert "smb: client: resolve SWN tcon from live registrations" Samuel Cabrero
2026-07-10 9:16 ` [PATCH 02/18] smb:client: Adjust witness notification request Samuel Cabrero
2026-07-10 9:16 ` [PATCH 03/18] smb:client: Rename variable to match the rest of the code Samuel Cabrero
2026-07-10 9:16 ` [PATCH 04/18] smb:client: Split idr remove and release functions Samuel Cabrero
2026-07-10 9:16 ` [PATCH 05/18] smb:client: Add a specific task to refresh witness registrations Samuel Cabrero
2026-07-10 9:16 ` [PATCH 06/18] smb:client: Store the tcon dstaddr in the witness registration Samuel Cabrero
2026-07-10 9:16 ` [PATCH 07/18] smb:client: Fix printf format string Samuel Cabrero
2026-07-10 9:16 ` [PATCH 08/18] smb:client: Save memory allocations Samuel Cabrero
2026-07-10 9:16 ` [PATCH 09/18] smb:client: Use the correct return code Samuel Cabrero
2026-07-10 9:16 ` [PATCH 10/18] smb:client: Improve tcon matching logic Samuel Cabrero
2026-07-10 9:16 ` [PATCH 11/18] smb:client: Pass the tcon to cifs_swn_send_register_message Samuel Cabrero
2026-07-10 9:16 ` [PATCH 12/18] smb:client: Pass the tcon to notification handlers Samuel Cabrero
2026-07-10 9:16 ` Samuel Cabrero [this message]
2026-07-10 9:16 ` [PATCH 14/18] smb:client: Cache auth info Samuel Cabrero
2026-07-10 9:16 ` [PATCH 15/18] smb:client: Do not store the tcon reference, find a matching one Samuel Cabrero
2026-07-10 9:16 ` [PATCH 16/18] smb:client: Simplify registration creation Samuel Cabrero
2026-07-10 9:16 ` [PATCH 17/18] smb:client: Improve registration network and share names handling Samuel Cabrero
2026-07-10 9:16 ` [PATCH 18/18] smb:client: Avoid witness re-register if the address did not change Samuel Cabrero
2026-07-10 14:16 ` [PATCH 00/18] SWN: Decouple witness registrations and tcons Enzo Matsumiya
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260710091637.58873-14-scabrero@suse.com \
--to=scabrero@suse.com \
--cc=bharathsm@microsoft.com \
--cc=ematsumiya@suse.de \
--cc=henrique.carvalho@suse.com \
--cc=linux-cifs@vger.kernel.org \
--cc=pc@manguebit.com \
--cc=ronniesahlberg@gmail.com \
--cc=smfrench@gmail.com \
--cc=sprasad@microsoft.com \
--cc=tom@talpey.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox