Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2229695/?format=api
{ "id": 2229695, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2229695/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260428155759.226368-1-henrique.carvalho@suse.com/", "project": { "id": 12, "url": "http://patchwork.ozlabs.org/api/1.1/projects/12/?format=api", "name": "Linux CIFS Client", "link_name": "linux-cifs-client", "list_id": "linux-cifs.vger.kernel.org", "list_email": "linux-cifs@vger.kernel.org", "web_url": "", "scm_url": "", "webscm_url": "" }, "msgid": "<20260428155759.226368-1-henrique.carvalho@suse.com>", "date": "2026-04-28T15:57:54", "name": "[v2,05/11] smb: server: split interface management from TCP in preparation for QUIC", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "f06050dfa1fd772acdb71fd775c506cba836391e", "submitter": { "id": 89563, "url": "http://patchwork.ozlabs.org/api/1.1/people/89563/?format=api", "name": "Henrique Carvalho", "email": "henrique.carvalho@suse.com" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/20260428155759.226368-1-henrique.carvalho@suse.com/mbox/", "series": [ { "id": 501886, "url": "http://patchwork.ozlabs.org/api/1.1/series/501886/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=501886", "date": "2026-04-28T15:55:41", "name": "smb: implement SMB over QUIC", "version": 2, "mbox": "http://patchwork.ozlabs.org/series/501886/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2229695/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2229695/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-cifs+bounces-11231-incoming=patchwork.ozlabs.org@vger.kernel.org>", "X-Original-To": [ "incoming@patchwork.ozlabs.org", "linux-cifs@vger.kernel.org" ], "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=suse.com header.i=@suse.com header.a=rsa-sha256\n header.s=google header.b=PyC0KR36;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c0a:e001:db::12fc:5321; helo=sea.lore.kernel.org;\n envelope-from=linux-cifs+bounces-11231-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com\n header.b=\"PyC0KR36\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=209.85.128.46", "smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=suse.com", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=suse.com" ], "Received": [ "from sea.lore.kernel.org (sea.lore.kernel.org\n [IPv6:2600:3c0a:e001:db::12fc:5321])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g4ll20gbvz1xrS\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 29 Apr 2026 02:10:06 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby sea.lore.kernel.org (Postfix) with ESMTP id AB6983115B88\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 28 Apr 2026 16:01:52 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id CF410441048;\n\tTue, 28 Apr 2026 15:58:10 +0000 (UTC)", "from mail-wm1-f46.google.com (mail-wm1-f46.google.com\n [209.85.128.46])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id E7E2A3C945A\n\tfor <linux-cifs@vger.kernel.org>; Tue, 28 Apr 2026 15:58:07 +0000 (UTC)", "by mail-wm1-f46.google.com with SMTP id\n 5b1f17b1804b1-488a9033b2cso122444195e9.2\n for <linux-cifs@vger.kernel.org>;\n Tue, 28 Apr 2026 08:58:07 -0700 (PDT)", "from precision ([2a01:4b00:c007:bb00:be9d:a3c4:18b1:4a25])\n by smtp.gmail.com with ESMTPSA id\n 5b1f17b1804b1-48a7b560a84sm3409255e9.4.2026.04.28.08.58.05\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Tue, 28 Apr 2026 08:58:05 -0700 (PDT)" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1777391890; cv=none;\n b=GRquKXBkA+Qp2sdE0Qz6n5Nlww2imjD6KFz6TNHY7HDDrlGMqCZk2RzzozU3Hb3XqcVbJytvf7BL0z6GE/GGxzP1eAUTYFIO9fNmCooEVR/TdDMT8apKvguqC5/WfnOW9KstBhmZz6cqRVqor7AR2qA0E4BTBMVErXHbBkarzrE=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1777391890; c=relaxed/simple;\n\tbh=mc8duuf18vGiKek7T/0raBsUgBqkfZdV+R5o90VA56k=;\n\th=From:To:Cc:Subject:Date:Message-ID:MIME-Version;\n b=VNg2vVkMKgx36bNSE/M6F5VkmDAgfLeujbqxzmIQxLdIe8Li8Guq4A47OcM+9ZDOEIb4kvPPlWTJqcBNQ8uO4gLmmdpR1rENP72RiQhHAHYPrZod7gE3KKUq73Yea0vsrgImZDembijZrfi//URSk59Ze39oppUFMpHeCT3pglI=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=suse.com;\n spf=pass smtp.mailfrom=suse.com;\n dkim=pass (2048-bit key) header.d=suse.com header.i=@suse.com\n header.b=PyC0KR36; arc=none smtp.client-ip=209.85.128.46", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=suse.com; s=google; t=1777391886; x=1777996686;\n darn=vger.kernel.org;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:from:to:cc:subject:date:message-id:reply-to;\n bh=XEWRVYzyIgG3Bi1Pa1Vh5S1rEgoz2yBSa2G8ehlgCSM=;\n b=PyC0KR36lb83Z988LHxI+6DqVlkw3aBJpHEpv3DHkwtJ2ybrxtQthtqkg9GvNDskoC\n Ehd6veECdnm5tEti0WKZytw8D81jFBUGRggpJbyStwUwPcFMQMFuLiaIZeEjJIJFO0RZ\n EhRQIB5q3YqBqOPctmO6sk3og1bu5MwFMuXn8INZT4sdTh0iWfmVLBY8jt6AHIFrnkdo\n uh+EsgKnZFn/FmfDEnm46afjbSC98PfcBRYvHbAUOHXsIVvxxC90K0qkbEjBHcGZtubg\n WDcITBLOOjOAq0jgvtJmgBopcLDQpVdlrRwvVh+qmKUsK0sTucxMEhb4IHjFjyMAEGPO\n Otpg==", "X-Google-DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1777391886; x=1777996686;\n h=content-transfer-encoding:mime-version:message-id:date:subject:cc\n :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date\n :message-id:reply-to;\n bh=XEWRVYzyIgG3Bi1Pa1Vh5S1rEgoz2yBSa2G8ehlgCSM=;\n b=mvozUZvsuNikejZJKD/WPOCFDWPKC9xDEg3ckmrAYm1Xe3MuemE5LvjZIzELjYGowZ\n 5aY6pJNCWMRowrc8h1CBgH8Izkl2GLH0L3JGFKvbI+7Eb/weXJ6Jki36iHC7Fvt1z856\n e06zK4pO6eyF+UskqszD+3z8HGCB+QQwqh9FrUevuRpBADNC8QMmqOOQdKrTUvKU40+x\n nXse4/Bp3bn4gdDGA4ZufzVwWm0V3b8RQISd5l7T/5ehdydjh0eohtpoWaHlMd4cJ9B5\n eD3vDJTGMy+maxocMwbNl9AcYOCpDefEm3XK44mBShyaNXwSHqte2wB1X9tdRfhniZO9\n V3AA==", "X-Gm-Message-State": "AOJu0Yy9JOmtsREVdOgzrlvafTEVsjVnhRWE9DJB8eF3UlXP+Ep72YAU\n\terpngFt/xezBDO2VlA7cM7eFiEvvae6EZyuA1EyuIvInk+dCTV7Cp9KbVfXr1dY/TleYKCDxvkh\n\tQvQJcszP3fg==", "X-Gm-Gg": "AeBDiet86DOo6FgM0WrmoqkjXno6o4vkEIKfY81pDlPqzi+sJa9nlfJ/XdJMIPyGTt2\n\tsJtaJ+EJhGAvb64+gDVcjtl8DM1V53woqbEqtChgIBp9GyFoP7kU5CA0OGsBdIH8X+Dq7YsJv08\n\tKB1LrO5F23xPi6HEY+HVRTirv1S+2pDMLadxasPiSAwtfU8KzmTcOtqFt4GM5ago7C01OXrQ1O4\n\t3xxeRLK0M59oi06sN8m1Nc/5SrLE+jc+BUSkdZ7XHbBaTOcdv5lwgyvDcU46eq7nVG7FpHAWMsI\n\tWJvqfu+7VnexhrzM13lGaCVQLHcg7uLSLok4EyIMLsEj78G7y1mgMnpHNFWHXPkXRQsWaPUdZuG\n\tZ65IWBqlmgW/yLrtUD7dwH45LCN+pvG10+O3uyASUwFy6CWpiyBcpu6XMdbQh1dxQfZUdcsUXXb\n\tIGnXhYi7JUoW/YXBMhZeOLW3XdsFimJgP1mJKknMugs+LR", "X-Received": "by 2002:a05:600c:4f92:b0:489:1ff1:74df with SMTP id\n 5b1f17b1804b1-48a77ae5430mr57089135e9.1.1777391885753;\n Tue, 28 Apr 2026 08:58:05 -0700 (PDT)", "From": "Henrique Carvalho <henrique.carvalho@suse.com>", "To": "linux-cifs@vger.kernel.org", "Cc": "linkinjeon@kernel.org,\n\tsfrench@samba.org,\n\tmetze@samba.org,\n\tsenozhatsky@chromium.org,\n\ttom@talpey.com,\n\tematsumiya@suse.de,\n\tHenrique Carvalho <henrique.carvalho@suse.com>", "Subject": "[PATCH v2 05/11] smb: server: split interface management from TCP in\n preparation for QUIC", "Date": "Tue, 28 Apr 2026 12:57:54 -0300", "Message-ID": "<20260428155759.226368-1-henrique.carvalho@suse.com>", "X-Mailer": "git-send-email 2.53.0", "Precedence": "bulk", "X-Mailing-List": "linux-cifs@vger.kernel.org", "List-Id": "<linux-cifs.vger.kernel.org>", "List-Subscribe": "<mailto:linux-cifs+subscribe@vger.kernel.org>", "List-Unsubscribe": "<mailto:linux-cifs+unsubscribe@vger.kernel.org>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit" }, "content": "Move active_num_conn out of transport_tcp.c and define it in\nconnection.c.\n\nMove the transport-agnostic bits out into a new interface.c /\ninterface.h, network-interface bookkeeping, the iface_list, the\nnetdevice notifier, alloc/find/set helpers, and the per-iface forker\nkthread plumbing.\n\nMake the necessary changes to transport_tcp.c, without functional change\nfor the TCP path; this is purely a layering rearrangement to make room\nfor additional transports.\n\nSigned-off-by: Henrique Carvalho <henrique.carvalho@suse.com>\n---\n fs/smb/server/Makefile | 2 +-\n fs/smb/server/connection.c | 9 +-\n fs/smb/server/connection.h | 1 +\n fs/smb/server/interface.c | 196 ++++++++++++++++++++++++++++++\n fs/smb/server/interface.h | 34 ++++++\n fs/smb/server/transport_ipc.c | 2 +-\n fs/smb/server/transport_tcp.c | 223 ++++------------------------------\n fs/smb/server/transport_tcp.h | 7 +-\n 8 files changed, 265 insertions(+), 209 deletions(-)\n create mode 100644 fs/smb/server/interface.c\n create mode 100644 fs/smb/server/interface.h", "diff": "diff --git a/fs/smb/server/Makefile b/fs/smb/server/Makefile\nindex 6407ba6b9340..7bd6501bfdc9 100644\n--- a/fs/smb/server/Makefile\n+++ b/fs/smb/server/Makefile\n@@ -8,7 +8,7 @@ ksmbd-y :=\tunicode.o auth.o vfs.o vfs_cache.o server.o ndr.o \\\n \t\tmisc.o oplock.o connection.o ksmbd_work.o crypto_ctx.o \\\n \t\tmgmt/ksmbd_ida.o mgmt/user_config.o mgmt/share_config.o \\\n \t\tmgmt/tree_connect.o mgmt/user_session.o smb_common.o \\\n-\t\ttransport_tcp.o transport_ipc.o smbacl.o smb2pdu.o \\\n+\t\tinterface.o transport_tcp.o transport_ipc.o smbacl.o smb2pdu.o \\\n \t\tsmb2ops.o smb2misc.o ksmbd_spnego_negtokeninit.asn1.o \\\n \t\tksmbd_spnego_negtokentarg.asn1.o asn1.o\n \ndiff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c\nindex 31392d245c30..7465b364c35c 100644\n--- a/fs/smb/server/connection.c\n+++ b/fs/smb/server/connection.c\n@@ -12,6 +12,7 @@\n #include \"smb_common.h\"\n #include \"mgmt/ksmbd_ida.h\"\n #include \"connection.h\"\n+#include \"interface.h\"\n #include \"transport_tcp.h\"\n #include \"transport_rdma.h\"\n #include \"misc.h\"\n@@ -79,6 +80,8 @@ static int create_proc_clients(void) { return 0; }\n static void delete_proc_clients(void) {}\n #endif\n \n+atomic_t active_num_conn = ATOMIC_INIT(0);\n+\n /**\n * ksmbd_conn_free() - free resources of the connection instance\n *\n@@ -512,9 +515,9 @@ int ksmbd_conn_transport_init(void)\n \tint ret;\n \n \tmutex_lock(&init_lock);\n-\tret = ksmbd_tcp_init();\n+\tret = ksmbd_interface_init();\n \tif (ret) {\n-\t\tpr_err(\"Failed to init TCP subsystem: %d\\n\", ret);\n+\t\tpr_err(\"Failed to init interface: %d\\n\", ret);\n \t\tgoto out;\n \t}\n \n@@ -558,7 +561,7 @@ void ksmbd_conn_transport_destroy(void)\n {\n \tdelete_proc_clients();\n \tmutex_lock(&init_lock);\n-\tksmbd_tcp_destroy();\n+\tksmbd_interface_destroy();\n \tksmbd_rdma_stop_listening();\n \tstop_sessions();\n \tmutex_unlock(&init_lock);\ndiff --git a/fs/smb/server/connection.h b/fs/smb/server/connection.h\nindex ae21a1bd4c70..b060baf5f688 100644\n--- a/fs/smb/server/connection.h\n+++ b/fs/smb/server/connection.h\n@@ -157,6 +157,7 @@ struct ksmbd_transport {\n #define CONN_HASH_BITS\t12\n extern DECLARE_HASHTABLE(conn_list, CONN_HASH_BITS);\n extern struct rw_semaphore conn_list_lock;\n+extern atomic_t active_num_conn;\n \n bool ksmbd_conn_alive(struct ksmbd_conn *conn);\n void ksmbd_conn_wait_idle(struct ksmbd_conn *conn);\ndiff --git a/fs/smb/server/interface.c b/fs/smb/server/interface.c\nnew file mode 100644\nindex 000000000000..a5e59a420639\n--- /dev/null\n+++ b/fs/smb/server/interface.c\n@@ -0,0 +1,196 @@\n+// SPDX-License-Identifier: GPL-2.0-or-later\n+/*\n+ * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>\n+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.\n+ */\n+\n+#include <linux/freezer.h>\n+\n+#include \"smb_common.h\"\n+#include \"server.h\"\n+#include \"auth.h\"\n+#include \"connection.h\"\n+#include \"transport_tcp.h\"\n+#include \"interface.h\"\n+\n+static LIST_HEAD(iface_list);\n+static int bind_additional_ifaces;\n+\n+static struct interface *alloc_iface(char *ifname)\n+{\n+\tstruct interface *iface;\n+\n+\tif (!ifname)\n+\t\treturn NULL;\n+\n+\tiface = kzalloc_obj(struct interface, KSMBD_DEFAULT_GFP);\n+\tif (!iface) {\n+\t\tkfree(ifname);\n+\t\treturn NULL;\n+\t}\n+\n+\tiface->name = ifname;\n+\tiface->state = IFACE_STATE_DOWN;\n+\tlist_add(&iface->entry, &iface_list);\n+\treturn iface;\n+}\n+\n+/**\n+ * ksmbd_interface_run_kthread() - start a per-interface forker thread\n+ * @iface:\tpointer to struct interface\n+ * @kthread_fn:\tthread routine to run\n+ * @suf:\tsuffix to append to the thread name (e.g. \"tcp\")\n+ *\n+ * Return:\tthe started task_struct, or ERR_PTR on failure.\n+ */\n+struct task_struct *ksmbd_interface_run_kthread(struct interface *iface,\n+\t\t\t\t\t\tint (*kthread_fn)(void *), const char *suf)\n+{\n+\tstruct task_struct *kthread;\n+\n+\tkthread = kthread_run(kthread_fn, (void *)iface, \"ksmbd-%s-%s\", iface->name, suf);\n+\treturn kthread;\n+}\n+\n+void ksmbd_interface_stop_kthread(struct task_struct *kthread)\n+{\n+\tint ret;\n+\n+\tif (!kthread)\n+\t\treturn;\n+\n+\tret = kthread_stop(kthread);\n+\tif (ret)\n+\t\tpr_err(\"failed to stop forker thread\\n\");\n+}\n+\n+static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,\n+\t\t\t void *ptr)\n+{\n+\tstruct net_device *netdev = netdev_notifier_info_to_dev(ptr);\n+\tstruct interface *iface;\n+\tint ret;\n+\n+\tswitch (event) {\n+\tcase NETDEV_UP:\n+\t\tif (netif_is_bridge_port(netdev))\n+\t\t\treturn NOTIFY_OK;\n+\n+\t\tiface = ksmbd_find_netdev_name_iface_list(netdev->name);\n+\t\tif (iface && iface->state == IFACE_STATE_DOWN) {\n+\t\t\tksmbd_debug(CONN, \"netdev-up event: netdev(%s) is going up\\n\",\n+\t\t\t\t\tiface->name);\n+\n+\t\t\tif (!iface->net)\n+\t\t\t\tiface->net = get_net(dev_net(netdev));\n+\n+\t\t\tret = ksmbd_tcp_create_socket(iface);\n+\t\t\tif (ret)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tif (!iface && bind_additional_ifaces) {\n+\t\t\tiface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP));\n+\t\t\tif (!iface)\n+\t\t\t\treturn NOTIFY_OK;\n+\n+\t\t\tksmbd_debug(CONN, \"netdev-up event: netdev(%s) is going up\\n\",\n+\t\t\t\t iface->name);\n+\n+\t\t\tiface->net = get_net(dev_net(netdev));\n+\n+\t\t\tret = ksmbd_tcp_create_socket(iface);\n+\t\t\tif (ret)\n+\t\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\tcase NETDEV_DOWN:\n+\t\tiface = ksmbd_find_netdev_name_iface_list(netdev->name);\n+\t\tif (iface && iface->state == IFACE_STATE_CONFIGURED) {\n+\t\t\tksmbd_debug(CONN, \"netdev-down event: netdev(%s) is going down\\n\",\n+\t\t\t\t\tiface->name);\n+\n+\t\t\tif (iface->ksmbd_tcp_socket)\n+\t\t\t\tkernel_sock_shutdown(iface->ksmbd_tcp_socket, SHUT_RDWR);\n+\n+\t\t\tif (iface->ksmbd_tcp_kthread)\n+\t\t\t\tksmbd_interface_stop_kthread(iface->ksmbd_tcp_kthread);\n+\n+\t\t\tif (iface->ksmbd_tcp_socket)\n+\t\t\t\tsock_release(iface->ksmbd_tcp_socket);\n+\n+\t\t\tiface->ksmbd_tcp_kthread = NULL;\n+\t\t\tiface->ksmbd_tcp_socket = NULL;\n+\n+\t\t\tput_net(iface->net);\n+\t\t\tiface->net = NULL;\n+\n+\t\t\tiface->state = IFACE_STATE_DOWN;\n+\t\t\tbreak;\n+\t\t}\n+\t\tbreak;\n+\t}\n+\n+\treturn NOTIFY_DONE;\n+}\n+\n+static struct notifier_block ksmbd_netdev_notifier = {\n+\t.notifier_call = ksmbd_netdev_event,\n+};\n+\n+int ksmbd_interface_init(void)\n+{\n+\tregister_netdevice_notifier(&ksmbd_netdev_notifier);\n+\n+\treturn 0;\n+}\n+\n+\n+void ksmbd_interface_destroy(void)\n+{\n+\tstruct interface *iface, *tmp;\n+\n+\tunregister_netdevice_notifier(&ksmbd_netdev_notifier);\n+\n+\tlist_for_each_entry_safe(iface, tmp, &iface_list, entry) {\n+\t\tlist_del(&iface->entry);\n+\t\tkfree(iface->name);\n+\t\tkfree(iface);\n+\t}\n+}\n+\n+struct interface *\n+ksmbd_find_netdev_name_iface_list(char *netdev_name)\n+{\n+\tstruct interface *iface;\n+\n+\tlist_for_each_entry(iface, &iface_list, entry)\n+\t\tif (!strcmp(iface->name, netdev_name))\n+\t\t\treturn iface;\n+\treturn NULL;\n+}\n+\n+int ksmbd_set_interfaces(char *ifc_list, int ifc_list_sz)\n+{\n+\tint sz = 0;\n+\n+\tif (!ifc_list_sz) {\n+\t\tbind_additional_ifaces = 1;\n+\t\treturn 0;\n+\t}\n+\n+\twhile (ifc_list_sz > 0) {\n+\t\tif (!alloc_iface(kstrdup(ifc_list, KSMBD_DEFAULT_GFP)))\n+\t\t\treturn -ENOMEM;\n+\n+\t\tsz = strlen(ifc_list);\n+\t\tif (!sz)\n+\t\t\tbreak;\n+\n+\t\tifc_list += sz + 1;\n+\t\tifc_list_sz -= (sz + 1);\n+\t}\n+\n+\tbind_additional_ifaces = 0;\n+\n+\treturn 0;\n+}\ndiff --git a/fs/smb/server/interface.h b/fs/smb/server/interface.h\nnew file mode 100644\nindex 000000000000..7e35645076a9\n--- /dev/null\n+++ b/fs/smb/server/interface.h\n@@ -0,0 +1,34 @@\n+/* SPDX-License-Identifier: GPL-2.0 */\n+/*\n+ * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>\n+ * Copyright (C) 2018 Samsung Electronics Co., Ltd.\n+ *\n+ */\n+\n+#ifndef __KSMBD_INTERFACE_H__\n+#define __KSMBD_INTERFACE_H__\n+\n+#include <linux/freezer.h>\n+\n+#define IFACE_STATE_DOWN\t\tBIT(0)\n+#define IFACE_STATE_CONFIGURED\t\tBIT(1)\n+\n+struct interface {\n+\tstruct task_struct\t*ksmbd_tcp_kthread;\n+\tstruct socket\t\t*ksmbd_tcp_socket;\n+\tstruct list_head\tentry;\n+\tchar\t\t\t*name;\n+\tint\t\t\tstate;\n+\tstruct net\t\t*net;\n+};\n+\n+int ksmbd_interface_init(void);\n+void ksmbd_interface_destroy(void);\n+int ksmbd_set_interfaces(char *ifc_list, int ifc_list_sz);\n+struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);\n+struct task_struct *ksmbd_interface_run_kthread(struct interface *iface,\n+\t\t\t\t\t\tint (*kthread_fn)(void *),\n+\t\t\t\t\t\tconst char *suf);\n+void ksmbd_interface_stop_kthread(struct task_struct *kthread);\n+\n+#endif /* _KSMBD_INTERFACE_H */\ndiff --git a/fs/smb/server/transport_ipc.c b/fs/smb/server/transport_ipc.c\nindex 2dbabe2d8005..6ccfb1cf8ed7 100644\n--- a/fs/smb/server/transport_ipc.c\n+++ b/fs/smb/server/transport_ipc.c\n@@ -348,7 +348,7 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req)\n \tret |= ksmbd_set_server_string(req->server_string);\n \tret |= ksmbd_set_work_group(req->work_group);\n \tserver_conf.bind_interfaces_only = req->bind_interfaces_only;\n-\tret |= ksmbd_tcp_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),\n+\tret |= ksmbd_set_interfaces(KSMBD_STARTUP_CONFIG_INTERFACES(req),\n \t\t\t\t\treq->ifc_list_sz);\n out:\n \tif (ret) {\ndiff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c\nindex 7e29b06820e2..37f4238f72f5 100644\n--- a/fs/smb/server/transport_tcp.c\n+++ b/fs/smb/server/transport_tcp.c\n@@ -11,23 +11,7 @@\n #include \"auth.h\"\n #include \"connection.h\"\n #include \"transport_tcp.h\"\n-\n-#define IFACE_STATE_DOWN\t\tBIT(0)\n-#define IFACE_STATE_CONFIGURED\t\tBIT(1)\n-\n-static atomic_t active_num_conn;\n-\n-struct interface {\n-\tstruct task_struct\t*ksmbd_kthread;\n-\tstruct socket\t\t*ksmbd_socket;\n-\tstruct list_head\tentry;\n-\tchar\t\t\t*name;\n-\tint\t\t\tstate;\n-};\n-\n-static LIST_HEAD(iface_list);\n-\n-static int bind_additional_ifaces;\n+#include \"interface.h\"\n \n struct tcp_transport {\n \tstruct ksmbd_transport\t\ttransport;\n@@ -38,8 +22,6 @@ struct tcp_transport {\n \n static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops;\n \n-static void tcp_stop_kthread(struct task_struct *kthread);\n-static struct interface *alloc_iface(char *ifname);\n static void ksmbd_tcp_disconnect(struct ksmbd_transport *t);\n \n #define KSMBD_TRANS(t)\t(&(t)->transport)\n@@ -214,7 +196,7 @@ static int ksmbd_tcp_new_connection(struct socket *client_sk)\n *\n * Return:\t0 on success, error number otherwise\n */\n-static int ksmbd_kthread_fn(void *p)\n+static int tcp_kthread_fn(void *p)\n {\n \tstruct socket *client_sk = NULL;\n \tstruct interface *iface = (struct interface *)p;\n@@ -223,10 +205,9 @@ static int ksmbd_kthread_fn(void *p)\n \tunsigned int max_ip_conns;\n \n \twhile (!kthread_should_stop()) {\n-\t\tif (!iface->ksmbd_socket) {\n+\t\tif (!iface->ksmbd_tcp_socket)\n \t\t\tbreak;\n-\t\t}\n-\t\tret = kernel_accept(iface->ksmbd_socket, &client_sk, 0);\n+\t\tret = kernel_accept(iface->ksmbd_tcp_socket, &client_sk, 0);\n \t\tif (ret == -EINVAL)\n \t\t\tbreak;\n \t\tif (ret)\n@@ -298,32 +279,6 @@ static int ksmbd_kthread_fn(void *p)\n \treturn 0;\n }\n \n-/**\n- * ksmbd_tcp_run_kthread() - start forker thread\n- * @iface: pointer to struct interface\n- *\n- * start forker thread(ksmbd/0) at module init time to listen\n- * on port 445 for new SMB connection requests. It creates per connection\n- * server threads(ksmbd/x)\n- *\n- * Return:\t0 on success or error number\n- */\n-static int ksmbd_tcp_run_kthread(struct interface *iface)\n-{\n-\tint rc;\n-\tstruct task_struct *kthread;\n-\n-\tkthread = kthread_run(ksmbd_kthread_fn, (void *)iface, \"ksmbd-%s\",\n-\t\t\t iface->name);\n-\tif (IS_ERR(kthread)) {\n-\t\trc = PTR_ERR(kthread);\n-\t\treturn rc;\n-\t}\n-\tiface->ksmbd_kthread = kthread;\n-\n-\treturn 0;\n-}\n-\n /**\n * ksmbd_tcp_readv() - read data from socket in given iovec\n * @t:\t\t\tTCP transport instance\n@@ -432,7 +387,7 @@ static void ksmbd_tcp_disconnect(struct ksmbd_transport *t)\n \t\tatomic_dec(&active_num_conn);\n }\n \n-static void tcp_destroy_socket(struct socket *ksmbd_socket)\n+void ksmbd_tcp_destroy_socket(struct socket *ksmbd_socket)\n {\n \tint ret;\n \n@@ -451,21 +406,22 @@ static void tcp_destroy_socket(struct socket *ksmbd_socket)\n *\n * Return:\t0 on success, error number otherwise\n */\n-static int create_socket(struct interface *iface)\n+int ksmbd_tcp_create_socket(struct interface *iface)\n {\n \tint ret;\n \tstruct sockaddr_in6 sin6;\n \tstruct sockaddr_in sin;\n \tstruct socket *ksmbd_socket;\n+\tstruct task_struct *kthread;\n \tbool ipv4 = false;\n \n-\tret = sock_create_kern(current->nsproxy->net_ns, PF_INET6, SOCK_STREAM,\n-\t\t\tIPPROTO_TCP, &ksmbd_socket);\n+\tret = sock_create_kern(iface->net, PF_INET6, SOCK_STREAM,\n+\t\t\t IPPROTO_TCP, &ksmbd_socket);\n \tif (ret) {\n \t\tif (ret != -EAFNOSUPPORT)\n \t\t\tpr_err(\"Can't create socket for ipv6, fallback to ipv4: %d\\n\", ret);\n-\t\tret = sock_create_kern(current->nsproxy->net_ns, PF_INET,\n-\t\t\t\tSOCK_STREAM, IPPROTO_TCP, &ksmbd_socket);\n+\t\tret = sock_create_kern(iface->net, PF_INET, SOCK_STREAM,\n+\t\t\t\t IPPROTO_TCP, &ksmbd_socket);\n \t\tif (ret) {\n \t\t\tpr_err(\"Can't create socket for ipv4: %d\\n\", ret);\n \t\t\tgoto out_clear;\n@@ -515,165 +471,28 @@ static int create_socket(struct interface *iface)\n \t\tgoto out_error;\n \t}\n \n-\tiface->ksmbd_socket = ksmbd_socket;\n-\tret = ksmbd_tcp_run_kthread(iface);\n-\tif (ret) {\n+\tiface->ksmbd_tcp_socket = ksmbd_socket;\n+\n+\tkthread = ksmbd_interface_run_kthread(iface, tcp_kthread_fn, \"tcp\");\n+\tif (IS_ERR(kthread)) {\n \t\tpr_err(\"Can't start ksmbd main kthread: %d\\n\", ret);\n+\t\tret = PTR_ERR(kthread);\n \t\tgoto out_error;\n \t}\n+\n+\tiface->ksmbd_tcp_kthread = kthread;\n \tiface->state = IFACE_STATE_CONFIGURED;\n \n \treturn 0;\n \n out_error:\n-\ttcp_destroy_socket(ksmbd_socket);\n+\tksmbd_tcp_destroy_socket(ksmbd_socket);\n out_clear:\n-\tiface->ksmbd_socket = NULL;\n+\tiface->ksmbd_tcp_socket = NULL;\n+\tiface->ksmbd_tcp_kthread = NULL;\n \treturn ret;\n }\n \n-struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name)\n-{\n-\tstruct interface *iface;\n-\n-\tlist_for_each_entry(iface, &iface_list, entry)\n-\t\tif (!strcmp(iface->name, netdev_name))\n-\t\t\treturn iface;\n-\treturn NULL;\n-}\n-\n-static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,\n-\t\t\t void *ptr)\n-{\n-\tstruct net_device *netdev = netdev_notifier_info_to_dev(ptr);\n-\tstruct interface *iface;\n-\tint ret;\n-\n-\tswitch (event) {\n-\tcase NETDEV_UP:\n-\t\tif (netif_is_bridge_port(netdev))\n-\t\t\treturn NOTIFY_OK;\n-\n-\t\tiface = ksmbd_find_netdev_name_iface_list(netdev->name);\n-\t\tif (iface && iface->state == IFACE_STATE_DOWN) {\n-\t\t\tksmbd_debug(CONN, \"netdev-up event: netdev(%s) is going up\\n\",\n-\t\t\t\t\tiface->name);\n-\t\t\tret = create_socket(iface);\n-\t\t\tif (ret)\n-\t\t\t\treturn NOTIFY_OK;\n-\t\t}\n-\t\tif (!iface && bind_additional_ifaces) {\n-\t\t\tiface = alloc_iface(kstrdup(netdev->name, KSMBD_DEFAULT_GFP));\n-\t\t\tif (!iface)\n-\t\t\t\treturn NOTIFY_OK;\n-\t\t\tksmbd_debug(CONN, \"netdev-up event: netdev(%s) is going up\\n\",\n-\t\t\t\t iface->name);\n-\t\t\tret = create_socket(iface);\n-\t\t\tif (ret)\n-\t\t\t\tbreak;\n-\t\t}\n-\t\tbreak;\n-\tcase NETDEV_DOWN:\n-\t\tiface = ksmbd_find_netdev_name_iface_list(netdev->name);\n-\t\tif (iface && iface->state == IFACE_STATE_CONFIGURED) {\n-\t\t\tksmbd_debug(CONN, \"netdev-down event: netdev(%s) is going down\\n\",\n-\t\t\t\t\tiface->name);\n-\t\t\tkernel_sock_shutdown(iface->ksmbd_socket, SHUT_RDWR);\n-\t\t\ttcp_stop_kthread(iface->ksmbd_kthread);\n-\t\t\tiface->ksmbd_kthread = NULL;\n-\t\t\tsock_release(iface->ksmbd_socket);\n-\t\t\tiface->ksmbd_socket = NULL;\n-\n-\t\t\tiface->state = IFACE_STATE_DOWN;\n-\t\t\tbreak;\n-\t\t}\n-\t\tbreak;\n-\t}\n-\n-\treturn NOTIFY_DONE;\n-}\n-\n-static struct notifier_block ksmbd_netdev_notifier = {\n-\t.notifier_call = ksmbd_netdev_event,\n-};\n-\n-int ksmbd_tcp_init(void)\n-{\n-\tregister_netdevice_notifier(&ksmbd_netdev_notifier);\n-\n-\treturn 0;\n-}\n-\n-static void tcp_stop_kthread(struct task_struct *kthread)\n-{\n-\tint ret;\n-\n-\tif (!kthread)\n-\t\treturn;\n-\n-\tret = kthread_stop(kthread);\n-\tif (ret)\n-\t\tpr_err(\"failed to stop forker thread\\n\");\n-}\n-\n-void ksmbd_tcp_destroy(void)\n-{\n-\tstruct interface *iface, *tmp;\n-\n-\tunregister_netdevice_notifier(&ksmbd_netdev_notifier);\n-\n-\tlist_for_each_entry_safe(iface, tmp, &iface_list, entry) {\n-\t\tlist_del(&iface->entry);\n-\t\tkfree(iface->name);\n-\t\tkfree(iface);\n-\t}\n-}\n-\n-static struct interface *alloc_iface(char *ifname)\n-{\n-\tstruct interface *iface;\n-\n-\tif (!ifname)\n-\t\treturn NULL;\n-\n-\tiface = kzalloc_obj(struct interface, KSMBD_DEFAULT_GFP);\n-\tif (!iface) {\n-\t\tkfree(ifname);\n-\t\treturn NULL;\n-\t}\n-\n-\tiface->name = ifname;\n-\tiface->state = IFACE_STATE_DOWN;\n-\tlist_add(&iface->entry, &iface_list);\n-\treturn iface;\n-}\n-\n-int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz)\n-{\n-\tint sz = 0;\n-\n-\tif (!ifc_list_sz) {\n-\t\tbind_additional_ifaces = 1;\n-\t\treturn 0;\n-\t}\n-\n-\twhile (ifc_list_sz > 0) {\n-\t\tif (!alloc_iface(kstrdup(ifc_list, KSMBD_DEFAULT_GFP)))\n-\t\t\treturn -ENOMEM;\n-\n-\t\tsz = strlen(ifc_list);\n-\t\tif (!sz)\n-\t\t\tbreak;\n-\n-\t\tifc_list += sz + 1;\n-\t\tifc_list_sz -= (sz + 1);\n-\t}\n-\n-\tbind_additional_ifaces = 0;\n-\n-\treturn 0;\n-}\n-\n static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops = {\n \t.read\t\t= ksmbd_tcp_read,\n \t.writev\t\t= ksmbd_tcp_writev,\ndiff --git a/fs/smb/server/transport_tcp.h b/fs/smb/server/transport_tcp.h\nindex 1e51675ee1b2..d122e4b69d65 100644\n--- a/fs/smb/server/transport_tcp.h\n+++ b/fs/smb/server/transport_tcp.h\n@@ -6,10 +6,13 @@\n #ifndef __KSMBD_TRANSPORT_TCP_H__\n #define __KSMBD_TRANSPORT_TCP_H__\n \n-int ksmbd_tcp_set_interfaces(char *ifc_list, int ifc_list_sz);\n-struct interface *ksmbd_find_netdev_name_iface_list(char *netdev_name);\n+#include \"interface.h\"\n+\n void ksmbd_free_transport(struct ksmbd_transport *kt);\n int ksmbd_tcp_init(void);\n void ksmbd_tcp_destroy(void);\n+int ksmbd_tcp_create_socket(struct interface *iface);\n+void ksmbd_tcp_stop_kthread(struct task_struct *kthread);\n+void ksmbd_tcp_destroy_socket(struct socket *ksmbd_socket);\n \n #endif /* __KSMBD_TRANSPORT_TCP_H__ */\n", "prefixes": [ "v2", "05/11" ] }