Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2220581/?format=api
{ "id": 2220581, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2220581/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/3d447904e3a370f61d4d4fe8aaee8bfdbb299c9c.1775571957.git.metze@samba.org/", "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": "<3d447904e3a370f61d4d4fe8aaee8bfdbb299c9c.1775571957.git.metze@samba.org>", "date": "2026-04-07T14:46:33", "name": "[7/8] smb: client: make use of IPPROTO_SMBDIRECT sockets", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "d40de1f2ba5c27693a9fb9bd3704d172dc7b13a4", "submitter": { "id": 8149, "url": "http://patchwork.ozlabs.org/api/1.1/people/8149/?format=api", "name": "Stefan Metzmacher", "email": "metze@samba.org" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-cifs-client/patch/3d447904e3a370f61d4d4fe8aaee8bfdbb299c9c.1775571957.git.metze@samba.org/mbox/", "series": [ { "id": 498990, "url": "http://patchwork.ozlabs.org/api/1.1/series/498990/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-cifs-client/list/?series=498990", "date": "2026-04-07T14:46:28", "name": "smb: add kernel internal IPPROTO_SMBDIRECT", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/498990/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2220581/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2220581/checks/", "tags": {}, "headers": { "Return-Path": "\n <linux-cifs+bounces-10696-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 (3072-bit key;\n secure) header.d=samba.org header.i=@samba.org header.a=rsa-sha256\n header.s=42 header.b=Xx3RXmsa;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2600:3c04:e001:36c::12fc:5321; helo=tor.lore.kernel.org;\n envelope-from=linux-cifs+bounces-10696-incoming=patchwork.ozlabs.org@vger.kernel.org;\n receiver=patchwork.ozlabs.org)", "smtp.subspace.kernel.org;\n\tdkim=pass (3072-bit key) header.d=samba.org header.i=@samba.org\n header.b=\"Xx3RXmsa\"", "smtp.subspace.kernel.org;\n arc=none smtp.client-ip=144.76.82.148", "smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=samba.org", "smtp.subspace.kernel.org;\n spf=pass smtp.mailfrom=samba.org" ], "Received": [ "from tor.lore.kernel.org (tor.lore.kernel.org\n [IPv6:2600:3c04:e001:36c::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 4fqq380F61z1yD3\n\tfor <incoming@patchwork.ozlabs.org>; Wed, 08 Apr 2026 00:54:11 +1000 (AEST)", "from smtp.subspace.kernel.org (conduit.subspace.kernel.org\n [100.90.174.1])\n\tby tor.lore.kernel.org (Postfix) with ESMTP id 9CC5530ADE5D\n\tfor <incoming@patchwork.ozlabs.org>; Tue, 7 Apr 2026 14:48:04 +0000 (UTC)", "from localhost.localdomain (localhost.localdomain [127.0.0.1])\n\tby smtp.subspace.kernel.org (Postfix) with ESMTP id F054F320CD3;\n\tTue, 7 Apr 2026 14:47:55 +0000 (UTC)", "from hr2.samba.org (hr2.samba.org [144.76.82.148])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby smtp.subspace.kernel.org (Postfix) with ESMTPS id C211E31D75E;\n\tTue, 7 Apr 2026 14:47:49 +0000 (UTC)", "from [127.0.0.2] (localhost [127.0.0.1])\n\tby hr2.samba.org with esmtpsa\n (TLS1.3:ECDHE_SECP256R1__ECDSA_SECP256R1_SHA256__CHACHA20_POLY1305:256)\n\t(Exim)\n\tid 1wA7iT-00000007WSV-48OV;\n\tTue, 07 Apr 2026 14:47:46 +0000" ], "ARC-Seal": "i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116;\n\tt=1775573275; cv=none;\n b=PSprweTeR7ZGrcuqxg1/jK3YqSKI+UoeZrGl/fBe4hcQv77Moggo5oEcy0AroedjLbP2jOvsaENYV+sjVu1cKeJH4hnVfS3nO+LIU9zzXbLLlwE/G/BH00FSORDnnc207zOjYH3VeZzk6HDTX2VRkEIVQhgH5p4QtQy0Vjg/r18=", "ARC-Message-Signature": "i=1; a=rsa-sha256; d=subspace.kernel.org;\n\ts=arc-20240116; t=1775573275; c=relaxed/simple;\n\tbh=R2fi9jfNGCmEa2UTj605KIX/CDVli+KSD2VOhFhUuTI=;\n\th=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References:\n\t MIME-Version;\n b=quQ/P7u30vuIYx2SGynmzvhEDySPyenNqZ18ROK5Ec6xUK4ZGBLzFg8qPhM2jE1yRe7yRqis02R1C57sKvA9qamqW/dbHSwQDFCDX83s8xlwz/qKbVzhpSBqMF76nQVZ7yvSCBoUHIBzGFtnNhxI3HgrPvXpUtNOUYhcuFUuAPc=", "ARC-Authentication-Results": "i=1; smtp.subspace.kernel.org;\n dmarc=pass (p=quarantine dis=none) header.from=samba.org;\n spf=pass smtp.mailfrom=samba.org;\n dkim=pass (3072-bit key) header.d=samba.org header.i=@samba.org\n header.b=Xx3RXmsa; arc=none smtp.client-ip=144.76.82.148", "DKIM-Signature": "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=samba.org;\n\ts=42; h=Message-ID:Date:Cc:To:From;\n\tbh=4qor25fDclrX4Tl2iTvjhE+2WdvSIagxoKLaDTejWrY=; b=Xx3RXmsaYFifQqQsF6rXmATthr\n\tmnpGPXyvBxQAstinyZJzYrgroWI11pW/bFFwyc0SRAqoXQVr5dIeULjITyYYkS6Uhj2hX1p03P1Wt\n\tg9huFfo5PPryvujlvRt8BmR3T9vn2T8VlTNhwifyIcg1dCLcQx3QDYRFaCampTfaEBtigChA1IC3X\n\te2W3UDQB7HTCmjDD4mqYv8xIibupEtkauUR+ksdL42G6OflaE7z56Bg45esmyPFTr+iPnL+7DzfAc\n\t+xBrPcKG2kpt15rTBGyqEaRNCg0uZUzCYqcCPrlJgC9IZZWTKZaW9KTOOAK5/gk9QB27pkT+pS+m4\n\toZk4k/bwMziRqKiJrntrgapPiKAumGnfPzEwU2jT1gYSGkeCKZHjXw5f6kUykUkRMDuDAdBnP0ldV\n\tYQ/wIwQm69lFp7QNnM/3LK9k7zg8MoCs2TzyfN1wqKSt1p5WGdNw9e/DNjY0zEmAv48Er26OL5KSc\n\tJ8hZNlTkNV0t/FbVRxqBNmjg;", "From": "Stefan Metzmacher <metze@samba.org>", "To": "linux-cifs@vger.kernel.org,\n\tsamba-technical@lists.samba.org", "Cc": "metze@samba.org,\n\tSteve French <smfrench@gmail.com>,\n\tTom Talpey <tom@talpey.com>,\n\tLong Li <longli@microsoft.com>,\n\tNamjae Jeon <linkinjeon@kernel.org>,\n\tDavid Howells <dhowells@redhat.com>,\n\tHenrique Carvalho <henrique.carvalho@suse.com>,\n\t\"David S . Miller\" <davem@davemloft.net>,\n\tEric Dumazet <edumazet@google.com>,\n\tJakub Kicinski <kuba@kernel.org>,\n\tPaolo Abeni <pabeni@redhat.com>,\n\tSimon Horman <horms@kernel.org>,\n\tKuniyuki Iwashima <kuniyu@google.com>,\n\tWillem de Bruijn <willemb@google.com>,\n\tnetdev@vger.kernel.org,\n\tXin Long <lucien.xin@gmail.com>,\n\tquic@lists.linux.dev,\n\tlinux-rdma@vger.kernel.org,\n\tlinux-kernel@vger.kernel.org", "Subject": "[PATCH 7/8] smb: client: make use of IPPROTO_SMBDIRECT sockets", "Date": "Tue, 7 Apr 2026 16:46:33 +0200", "Message-ID": "\n <3d447904e3a370f61d4d4fe8aaee8bfdbb299c9c.1775571957.git.metze@samba.org>", "X-Mailer": "git-send-email 2.43.0", "In-Reply-To": "<cover.1775571957.git.metze@samba.org>", "References": "<cover.1775571957.git.metze@samba.org>", "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": "This reduces the function calls for special smbdirect features to\n- smbdirect_socket_from_sock()\n- smbdirect_socket_set_logging()\n- smbdirect_socket_set_initial_parameters()\n- smbdirect_socket_set_kernel_settings()\n- smbdirect_socket_get_current_parameters()\n- smbdirect_connection_is_connected()\n- smbdirect_connection_send_single_iter()\n- smbdirect_connection_send_wait_zero_pending()\n- smbdirect_connection_register_mr_io()\n- smbdirect_mr_io_fill_buffer_descriptor()\n- smbdirect_connection_deregister_mr_io()\n- smbdirect_connection_legacy_debug_proc_show()\n\nIn future with modifications from David Howells\nwe'll also be able to use sock_sendmsg() and avoid\ndirect calls to smbdirect_connection_send_single_iter() and\nsmbdirect_connection_send_wait_zero_pending().\n\nThis will also make it easier to implement the QUIC\ntransport Henrique Carvalho is working on.\n\nIn the end the core smb handling should just make\nuse of a SOCK_STREAM socket, after the initial setup.\n\nThere's still a way to go, but almost all changes\nwill be done within the smbdirect code, e.g.\nadding MSG_SPLICE_PAGES support or\nsplice_read/read_sock/read_skb.\n\nBut it's a good start, which will make changes\nmuch easier.\n\nCc: Steve French <smfrench@gmail.com>\nCc: Tom Talpey <tom@talpey.com>\nCc: Long Li <longli@microsoft.com>\nCc: Namjae Jeon <linkinjeon@kernel.org>\nCc: David Howells <dhowells@redhat.com>\nCc: Henrique Carvalho <henrique.carvalho@suse.com>\nCc: linux-cifs@vger.kernel.org\nCc: samba-technical@lists.samba.org\nCc: David S. Miller <davem@davemloft.net>\nCc: Eric Dumazet <edumazet@google.com>\nCc: Jakub Kicinski <kuba@kernel.org>\nCc: Paolo Abeni <pabeni@redhat.com>\nCc: Simon Horman <horms@kernel.org>\nCc: Kuniyuki Iwashima <kuniyu@google.com>\nCc: Willem de Bruijn <willemb@google.com>\nCc: netdev@vger.kernel.org\nCc: Xin Long <lucien.xin@gmail.com>\nCc: quic@lists.linux.dev\nCc: linux-rdma@vger.kernel.org\nCc: linux-kernel@vger.kernel.org\nSigned-off-by: Stefan Metzmacher <metze@samba.org>\n---\n fs/smb/client/cifs_debug.c | 2 +-\n fs/smb/client/cifsfs.c | 2 +-\n fs/smb/client/cifsglob.h | 7 +-\n fs/smb/client/connect.c | 123 +++++++++--------\n fs/smb/client/file.c | 8 +-\n fs/smb/client/sess.c | 4 +-\n fs/smb/client/smb2ops.c | 8 +-\n fs/smb/client/smb2pdu.c | 10 +-\n fs/smb/client/smbdirect.c | 275 +++++++++++--------------------------\n fs/smb/client/smbdirect.h | 27 +---\n fs/smb/client/transport.c | 2 +-\n 11 files changed, 170 insertions(+), 298 deletions(-)", "diff": "diff --git a/fs/smb/client/cifs_debug.c b/fs/smb/client/cifs_debug.c\nindex 0691d2a3e04b..70f30b1f8cda 100644\n--- a/fs/smb/client/cifs_debug.c\n+++ b/fs/smb/client/cifs_debug.c\n@@ -481,7 +481,7 @@ static int cifs_debug_data_proc_show(struct seq_file *m, void *v)\n \n \t\tseq_printf(m, \"\\nServer capabilities: 0x%x\", server->capabilities);\n \n-\t\tif (server->rdma)\n+\t\tif (cifs_rdma_enabled(server))\n \t\t\tseq_printf(m, \"\\nRDMA \");\n \t\tseq_printf(m, \"\\nTCP status: %d Instance: %d\"\n \t\t\t\t\"\\nLocal Users To Server: %d SecMode: 0x%x Req On Wire: %d\",\ndiff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c\nindex 32d0305a1239..12986050e16c 100644\n--- a/fs/smb/client/cifsfs.c\n+++ b/fs/smb/client/cifsfs.c\n@@ -529,7 +529,7 @@ cifs_show_address(struct seq_file *s, struct TCP_Server_Info *server)\n \tdefault:\n \t\tseq_puts(s, \"(unknown)\");\n \t}\n-\tif (server->rdma)\n+\tif (cifs_rdma_enabled(server))\n \t\tseq_puts(s, \",rdma\");\n }\n \ndiff --git a/fs/smb/client/cifsglob.h b/fs/smb/client/cifsglob.h\nindex 709e96e07791..f7b62bcaadd9 100644\n--- a/fs/smb/client/cifsglob.h\n+++ b/fs/smb/client/cifsglob.h\n@@ -35,6 +35,7 @@\n #define SMB_PATH_MAX 260\n #define CIFS_PORT 445\n #define RFC1001_PORT 139\n+#define SMBD_IWARP_PORT 5445\n \n /*\n * The sizes of various internal tables and strings\n@@ -759,10 +760,8 @@ struct TCP_Server_Info {\n \tbool\tsec_mskerberos;\t\t/* supports legacy MS Kerberos */\n \tbool\tsec_iakerb;\t\t/* supports pass-through auth for Kerberos (krb5 proxy) */\n \tbool\tlarge_buf;\t\t/* is current buffer large? */\n-\t/* use SMBD connection instead of socket */\n-\tbool\trdma;\n-\t/* point to the SMBD connection if RDMA is used instead of socket */\n-\tstruct smbd_connection *smbd_conn;\n+\tint\tipproto; /* IPPROTO_TCP or IPOROTO_SMBDIRECT */\n+#define cifs_rdma_enabled(__server)\t((__server)->ipproto == IPPROTO_SMBDIRECT)\n \tstruct delayed_work\techo; /* echo ping workqueue job */\n \tchar\t*smallbuf;\t/* pointer to current \"small\" buffer */\n \tchar\t*bigbuf;\t/* pointer to current \"big\" buffer */\ndiff --git a/fs/smb/client/connect.c b/fs/smb/client/connect.c\nindex 69b38f0ccf2b..d42abe1d3772 100644\n--- a/fs/smb/client/connect.c\n+++ b/fs/smb/client/connect.c\n@@ -313,8 +313,6 @@ cifs_abort_connection(struct TCP_Server_Info *server)\n \t\t\t server->ssocket->flags);\n \t\tsock_release(server->ssocket);\n \t\tserver->ssocket = NULL;\n-\t} else if (cifs_rdma_enabled(server)) {\n-\t\tsmbd_destroy(server);\n \t}\n \tserver->sequence_number = 0;\n \tserver->session_estab = false;\n@@ -408,10 +406,7 @@ static int __cifs_reconnect(struct TCP_Server_Info *server,\n \t\t\tcifs_dbg(FYI, \"%s: reconn_set_ipaddr_from_hostname: rc=%d\\n\", __func__, rc);\n \t\t}\n \n-\t\tif (cifs_rdma_enabled(server))\n-\t\t\trc = smbd_reconnect(server);\n-\t\telse\n-\t\t\trc = generic_ip_connect(server);\n+\t\trc = generic_ip_connect(server);\n \t\tif (rc) {\n \t\t\tcifs_server_unlock(server);\n \t\t\tcifs_dbg(FYI, \"%s: reconnect error %d\\n\", __func__, rc);\n@@ -468,10 +463,7 @@ static int __reconnect_target_locked(struct TCP_Server_Info *server,\n \t\tcifs_dbg(FYI, \"%s: reconn_set_ipaddr_from_hostname: rc=%d\\n\", __func__, rc);\n \t}\n \t/* Reconnect the socket */\n-\tif (cifs_rdma_enabled(server))\n-\t\trc = smbd_reconnect(server);\n-\telse\n-\t\trc = generic_ip_connect(server);\n+\trc = generic_ip_connect(server);\n \n \treturn rc;\n }\n@@ -746,10 +738,7 @@ cifs_readv_from_socket(struct TCP_Server_Info *server, struct msghdr *smb_msg)\n \n \t\tif (server_unresponsive(server))\n \t\t\treturn -ECONNABORTED;\n-\t\tif (cifs_rdma_enabled(server) && server->smbd_conn)\n-\t\t\tlength = smbd_recv(server->smbd_conn, smb_msg);\n-\t\telse\n-\t\t\tlength = sock_recvmsg(server->ssocket, smb_msg, 0);\n+\t\tlength = sock_recvmsg(server->ssocket, smb_msg, 0);\n \n \t\tspin_lock(&server->srv_lock);\n \t\tif (server->tcpStatus == CifsExiting) {\n@@ -1088,8 +1077,6 @@ clean_demultiplex_info(struct TCP_Server_Info *server)\n \twake_up_all(&server->request_q);\n \t/* give those requests time to exit */\n \tmsleep(125);\n-\tif (cifs_rdma_enabled(server))\n-\t\tsmbd_destroy(server);\n \tif (server->ssocket) {\n \t\tsock_release(server->ssocket);\n \t\tserver->ssocket = NULL;\n@@ -1542,7 +1529,7 @@ match_port(struct TCP_Server_Info *server, struct sockaddr *addr)\n \t__be16 port, *sport;\n \n \t/* SMBDirect manages its own ports, don't match it here */\n-\tif (server->rdma)\n+\tif (cifs_rdma_enabled(server))\n \t\treturn true;\n \n \tswitch (addr->sa_family) {\n@@ -1649,7 +1636,7 @@ static int match_server(struct TCP_Server_Info *server,\n \tif (server->echo_interval != ctx->echo_interval * HZ)\n \t\treturn 0;\n \n-\tif (server->rdma != ctx->rdma)\n+\tif (cifs_rdma_enabled(server) != ctx->rdma)\n \t\treturn 0;\n \n \tif (server->ignore_signature != ctx->ignore_signature)\n@@ -1791,7 +1778,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,\n \ttcp_ses->noblocksnd = ctx->noblocksnd || ctx->rootfs;\n \ttcp_ses->noautotune = ctx->noautotune;\n \ttcp_ses->tcp_nodelay = ctx->sockopt_tcp_nodelay;\n-\ttcp_ses->rdma = ctx->rdma;\n+\ttcp_ses->ipproto = ctx->rdma ? IPPROTO_SMBDIRECT : IPPROTO_TCP;\n \ttcp_ses->in_flight = 0;\n \ttcp_ses->max_in_flight = 0;\n \ttcp_ses->credits = 1;\n@@ -1844,29 +1831,18 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,\n \t++tcp_ses->srv_count;\n \ttcp_ses->echo_interval = ctx->echo_interval * HZ;\n \n-\tif (tcp_ses->rdma) {\n-#ifndef CONFIG_CIFS_SMB_DIRECT\n-\t\tcifs_dbg(VFS, \"CONFIG_CIFS_SMB_DIRECT is not enabled\\n\");\n-\t\trc = -ENOENT;\n-\t\tgoto out_err_crypto_release;\n-#endif\n-\t\ttcp_ses->smbd_conn = smbd_get_connection(\n-\t\t\ttcp_ses, (struct sockaddr *)&ctx->dstaddr);\n-\t\tif (tcp_ses->smbd_conn) {\n-\t\t\tcifs_dbg(VFS, \"RDMA transport established\\n\");\n-\t\t\trc = 0;\n-\t\t\tgoto smbd_connected;\n-\t\t} else {\n+\trc = ip_connect(tcp_ses);\n+\tif (rc < 0) {\n+\t\tif (cifs_rdma_enabled(tcp_ses) && rc == -EPROTONOSUPPORT) {\n+\t\t\tcifs_dbg(VFS, \"CONFIG_CIFS_SMB_DIRECT is not enabled\\n\");\n \t\t\trc = -ENOENT;\n \t\t\tgoto out_err_crypto_release;\n \t\t}\n-\t}\n-\trc = ip_connect(tcp_ses);\n-\tif (rc < 0) {\n \t\tcifs_dbg(VFS, \"Error connecting to socket. Aborting operation.\\n\");\n \t\tgoto out_err_crypto_release;\n \t}\n-smbd_connected:\n+\tif (cifs_rdma_enabled(tcp_ses))\n+\t\tcifs_dbg(VFS, \"RDMA transport established\\n\");\n \t/*\n \t * since we're in a cifs function already, we know that\n \t * this will succeed. No need for try_module_get().\n@@ -3331,6 +3307,7 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \tstruct sockaddr *saddr;\n \tstruct socket *socket;\n \tint slen, sfamily;\n+\tconst char *pname = cifs_rdma_enabled(server) ? \"smbdirect\" : \"tcp\";\n \t__be16 sport;\n \tint rc = 0;\n \n@@ -3342,28 +3319,32 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \t\tsport = ipv6->sin6_port;\n \t\tslen = sizeof(struct sockaddr_in6);\n \t\tsfamily = AF_INET6;\n-\t\tcifs_dbg(FYI, \"%s: connecting to [%pI6]:%d\\n\", __func__, &ipv6->sin6_addr,\n-\t\t\t\tntohs(sport));\n+\t\tcifs_dbg(FYI, \"%s: connecting with %s to [%pI6]:%d\\n\",\n+\t\t\t __func__, pname, &ipv6->sin6_addr, ntohs(sport));\n \t} else {\n \t\tstruct sockaddr_in *ipv4 = (struct sockaddr_in *)&server->dstaddr;\n \n \t\tsport = ipv4->sin_port;\n \t\tslen = sizeof(struct sockaddr_in);\n \t\tsfamily = AF_INET;\n-\t\tcifs_dbg(FYI, \"%s: connecting to %pI4:%d\\n\", __func__, &ipv4->sin_addr,\n-\t\t\t\tntohs(sport));\n+\t\tcifs_dbg(FYI, \"%s: connecting with %s to %pI4:%d\\n\",\n+\t\t\t __func__, pname, &ipv4->sin_addr, ntohs(sport));\n \t}\n \n \tif (server->ssocket) {\n-\t\tsocket = server->ssocket;\n-\t} else {\n+\t\tsock_release(server->ssocket);\n+\t\tserver->ssocket = NULL;\n+\t}\n+\n+\t{\n \t\tstruct net *net = cifs_net_ns(server);\n \t\tstruct sock *sk;\n \n \t\trc = sock_create_kern(net, sfamily, SOCK_STREAM,\n-\t\t\t\t IPPROTO_TCP, &server->ssocket);\n+\t\t\t\t server->ipproto, &server->ssocket);\n \t\tif (rc < 0) {\n-\t\t\tcifs_server_dbg(VFS, \"Error %d creating socket\\n\", rc);\n+\t\t\tcifs_server_dbg(VFS, \"Error %d creating %s socket\\n\",\n+\t\t\t\t\trc, pname);\n \t\t\treturn rc;\n \t\t}\n \n@@ -3371,7 +3352,7 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \t\tsk_net_refcnt_upgrade(sk);\n \n \t\t/* BB other socket options to set KEEPALIVE, NODELAY? */\n-\t\tcifs_dbg(FYI, \"Socket created\\n\");\n+\t\tcifs_dbg(FYI, \"%s socket created\\n\", pname);\n \t\tsocket = server->ssocket;\n \t\tsocket->sk->sk_allocation = GFP_NOFS;\n \t\tsocket->sk->sk_use_task_frag = false;\n@@ -3382,8 +3363,10 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \t}\n \n \trc = bind_socket(server);\n-\tif (rc < 0)\n-\t\treturn rc;\n+\tif (rc < 0) {\n+\t\tcifs_dbg(FYI, \"Error %d bind_socket() %s\\n\", rc, pname);\n+\t\tgoto close_socket;\n+\t}\n \n \t/*\n \t * Eventually check for other socket options to change from\n@@ -3404,6 +3387,17 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \tif (server->tcp_nodelay)\n \t\ttcp_sock_set_nodelay(socket->sk);\n \n+\tswitch (server->ipproto) {\n+\tcase IPPROTO_SMBDIRECT:\n+\t\trc = smbd_prepare_socket(server, ntohs(sport));\n+\t\tif (rc < 0) {\n+\t\t\tcifs_dbg(FYI, \"Error %d from smbd_prepare_socket(port=%u)\\n\",\n+\t\t\t\t rc, ntohs(sport));\n+\t\t\tgoto close_socket;\n+\t\t}\n+\t\tbreak;\n+\t}\n+\n \tcifs_dbg(FYI, \"sndbuf %d rcvbuf %d rcvtimeo 0x%lx\\n\",\n \t\t socket->sk->sk_sndbuf,\n \t\t socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);\n@@ -3418,11 +3412,8 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \tif (server->noblockcnt && rc == -EINPROGRESS)\n \t\trc = 0;\n \tif (rc < 0) {\n-\t\tcifs_dbg(FYI, \"Error %d connecting to server\\n\", rc);\n-\t\ttrace_smb3_connect_err(server->hostname, server->conn_id, &server->dstaddr, rc);\n-\t\tsock_release(socket);\n-\t\tserver->ssocket = NULL;\n-\t\treturn rc;\n+\t\tcifs_dbg(FYI, \"Error %d connecting with %s to server\\n\", rc, pname);\n+\t\tgoto close_socket;\n \t}\n \ttrace_smb3_connect_done(server->hostname, server->conn_id, &server->dstaddr);\n \n@@ -3434,9 +3425,20 @@ generic_ip_connect(struct TCP_Server_Info *server)\n \t */\n \tif (server->with_rfc1001 ||\n \t server->rfc1001_sessinit == 1 ||\n-\t (server->rfc1001_sessinit == -1 && sport == htons(RFC1001_PORT)))\n+\t (server->rfc1001_sessinit == -1 && sport == htons(RFC1001_PORT))) {\n \t\trc = ip_rfc1001_connect(server);\n+\t\tif (rc < 0) {\n+\t\t\tcifs_dbg(FYI, \"Error %d from ip_rfc1001_connect\\n\", rc);\n+\t\t\tgoto close_socket;\n+\t\t}\n+\t}\n+\n+\treturn rc;\n \n+close_socket:\n+\ttrace_smb3_connect_err(server->hostname, server->conn_id, &server->dstaddr, rc);\n+\tsock_release(socket);\n+\tserver->ssocket = NULL;\n \treturn rc;\n }\n \n@@ -3446,6 +3448,13 @@ ip_connect(struct TCP_Server_Info *server)\n \t__be16 *sport;\n \tstruct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&server->dstaddr;\n \tstruct sockaddr_in *addr = (struct sockaddr_in *)&server->dstaddr;\n+\tu16 port1 = CIFS_PORT;\n+\tu16 port2 = RFC1001_PORT;\n+\n+\tif (cifs_rdma_enabled(server)) {\n+\t\tport1 = SMBD_IWARP_PORT;\n+\t\tport2 = CIFS_PORT;\n+\t}\n \n \tif (server->dstaddr.ss_family == AF_INET6)\n \t\tsport = &addr6->sin6_port;\n@@ -3455,15 +3464,15 @@ ip_connect(struct TCP_Server_Info *server)\n \tif (*sport == 0) {\n \t\tint rc;\n \n-\t\t/* try with 445 port at first */\n-\t\t*sport = htons(CIFS_PORT);\n+\t\t/* try with port1 at first */\n+\t\t*sport = htons(port1);\n \n \t\trc = generic_ip_connect(server);\n \t\tif (rc >= 0)\n \t\t\treturn rc;\n \n-\t\t/* if it failed, try with 139 port */\n-\t\t*sport = htons(RFC1001_PORT);\n+\t\t/* if it failed, try with port2 */\n+\t\t*sport = htons(port2);\n \t}\n \n \treturn generic_ip_connect(server);\ndiff --git a/fs/smb/client/file.c b/fs/smb/client/file.c\nindex a69e05f86d7e..8ca9f60ff429 100644\n--- a/fs/smb/client/file.c\n+++ b/fs/smb/client/file.c\n@@ -97,9 +97,9 @@ static void cifs_prepare_write(struct netfs_io_subrequest *subreq)\n \t\t\t cifs_trace_rw_credits_write_prepare);\n \n #ifdef CONFIG_CIFS_SMB_DIRECT\n-\tif (server->smbd_conn) {\n+\tif (cifs_rdma_enabled(server)) {\n \t\tconst struct smbdirect_socket_parameters *sp =\n-\t\t\tsmbd_get_parameters(server->smbd_conn);\n+\t\t\tsmbd_get_parameters(server);\n \n \t\tstream->sreq_max_segs = sp->max_frmr_depth;\n \t}\n@@ -191,9 +191,9 @@ static int cifs_prepare_read(struct netfs_io_subrequest *subreq)\n \t\t\t cifs_trace_rw_credits_read_submit);\n \n #ifdef CONFIG_CIFS_SMB_DIRECT\n-\tif (server->smbd_conn) {\n+\tif (cifs_rdma_enabled(server)) {\n \t\tconst struct smbdirect_socket_parameters *sp =\n-\t\t\tsmbd_get_parameters(server->smbd_conn);\n+\t\t\tsmbd_get_parameters(server);\n \n \t\trreq->io_streams[0].sreq_max_segs = sp->max_frmr_depth;\n \t}\ndiff --git a/fs/smb/client/sess.c b/fs/smb/client/sess.c\nindex 698bd27119ae..9e79439002e6 100644\n--- a/fs/smb/client/sess.c\n+++ b/fs/smb/client/sess.c\n@@ -207,7 +207,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)\n \t\tlist_for_each_entry_safe_from(iface, niface, &ses->iface_list,\n \t\t\t\t iface_head) {\n \t\t\t/* do not mix rdma and non-rdma interfaces */\n-\t\t\tif (iface->rdma_capable != ses->server->rdma)\n+\t\t\tif (iface->rdma_capable != cifs_rdma_enabled(ses->server))\n \t\t\t\tcontinue;\n \n \t\t\t/* skip ifaces that are unusable */\n@@ -395,7 +395,7 @@ cifs_chan_update_iface(struct cifs_ses *ses, struct TCP_Server_Info *server)\n \t\t}\n \n \t\t/* do not mix rdma and non-rdma interfaces */\n-\t\tif (iface->rdma_capable != server->rdma)\n+\t\tif (iface->rdma_capable != cifs_rdma_enabled(server))\n \t\t\tcontinue;\n \n \t\tif (!iface->is_active ||\ndiff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c\nindex 509fcea28a42..208797de0c31 100644\n--- a/fs/smb/client/smb2ops.c\n+++ b/fs/smb/client/smb2ops.c\n@@ -503,9 +503,9 @@ smb3_negotiate_wsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)\n \twsize = ctx->got_wsize ? ctx->vol_wsize : SMB3_DEFAULT_IOSIZE;\n \twsize = min_t(unsigned int, wsize, server->max_write);\n #ifdef CONFIG_CIFS_SMB_DIRECT\n-\tif (server->rdma) {\n+\tif (cifs_rdma_enabled(server)) {\n \t\tconst struct smbdirect_socket_parameters *sp =\n-\t\t\tsmbd_get_parameters(server->smbd_conn);\n+\t\t\tsmbd_get_parameters(server);\n \n \t\tif (server->sign)\n \t\t\t/*\n@@ -554,9 +554,9 @@ smb3_negotiate_rsize(struct cifs_tcon *tcon, struct smb3_fs_context *ctx)\n \trsize = ctx->got_rsize ? ctx->vol_rsize : SMB3_DEFAULT_IOSIZE;\n \trsize = min_t(unsigned int, rsize, server->max_read);\n #ifdef CONFIG_CIFS_SMB_DIRECT\n-\tif (server->rdma) {\n+\tif (cifs_rdma_enabled(server)) {\n \t\tconst struct smbdirect_socket_parameters *sp =\n-\t\t\tsmbd_get_parameters(server->smbd_conn);\n+\t\t\tsmbd_get_parameters(server);\n \n \t\tif (server->sign)\n \t\t\t/*\ndiff --git a/fs/smb/client/smb2pdu.c b/fs/smb/client/smb2pdu.c\nindex 957aca2222b5..e954c75b36da 100644\n--- a/fs/smb/client/smb2pdu.c\n+++ b/fs/smb/client/smb2pdu.c\n@@ -4472,7 +4472,7 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)\n \t\treturn false;\n \n \t/* we can only offload on an rdma connection */\n-\tif (!server->rdma || !server->smbd_conn)\n+\tif (!cifs_rdma_enabled(server))\n \t\treturn false;\n \n \t/* we don't support signed offload yet */\n@@ -4483,6 +4483,10 @@ static inline bool smb3_use_rdma_offload(struct cifs_io_parms *io_parms)\n \tif (smb3_encryption_required(tcon))\n \t\treturn false;\n \n+\t/* this implicitly sets up server->rdma_readwrite_threshold */\n+\tif (!smbd_get_parameters(server))\n+\t\treturn false;\n+\n \t/* offload also has its overhead, so only do it if desired */\n \tif (io_parms->length < server->rdma_readwrite_threshold)\n \t\treturn false;\n@@ -4540,7 +4544,7 @@ smb2_new_read_req(void **buf, unsigned int *total_len,\n \t\tstruct smbdirect_buffer_descriptor_v1 *v1;\n \t\tbool need_invalidate = server->dialect == SMB30_PROT_ID;\n \n-\t\trdata->mr = smbd_register_mr(server->smbd_conn, &rdata->subreq.io_iter,\n+\t\trdata->mr = smbd_register_mr(server, &rdata->subreq.io_iter,\n \t\t\t\t\t true, need_invalidate);\n \t\tif (!rdata->mr)\n \t\t\treturn -EAGAIN;\n@@ -5134,7 +5138,7 @@ smb2_async_writev(struct cifs_io_subrequest *wdata)\n \t\tstruct smbdirect_buffer_descriptor_v1 *v1;\n \t\tbool need_invalidate = server->dialect == SMB30_PROT_ID;\n \n-\t\twdata->mr = smbd_register_mr(server->smbd_conn, &wdata->subreq.io_iter,\n+\t\twdata->mr = smbd_register_mr(server, &wdata->subreq.io_iter,\n \t\t\t\t\t false, need_invalidate);\n \t\tif (!wdata->mr) {\n \t\t\trc = -EAGAIN;\ndiff --git a/fs/smb/client/smbdirect.c b/fs/smb/client/smbdirect.c\nindex 9e67adcdc7d3..7d4fa896efc0 100644\n--- a/fs/smb/client/smbdirect.c\n+++ b/fs/smb/client/smbdirect.c\n@@ -11,10 +11,6 @@\n #include \"smb2proto.h\"\n #include \"../common/smbdirect/smbdirect_public.h\"\n \n-/* Port numbers for SMBD transport */\n-#define SMB_PORT\t445\n-#define SMBD_PORT\t5445\n-\n /* Address lookup and resolve timeout in ms */\n #define RDMA_RESOLVE_TIMEOUT\t5000\n \n@@ -81,18 +77,9 @@ int rdma_readwrite_threshold = 4096;\n /* Transport logging functions\n * Logging are defined as classes. They can be OR'ed to define the actual\n * logging level via module parameter smbd_logging_class\n- * e.g. cifs.smbd_logging_class=0xa0 will log all log_rdma_recv() and\n- * log_rdma_event()\n+ * e.g. cifs.smbd_logging_class=0xa0 will log all SMBDIRECT_LOG_RDMA_RECV and\n+ * SMBDIRECT_LOG_RDMA_EVENT\n */\n-#define LOG_OUTGOING\t\t\t0x1\n-#define LOG_INCOMING\t\t\t0x2\n-#define LOG_READ\t\t\t0x4\n-#define LOG_WRITE\t\t\t0x8\n-#define LOG_RDMA_SEND\t\t\t0x10\n-#define LOG_RDMA_RECV\t\t\t0x20\n-#define LOG_KEEP_ALIVE\t\t\t0x40\n-#define LOG_RDMA_EVENT\t\t\t0x80\n-#define LOG_RDMA_MR\t\t\t0x100\n static unsigned int smbd_logging_class;\n module_param(smbd_logging_class, uint, 0644);\n MODULE_PARM_DESC(smbd_logging_class,\n@@ -114,17 +101,6 @@ static bool smbd_logging_needed(struct smbdirect_socket *sc,\n \tBUILD_BUG_SAME(ERR);\n \tBUILD_BUG_SAME(INFO);\n #undef BUILD_BUG_SAME\n-#define BUILD_BUG_SAME(x) BUILD_BUG_ON(x != SMBDIRECT_ ##x)\n-\tBUILD_BUG_SAME(LOG_OUTGOING);\n-\tBUILD_BUG_SAME(LOG_INCOMING);\n-\tBUILD_BUG_SAME(LOG_READ);\n-\tBUILD_BUG_SAME(LOG_WRITE);\n-\tBUILD_BUG_SAME(LOG_RDMA_SEND);\n-\tBUILD_BUG_SAME(LOG_RDMA_RECV);\n-\tBUILD_BUG_SAME(LOG_KEEP_ALIVE);\n-\tBUILD_BUG_SAME(LOG_RDMA_EVENT);\n-\tBUILD_BUG_SAME(LOG_RDMA_MR);\n-#undef BUILD_BUG_SAME\n \n \tif (lvl <= smbd_logging_level || cls & smbd_logging_class)\n \t\treturn true;\n@@ -148,22 +124,7 @@ do {\t\t\t\t\t\t\t\t\t\\\n \t\tcifs_dbg(VFS, \"%s:%d \" fmt, __func__, __LINE__, ##args);\\\n } while (0)\n \n-#define log_outgoing(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_OUTGOING, fmt, ##args)\n-#define log_incoming(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_INCOMING, fmt, ##args)\n-#define log_read(level, fmt, args...)\tlog_rdma(level, LOG_READ, fmt, ##args)\n-#define log_write(level, fmt, args...)\tlog_rdma(level, LOG_WRITE, fmt, ##args)\n-#define log_rdma_send(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_RDMA_SEND, fmt, ##args)\n-#define log_rdma_recv(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_RDMA_RECV, fmt, ##args)\n-#define log_keep_alive(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_KEEP_ALIVE, fmt, ##args)\n-#define log_rdma_event(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_RDMA_EVENT, fmt, ##args)\n-#define log_rdma_mr(level, fmt, args...) \\\n-\t\tlog_rdma(level, LOG_RDMA_MR, fmt, ##args)\n+#define log_write(level, fmt, args...)\tlog_rdma(level, SMBDIRECT_LOG_WRITE, fmt, ##args)\n \n static int smbd_post_send_full_iter(struct smbdirect_socket *sc,\n \t\t\t\t struct smbdirect_send_batch *batch,\n@@ -195,82 +156,24 @@ static int smbd_post_send_full_iter(struct smbdirect_socket *sc,\n \treturn bytes;\n }\n \n-/*\n- * Destroy the transport and related RDMA and memory resources\n- * Need to go through all the pending counters and make sure on one is using\n- * the transport while it is destroyed\n- */\n-void smbd_destroy(struct TCP_Server_Info *server)\n-{\n-\tstruct smbd_connection *info = server->smbd_conn;\n-\n-\tif (!info) {\n-\t\tlog_rdma_event(INFO, \"rdma session already destroyed\\n\");\n-\t\treturn;\n-\t}\n-\n-\tsmbdirect_socket_release(info->socket);\n-\n-\tkfree(info);\n-\tserver->smbd_conn = NULL;\n-}\n-\n-/*\n- * Reconnect this SMBD connection, called from upper layer\n- * return value: 0 on success, or actual error code\n- */\n-int smbd_reconnect(struct TCP_Server_Info *server)\n-{\n-\tlog_rdma_event(INFO, \"reconnecting rdma session\\n\");\n-\n-\tif (!server->smbd_conn) {\n-\t\tlog_rdma_event(INFO, \"rdma session already destroyed\\n\");\n-\t\tgoto create_conn;\n-\t}\n-\n-\t/*\n-\t * This is possible if transport is disconnected and we haven't received\n-\t * notification from RDMA, but upper layer has detected timeout\n-\t */\n-\tlog_rdma_event(INFO, \"disconnecting transport\\n\");\n-\tsmbd_destroy(server);\n-\n-create_conn:\n-\tlog_rdma_event(INFO, \"creating rdma session\\n\");\n-\tserver->smbd_conn = smbd_get_connection(\n-\t\tserver, (struct sockaddr *) &server->dstaddr);\n-\n-\tif (server->smbd_conn) {\n-\t\tcifs_dbg(VFS, \"RDMA transport re-established\\n\");\n-\t\ttrace_smb3_smbd_connect_done(server->hostname, server->conn_id, &server->dstaddr);\n-\t\treturn 0;\n-\t}\n-\ttrace_smb3_smbd_connect_err(server->hostname, server->conn_id, &server->dstaddr);\n-\treturn -ENOENT;\n-}\n-\n /* Create a SMBD connection, called by upper layer */\n-static struct smbd_connection *_smbd_get_connection(\n-\tstruct TCP_Server_Info *server, struct sockaddr *dstaddr, int port)\n+int smbd_prepare_socket(struct TCP_Server_Info *server, int port)\n {\n-\tstruct net *net = cifs_net_ns(server);\n-\tstruct smbd_connection *info;\n-\tstruct smbdirect_socket *sc;\n+\tstruct smbdirect_socket *sc = NULL;\n \tstruct smbdirect_socket_parameters init_params = {};\n \tstruct smbdirect_socket_parameters *sp;\n-\t__be16 *sport;\n \tu64 port_flags = 0;\n \tint ret;\n \n \tswitch (port) {\n-\tcase SMBD_PORT:\n+\tcase SMBD_IWARP_PORT:\n \t\t/*\n \t\t * only allow iWarp devices\n \t\t * for port 5445.\n \t\t */\n \t\tport_flags |= SMBDIRECT_FLAG_PORT_RANGE_ONLY_IW;\n \t\tbreak;\n-\tcase SMB_PORT:\n+\tcase CIFS_PORT:\n \t\t/*\n \t\t * only allow InfiniBand, RoCEv1 or RoCEv2\n \t\t * devices for port 445.\n@@ -281,6 +184,12 @@ static struct smbd_connection *_smbd_get_connection(\n \t\tbreak;\n \t}\n \n+\tif (server && cifs_rdma_enabled(server) && server->ssocket)\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n+\n+\tif (WARN_ON_ONCE(!sc))\n+\t\treturn -ENOTCONN;\n+\n \t/*\n \t * Create the initial parameters\n \t */\n@@ -301,107 +210,40 @@ static struct smbd_connection *_smbd_get_connection(\n \tsp->keepalive_interval_msec = smbd_keep_alive_interval * 1000;\n \tsp->keepalive_timeout_msec = KEEPALIVE_RECV_TIMEOUT * 1000;\n \n-\tinfo = kzalloc_obj(*info);\n-\tif (!info)\n-\t\treturn NULL;\n-\tret = smbdirect_socket_create_kern(net, &sc);\n-\tif (ret)\n-\t\tgoto socket_init_failed;\n \tsmbdirect_socket_set_logging(sc, NULL, smbd_logging_needed, smbd_logging_vaprintf);\n \tret = smbdirect_socket_set_initial_parameters(sc, sp);\n \tif (ret)\n-\t\tgoto set_params_failed;\n+\t\treturn ret;\n \tret = smbdirect_socket_set_kernel_settings(sc, IB_POLL_SOFTIRQ, GFP_KERNEL);\n \tif (ret)\n-\t\tgoto set_settings_failed;\n-\n-\tif (dstaddr->sa_family == AF_INET6)\n-\t\tsport = &((struct sockaddr_in6 *)dstaddr)->sin6_port;\n-\telse\n-\t\tsport = &((struct sockaddr_in *)dstaddr)->sin_port;\n-\n-\t*sport = htons(port);\n+\t\treturn ret;\n \n-\tret = smbdirect_connect_sync(sc, dstaddr);\n-\tif (ret) {\n-\t\tlog_rdma_event(ERR, \"connect to %pISpsfc failed: %1pe\\n\",\n-\t\t\t dstaddr, ERR_PTR(ret));\n-\t\tgoto connect_failed;\n-\t}\n-\n-\tinfo->socket = sc;\n-\treturn info;\n-\n-connect_failed:\n-set_settings_failed:\n-set_params_failed:\n-\tsmbdirect_socket_release(sc);\n-socket_init_failed:\n-\tkfree(info);\n-\treturn NULL;\n+\treturn 0;\n }\n \n-const struct smbdirect_socket_parameters *smbd_get_parameters(struct smbd_connection *conn)\n+const struct smbdirect_socket_parameters *smbd_get_parameters(struct TCP_Server_Info *server)\n {\n-\tif (unlikely(!conn->socket)) {\n-\t\tstatic const struct smbdirect_socket_parameters zero_params;\n+\tstruct smbdirect_socket *sc = NULL;\n+\tconst struct smbdirect_socket_parameters *sp = NULL;\n \n-\t\treturn &zero_params;\n-\t}\n-\n-\treturn smbdirect_socket_get_current_parameters(conn->socket);\n-}\n+\tif (server && cifs_rdma_enabled(server) && server->ssocket)\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n \n-struct smbd_connection *smbd_get_connection(\n-\tstruct TCP_Server_Info *server, struct sockaddr *dstaddr)\n-{\n-\tstruct smbd_connection *ret;\n-\tconst struct smbdirect_socket_parameters *sp;\n-\tint port = SMBD_PORT;\n-\n-try_again:\n-\tret = _smbd_get_connection(server, dstaddr, port);\n+\tif (!sc) {\n+\t\tstatic const struct smbdirect_socket_parameters zero_params;\n \n-\t/* Try SMB_PORT if SMBD_PORT doesn't work */\n-\tif (!ret && port == SMBD_PORT) {\n-\t\tport = SMB_PORT;\n-\t\tgoto try_again;\n+\t\treturn &zero_params;\n \t}\n-\tif (!ret)\n-\t\treturn NULL;\n \n-\tsp = smbd_get_parameters(ret);\n+\tsp = smbdirect_socket_get_current_parameters(sc);\n \n-\tserver->rdma_readwrite_threshold =\n-\t\trdma_readwrite_threshold > sp->max_fragmented_send_size ?\n-\t\tsp->max_fragmented_send_size :\n-\t\trdma_readwrite_threshold;\n+\tif (server->rdma_readwrite_threshold == 0)\n+\t\tserver->rdma_readwrite_threshold =\n+\t\t\trdma_readwrite_threshold > sp->max_fragmented_send_size ?\n+\t\t\tsp->max_fragmented_send_size :\n+\t\t\trdma_readwrite_threshold;\n \n-\treturn ret;\n-}\n-\n-/*\n- * Receive data from the transport's receive reassembly queue\n- * All the incoming data packets are placed in reassembly queue\n- * iter: the buffer to read data into\n- * size: the length of data to read\n- * return value: actual data read\n- *\n- * Note: this implementation copies the data from reassembly queue to receive\n- * buffers used by upper layer. This is not the optimal code path. A better way\n- * to do it is to not have upper layer allocate its receive buffers but rather\n- * borrow the buffer from reassembly queue, and return it after data is\n- * consumed. But this will require more changes to upper layer code, and also\n- * need to consider packet boundaries while they still being reassembled.\n- */\n-int smbd_recv(struct smbd_connection *info, struct msghdr *msg)\n-{\n-\tstruct smbdirect_socket *sc = info->socket;\n-\n-\tif (!smbdirect_connection_is_connected(sc))\n-\t\treturn -ENOTCONN;\n-\n-\treturn smbdirect_connection_recvmsg(sc, msg, 0);\n+\treturn sp;\n }\n \n /*\n@@ -410,12 +252,11 @@ int smbd_recv(struct smbd_connection *info, struct msghdr *msg)\n * rqst: the data to write\n * return value: 0 if successfully write, otherwise error code\n */\n-int smbd_send(struct TCP_Server_Info *server,\n+static int smbd_send_locked(struct TCP_Server_Info *server,\n \tint num_rqst, struct smb_rqst *rqst_array)\n {\n-\tstruct smbd_connection *info = server->smbd_conn;\n-\tstruct smbdirect_socket *sc = info->socket;\n-\tconst struct smbdirect_socket_parameters *sp = smbd_get_parameters(info);\n+\tstruct smbdirect_socket *sc = NULL;\n+\tconst struct smbdirect_socket_parameters *sp = smbd_get_parameters(server);\n \tstruct smb_rqst *rqst;\n \tstruct iov_iter iter;\n \tstruct smbdirect_send_batch_storage bstorage;\n@@ -424,6 +265,9 @@ int smbd_send(struct TCP_Server_Info *server,\n \tint rc, i, rqst_idx;\n \tint error = 0;\n \n+\tif (server && cifs_rdma_enabled(server) && server->ssocket)\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n+\n \tif (!smbdirect_connection_is_connected(sc))\n \t\treturn -EAGAIN;\n \n@@ -508,6 +352,28 @@ int smbd_send(struct TCP_Server_Info *server,\n \treturn 0;\n }\n \n+int smbd_send(struct TCP_Server_Info *server,\n+\tint num_rqst, struct smb_rqst *rqst_array)\n+{\n+\tstruct smbdirect_socket *sc = NULL;\n+\tstruct sock *sk = NULL;\n+\tint ret;\n+\n+\tif (server && cifs_rdma_enabled(server) && server->ssocket) {\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n+\t\tsk = server->ssocket->sk;\n+\t}\n+\n+\tif (!smbdirect_connection_is_connected(sc))\n+\t\treturn -EAGAIN;\n+\n+\tlock_sock(sk);\n+\tret = smbd_send_locked(server, num_rqst, rqst_array);\n+\trelease_sock(sk);\n+\n+\treturn ret;\n+}\n+\n /*\n * Register memory for RDMA read/write\n * iter: the buffer to register memory with\n@@ -515,11 +381,14 @@ int smbd_send(struct TCP_Server_Info *server,\n * need_invalidate: true if this MR needs to be locally invalidated after I/O\n * return value: the MR registered, NULL if failed.\n */\n-struct smbdirect_mr_io *smbd_register_mr(struct smbd_connection *info,\n+struct smbdirect_mr_io *smbd_register_mr(struct TCP_Server_Info *server,\n \t\t\t\t struct iov_iter *iter,\n \t\t\t\t bool writing, bool need_invalidate)\n {\n-\tstruct smbdirect_socket *sc = info->socket;\n+\tstruct smbdirect_socket *sc = NULL;\n+\n+\tif (server && cifs_rdma_enabled(server) && server->ssocket)\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n \n \tif (!smbdirect_connection_is_connected(sc))\n \t\treturn NULL;\n@@ -546,15 +415,25 @@ void smbd_deregister_mr(struct smbdirect_mr_io *mr)\n \n void smbd_debug_proc_show(struct TCP_Server_Info *server, struct seq_file *m)\n {\n-\tif (!server->rdma)\n+\tstruct smbdirect_socket *sc = NULL;\n+\n+\tif (!cifs_rdma_enabled(server))\n \t\treturn;\n \n-\tif (!server->smbd_conn) {\n+\tif (server->ssocket) {\n+\t\tsc = smbdirect_socket_from_sock(server->ssocket);\n+\t\t/*\n+\t\t * setup server->rdma_readwrite_threshold is required\n+\t\t */\n+\t\t(void) smbd_get_parameters(server);\n+\t}\n+\n+\tif (!sc) {\n \t\tseq_puts(m, \"\\nSMBDirect transport not available\");\n \t\treturn;\n \t}\n \n-\tsmbdirect_connection_legacy_debug_proc_show(server->smbd_conn->socket,\n+\tsmbdirect_connection_legacy_debug_proc_show(sc,\n \t\t\t\t\t\t server->rdma_readwrite_threshold,\n \t\t\t\t\t\t m);\n }\ndiff --git a/fs/smb/client/smbdirect.h b/fs/smb/client/smbdirect.h\nindex 0017d5b2de44..44b37234d87c 100644\n--- a/fs/smb/client/smbdirect.h\n+++ b/fs/smb/client/smbdirect.h\n@@ -8,7 +8,6 @@\n #define _SMBDIRECT_H\n \n #ifdef CONFIG_CIFS_SMB_DIRECT\n-#define cifs_rdma_enabled(server)\t((server)->rdma)\n \n #include \"cifsglob.h\"\n \n@@ -23,29 +22,18 @@ extern int smbd_max_send_size;\n extern int smbd_send_credit_target;\n extern int smbd_receive_credit_max;\n \n-struct smbd_connection {\n-\tstruct smbdirect_socket *socket;\n-};\n+/* prepare a SMBDirect session */\n+int smbd_prepare_socket(struct TCP_Server_Info *server, int port);\n \n-/* Create a SMBDirect session */\n-struct smbd_connection *smbd_get_connection(\n-\tstruct TCP_Server_Info *server, struct sockaddr *dstaddr);\n-\n-const struct smbdirect_socket_parameters *smbd_get_parameters(struct smbd_connection *conn);\n-\n-/* Reconnect SMBDirect session */\n-int smbd_reconnect(struct TCP_Server_Info *server);\n-/* Destroy SMBDirect session */\n-void smbd_destroy(struct TCP_Server_Info *server);\n+const struct smbdirect_socket_parameters *smbd_get_parameters(struct TCP_Server_Info *server);\n \n /* Interface for carrying upper layer I/O through send/recv */\n-int smbd_recv(struct smbd_connection *info, struct msghdr *msg);\n int smbd_send(struct TCP_Server_Info *server,\n \tint num_rqst, struct smb_rqst *rqst);\n \n /* Interfaces to register and deregister MR for RDMA read/write */\n struct smbdirect_mr_io *smbd_register_mr(\n-\tstruct smbd_connection *info, struct iov_iter *iter,\n+\tstruct TCP_Server_Info *server, struct iov_iter *iter,\n \tbool writing, bool need_invalidate);\n void smbd_mr_fill_buffer_descriptor(struct smbdirect_mr_io *mr,\n \t\t\t\t struct smbdirect_buffer_descriptor_v1 *v1);\n@@ -54,13 +42,6 @@ void smbd_deregister_mr(struct smbdirect_mr_io *mr);\n void smbd_debug_proc_show(struct TCP_Server_Info *server, struct seq_file *m);\n \n #else\n-#define cifs_rdma_enabled(server)\t0\n-struct smbd_connection {};\n-static inline void *smbd_get_connection(\n-\tstruct TCP_Server_Info *server, struct sockaddr *dstaddr) {return NULL;}\n-static inline int smbd_reconnect(struct TCP_Server_Info *server) {return -1; }\n-static inline void smbd_destroy(struct TCP_Server_Info *server) {}\n-static inline int smbd_recv(struct smbd_connection *info, struct msghdr *msg) {return -1; }\n static inline int smbd_send(struct TCP_Server_Info *server, int num_rqst, struct smb_rqst *rqst) {return -1; }\n #endif\n \ndiff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c\nindex 05f8099047e1..e64becee928f 100644\n--- a/fs/smb/client/transport.c\n+++ b/fs/smb/client/transport.c\n@@ -253,7 +253,7 @@ int __smb_send_rqst(struct TCP_Server_Info *server, int num_rqst,\n \tif (cifs_rdma_enabled(server)) {\n \t\t/* return -EAGAIN when connecting or reconnecting */\n \t\trc = -EAGAIN;\n-\t\tif (server->smbd_conn)\n+\t\tif (ssocket)\n \t\t\trc = smbd_send(server, num_rqst, rqst);\n \t\tgoto smbd_done;\n \t}\n", "prefixes": [ "7/8" ] }