Bahubali B Gumaji
b38f99c121
ksmbd: add procfs interface for runtime monitoring and statistics
...
This patch introduces a /proc filesystem interface to ksmbd, providing
visibility into the internal state of the SMB server. This allows
administrators and developers to monitor active connections, user
sessions, and opened files in real-time without relying on external
tools or heavy debugging.
Key changes include:
- Connection Monitoring (/proc/fs/ksmbd/clients): Displays a list of
active network connections, including client IP addresses, SMB dialects,
credits, and last active timestamps.
- Session Management (/proc/fs/ksmbd/sessions/): Adds a global sessions
file to list all authenticated users and their session IDs.
- Creates individual session entries (e.g., /proc/fs/ksmbd/sessions/<id>)
detailing capabilities (DFS, Multi-channel, etc.), signing/encryption
algorithms, and connected tree shares.
- File Tracking (/proc/fs/ksmbd/files): Shows all currently opened files
across the server, including tree IDs, process IDs (PID), access modes
(daccess/saccess), and oplock/lease states.
- Statistics & Counters: Implements internal counters for global server
metrics, such as the number of tree connections, total sessions, and
processed read/write bytes.
Signed-off-by: Hyunchul Lee <hyc.lee@gmail.com >
Signed-off-by: Bahubali B Gumaji <bahubali.bg@samsung.com >
Signed-off-by: Sang-Soo Lee <constant.lee@samsung.com >
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 20:25:16 -06:00
Namjae Jeon
010eb01ce2
ksmbd: fix infinite loop caused by next_smb2_rcv_hdr_off reset in error paths
...
The problem occurs when a signed request fails smb2 signature verification
check. In __process_request(), if check_sign_req() returns an error,
set_smb2_rsp_status(work, STATUS_ACCESS_DENIED) is called.
set_smb2_rsp_status() set work->next_smb2_rcv_hdr_off as zero. By resetting
next_smb2_rcv_hdr_off to zero, the pointer to the next command in the chain
is lost. Consequently, is_chained_smb2_message() continues to point to
the same request header instead of advancing. If the header's NextCommand
field is non-zero, the function returns true, causing __handle_ksmbd_work()
to repeatedly process the same failed request in an infinite loop.
This results in the kernel log being flooded with "bad smb2 signature"
messages and high CPU usage.
This patch fixes the issue by changing the return value from
SERVER_HANDLER_CONTINUE to SERVER_HANDLER_ABORT. This ensures that
the processing loop terminates immediately rather than attempting to
continue from an invalidated offset.
Reported-by: tianshuo han <hantianshuo233@gmail.com >
Cc: stable@vger.kernel.org
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 20:24:11 -06:00
Stefan Metzmacher
214220e7fa
smb: server: make use of rdma_restrict_node_type()
...
For smbdirect it required to use different ports depending
on the RDMA protocol. E.g. for iWarp 5445 is needed
(as tcp port 445 already used by the raw tcp transport for SMB),
while InfiniBand, RoCEv1 and RoCEv2 use port 445, as they
use an independent port range (even for RoCEv2, which uses udp
port 4791 itself).
Currently ksmbd is not able to function correctly at
all if the system has iWarp (RDMA_NODE_RNIC) interface(s)
and any InfiniBand, RoCEv1 and/or RoCEv2 interface(s)
at the same time.
Now we do a wildcard listen on port 5445 only
for iWarp devices and another wildcard listen
on port 445 of any InfiniBand, RoCEv1 and/or RoCEv2
devices.
The wildcard listeners also work if there is
no device of the requested node_type, this
is the same logic as we had before, but before
we had to decide between port 5445 or 445
and now both are possible at the same time.
Cc: Jason Gunthorpe <jgg@ziepe.ca >
Cc: Leon Romanovsky <leon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-rdma@vger.kernel.org
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
07e0b72eb0
smb: client: make use of rdma_restrict_node_type()
...
For smbdirect it required to use different ports depending
on the RDMA protocol. E.g. for iWarp 5445 is needed
(as tcp port 445 already used by the raw tcp transport for SMB),
while InfiniBand, RoCEv1 and RoCEv2 use port 445, as they
use an independent port range (even for RoCEv2, which uses udp
port 4791 itself).
And cifs.ko uses 5445 with a fallback to 445, which
means depending on the available interfaces, it tries
5445 in the RoCE range or may tries iWarp with 445
as a fallback. This leads to strange error messages
and strange network captures.
To avoid these problems they will be able to
use rdma_restrict_node_type(RDMA_NODE_RNIC) before
trying port 5445 and rdma_restrict_node_type(RDMA_NODE_IB_CA)
before trying port 445. It means we'll get early
-ENODEV early from rdma_resolve_addr() without any
network traffic and timeouts.
Cc: Jason Gunthorpe <jgg@ziepe.ca >
Cc: Leon Romanovsky <leon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-rdma@vger.kernel.org
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
cf74fcdc43
smb: client: let send_done handle a completion without IB_SEND_SIGNALED
...
With smbdirect_send_batch processing we likely have requests without
IB_SEND_SIGNALED, which will be destroyed in the final request
that has IB_SEND_SIGNALED set.
If the connection is broken all requests are signaled
even without explicit IB_SEND_SIGNALED.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
5b1c614965
smb: client: let smbd_post_send_negotiate_req() use smbd_post_send()
...
The server has similar logic and it makes sure that
request->wr is used instead of a stack struct ib_send_wr send_wr.
This makes sure send_done can see request->wr.send_flags
as the next commit will check for IB_SEND_SIGNALED
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
93ac432274
smb: client: fix last send credit problem causing disconnects
...
When we are about to use the last send credit that was
granted to us by the peer, we need to wait until
we are ourself able to grant at least one credit
to the peer. Otherwise it might not be possible
for the peer to grant more credits.
The following sections in MS-SMBD are related to this:
3.1.5.1 Sending Upper Layer Messages
...
If Connection.SendCredits is 1 and the CreditsGranted field of the
message is 0, stop processing.
...
3.1.5.9 Managing Credits Prior to Sending
...
If Connection.ReceiveCredits is zero, or if Connection.SendCredits is
one and the Connection.SendQueue is not empty, the sender MUST allocate
and post at least one receive of size Connection.MaxReceiveSize and MUST
increment Connection.ReceiveCredits by the number allocated and posted.
If no receives are posted, the processing MUST return a value of zero to
indicate to the caller that no Send message can be currently performed.
...
This is a similar logic as we have in the server.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
21538121ef
smb: client: make use of smbdirect_socket.send_io.bcredits
...
It turns out that our code will corrupt the stream of
reassabled data transfer messages when we trigger an
immendiate (empty) send.
In order to fix this we'll have a single 'batch' credit per
connection. And code getting that credit is free to use
as much messages until remaining_length reaches 0, then
the batch credit it given back and the next logical send can
happen.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
2c1ac39ce9
smb: client: use smbdirect_send_batch processing
...
This will allow us to use similar logic as we have in
the server soon, so that we can share common code later.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
dc77da0373
smb: client: introduce and use smbd_{alloc, free}_send_io()
...
This is basically a copy of smb_direct_{alloc,free}_sendmsg()
in the server, with just using ib_dma_unmap_page() in all
cases, which is the same as ib_dma_unmap_single().
We'll use this logic in common code in future.
(I basically backported it from my branch that
as already has everything in common).
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
bf30515cae
smb: client: split out smbd_ib_post_send()
...
This is like smb_direct_post_send() in the server
and will simplify porting the smbdirect_send_batch
and credit related logic from the server.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
bb848d205f
smb: client: port and use the wait_for_credits logic used by server
...
This simplifies the logic and prepares the use of
smbdirect_send_batch in order to make sure
all messages in a multi fragment send are grouped
together.
We'll add the smbdirect_send_batch processin
in a later patch.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
8bfe3fd33f
smb: client: remove pointless sc->send_io.pending handling in smbd_post_send_iter()
...
If we reach this the connection is already broken as
smbd_post_send() already called
smbd_disconnect_rdma_connection().
This will also simplify further changes.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
6858531e5e
smb: client: remove pointless sc->recv_io.credits.count rollback
...
We either reach this code path before we call
new_credits = manage_credits_prior_sending(sc),
which means new_credits is still 0
or the connection is already broken as
smbd_post_send() already called
smbd_disconnect_rdma_connection().
This will also simplify further changes.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
bf1656e12a
smb: client: let smbd_post_send() make use of request->wr
...
We don't need a stack variable in addition.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:58 -06:00
Stefan Metzmacher
defb3c05fe
smb: client: let recv_done() queue a refill when the peer is low on credits
...
In captures I saw that Windows was granting 191 credits in a batch
when its peer posted a lot of messages. We are asking for a
credit target of 255 and 191 is 252*3/4.
So we also use that logic in order to fill the
recv buffers available to the peer.
Fixes: 02548c477a ("smb: client: queue post_recv_credits_work also if the peer raises the credit target")
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
9911b1ed18
smb: client: make use of smbdirect_socket.recv_io.credits.available
...
The logic off managing recv credits by counting posted recv_io and
granted credits is racy.
That's because the peer might already consumed a credit,
but between receiving the incoming recv at the hardware
and processing the completion in the 'recv_done' functions
we likely have a window where we grant credits, which
don't really exist.
So we better have a decicated counter for the
available credits, which will be incremented
when we posted new recv buffers and drained when
we grant the credits to the peer.
Fixes: 5fb9b459b3 ("smb: client: count the number of posted recv_io messages in order to calculated credits")
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
9da82dc73c
smb: server: let send_done handle a completion without IB_SEND_SIGNALED
...
With smbdirect_send_batch processing we likely have requests without
IB_SEND_SIGNALED, which will be destroyed in the final request
that has IB_SEND_SIGNALED set.
If the connection is broken all requests are signaled
even without explicit IB_SEND_SIGNALED.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
8cf2bbac62
smb: server: fix last send credit problem causing disconnects
...
When we are about to use the last send credit that was
granted to us by the peer, we need to wait until
we are ourself able to grant at least one credit
to the peer. Otherwise it might not be possible
for the peer to grant more credits.
The following sections in MS-SMBD are related to this:
3.1.5.1 Sending Upper Layer Messages
...
If Connection.SendCredits is 1 and the CreditsGranted field of the
message is 0, stop processing.
...
3.1.5.9 Managing Credits Prior to Sending
...
If Connection.ReceiveCredits is zero, or if Connection.SendCredits is
one and the Connection.SendQueue is not empty, the sender MUST allocate
and post at least one receive of size Connection.MaxReceiveSize and MUST
increment Connection.ReceiveCredits by the number allocated and posted.
If no receives are posted, the processing MUST return a value of zero to
indicate to the caller that no Send message can be currently performed.
...
This problem was found by running this on Windows 2025
against ksmbd with required smb signing:
'frametest.exe -r 4k -t 20 -n 2000' after
'frametest.exe -w 4k -t 20 -n 2000'.
Link: https://lore.kernel.org/linux-cifs/b58fa352-2386-4145-b42e-9b4b1d484e17@samba.org/
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
34abd408c8
smb: server: make use of smbdirect_socket.send_io.bcredits
...
It turns out that our code will corrupt the stream of
reassabled data transfer messages when we trigger an
immendiate (empty) send.
In order to fix this we'll have a single 'batch' credit per
connection. And code getting that credit is free to use
as much messages until remaining_length reaches 0, then
the batch credit it given back and the next logical send can
happen.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
8106978d40
smb: server: let recv_done() queue a refill when the peer is low on credits
...
In captures I saw that Windows was granting 191 credits in a batch
when its peer posted a lot of messages. We are asking for a
credit target of 255 and 191 is 252*3/4.
So we also use that logic in order to fill the
recv buffers available to the peer.
Fixes: a7eef6144c ("smb: server: queue post_recv_credits_work in put_recvmsg() and avoid count_avail_recvmsg")
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
26ad87a2cf
smb: server: make use of smbdirect_socket.recv_io.credits.available
...
The logic off managing recv credits by counting posted recv_io and
granted credits is racy.
That's because the peer might already consumed a credit,
but between receiving the incoming recv at the hardware
and processing the completion in the 'recv_done' functions
we likely have a window where we grant credits, which
don't really exist.
So we better have a decicated counter for the
available credits, which will be incremented
when we posted new recv buffers and drained when
we grant the credits to the peer.
This fixes regression Namjae reported with
the 6.18 release.
Fixes: 89b021a726 ("smb: server: manage recv credits by counting posted recv_io and granted credits")
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
8e94268b21
smb: smbdirect: introduce smbdirect_socket.send_io.bcredits.*
...
It turns out that our code will corrupt the stream of
reassabled data transfer messages when we trigger an
immendiate (empty) send.
In order to fix this we'll have a single 'batch' credit per
connection. And code getting that credit is free to use
as much messages until remaining_length reaches 0, then
the batch credit it given back and the next logical send can
happen.
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
Stefan Metzmacher
6e3c5052f9
smb: smbdirect: introduce smbdirect_socket.recv_io.credits.available
...
The logic off managing recv credits by counting posted recv_io and
granted credits is racy.
That's because the peer might already consumed a credit,
but between receiving the incoming recv at the hardware
and processing the completion in the 'recv_done' functions
we likely have a window where we grant credits, which
don't really exist.
So we better have a decicated counter for the
available credits, which will be incremented
when we posted new recv buffers and drained when
we grant the credits to the peer.
Fixes: 5fb9b459b3 ("smb: client: count the number of posted recv_io messages in order to calculated credits")
Fixes: 89b021a726 ("smb: server: manage recv credits by counting posted recv_io and granted credits")
Cc: <stable@vger.kernel.org > # 6.18.x
Cc: Steve French <smfrench@gmail.com >
Cc: Tom Talpey <tom@talpey.com >
Cc: Long Li <longli@microsoft.com >
Cc: Namjae Jeon <linkinjeon@kernel.org >
Cc: linux-cifs@vger.kernel.org
Cc: samba-technical@lists.samba.org
Signed-off-by: Stefan Metzmacher <metze@samba.org >
Acked-by: Namjae Jeon <linkinjeon@kernel.org >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:12:57 -06:00
David Howells
10dfb0738a
cifs: Label SMB2 statuses with errors
...
Label the SMB2 status entries with error codes as a prelude to
autogenerating the mapping table. This was done with the following script:
#!/usr/bin/perl -w
use strict;
my @error_mapping_table = ();
my %statuses = ();
#
# Read the status list
#
my $f = "fs/smb/common/smb2status.h";
open FILE, "<$f" || die $f;
my @contents = <FILE>;
close FILE || die;
my $l = 0;
foreach (@contents) {
$l++;
if (m!^#define\s*([A-Za-z0-9_]+)\s+cpu_to_le32[(]([0-9a-fA-Fx]+)[)]!) {
my $status = $1;
my $code = $2;
my $s;
next if ($status =~ /^STATUS_SEVERITY/);
if (exists($statuses{$status})) {
print("$f:$l: Duplicate declaration of ", $s->{status}, "\n");
} else {
my %_s = (
status => $status,
code => hex($code)
);
$statuses{$status} = \%_s;
}
}
}
#
# Read the SMB2 status => error mapping table
#
$f = "fs/smb/client/smb2maperror.c";
open(MFILE, "<$f") || die $f;
my @maperror = <MFILE>;
close MFILE || die;
my $parse = 0;
my $acc = "";
$l = 0;
foreach my $line (@maperror) {
chomp $line;
$l++;
if ($parse == 0 &&
$line =~ /^static const struct status_to_posix_error smb2_error_map_table/) {
$parse = 1;
next;
}
last if ($parse >= 1 && $line =~ /^[}];/);
if ($parse == 1) {
if ($line =~ /[\t][{].*[}],/) {
$acc = $line;
$parse = 3;
} elsif ($line =~ /[\t][{].*/) {
$acc = $line;
$parse = 2;
next;
} elsif ($line =~ m!^\s*/[*].*[*]/!) {
next;
} else {
die "smb2maperror.c:$l: unparseable mapping element\n";
}
}
if ($parse == 2) {
if ($line =~ /.*[}],/) {
$acc .= $line;
$parse = 3;
} else {
$acc .= $line;
}
}
if ($parse == 3) {
$acc =~ s/\s+//g;
if ($acc =~ m/[{](.*)[}]/) {
$acc = $1;
} else {
die "'$acc'";
}
my ($status, $error, $string) = split(/,/, $acc);
if (exists($statuses{$status})) {
my $s = $statuses{$status};
if (exists($s->{error})) {
print("$f:$l: Dup mapping entry $status\n");
}
$s->{error} = $error;
#print $s->{code}, " => ", $error, "\n";
} else {
print STDERR "$f:$l: Unknown status $status\n";
}
$acc = "";
$parse = 1;
}
}
#
# Sort the error table by STATUS_* value
#
my @order = ();
foreach my $status (keys(%statuses)) {
my $s = $statuses{$status};
push @order, $s;
unless (exists($s->{code})) {
print("Unknown code for ", $s->{status}, "\n")
} else {
#print("Code for ", $s->{status}, " is ", $s->{code}, "\n");
}
}
@order = sort( { $a->{code} <=> $b->{code} } @order);
foreach my $s (@order) {
my $status = $s->{status};
my $error = $s->{error};
my $code = $s->{code};
my $pad = " ";
if (length($status) < 32) {
my $n = 32 - length($status);
$pad = "\t" x ((($n-1) / 8) + 1);
}
#printf("#define %s%scpu_to_le32(0x%08x) // -%s\n", $status, $pad, $code, $error);
#printf("\t%s%s= 0x%08x, // -%s\n", $status, $pad, $code, $error);
}
#
# Decorate the definitions
#
my @output = ();
for (my $i = 0; $i <= $#contents; $i++) {
my $line = $contents[$i];
if ($line =~ m!^#define\s*([A-Za-z0-9_]+)\s+cpu_to_le32[(]([0-9a-fA-Fx]+)[)]!) {
my $status = $1;
my $code = $2;
if ($status =~ /^STATUS_SEVERITY/) {
push @output, $line;
next;
}
my $pad = " ";
if (length($status) < 40) {
my $n = 40 - length($status);
$pad = "\t" x ((($n-1) / 8) + 1);
}
my $s = $statuses{$1};
my $error = "EIO";
if (exists($s->{error})) {
$error = $s->{error};
} else {
if (!$s->{code}) {
print "ZERO ", $status, "\n";
$error = "0";
} else {
$error = "-EIO";
}
}
#my $rev = "#define " . $status . $pad . "_S(" . $2 . ", " . $error . ")\n";
my $rev = "#define " . $status . $pad . "cpu_to_le32(" . $2 . ") // " . $error . "\n";
push @output, $rev;
} else {
push @output, $line;
}
}
open FILE, ">fs/smb/common/smb2status.h" || die;
print FILE @output;
close FILE || die;
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <stfrench@microsoft.com >
cc: ChenXiaoSong <chenxiaosong@kylinos.cn >
cc: linux-cifs@vger.kernel.org
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn >
Reviewed-by: David Howells <dhowells@redhat.com >
Link: https://lore.kernel.org/linux-cifs/20260106071507.1420900-2-chenxiaosong.chenxiaosong@linux.dev/
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:46 -06:00
David Howells
c9ce93ef27
cifs: SMB1 split: Make BCC accessors conditional
...
Make the BCC accessor functions conditional.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:46 -06:00
David Howells
88f7d7e32d
cifs: SMB1 split: connect.c
...
Split SMB1-specific connection management stuff to smb1ops.c and move
CIFSTCon() to cifssmb.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:46 -06:00
David Howells
dec5a519e6
cifs: SMB1 split: sess.c
...
Split SMB1-specific session setup stuff into smb1session.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:46 -06:00
David Howells
b6fe923776
cifs: SMB1 split: cifsencrypt.c
...
Split SMB1-specific message signing into smb1encrypt.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
6fb4e46d2f
cifs: SMB1 split: netmisc.c
...
Split a variety of bits from netmisc.c into other places, notably the error
table into smb1maperror.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
3739f6d298
cifs: SMB1 split: misc.c
...
Split SMB1 bits from misc.c to smb1misc.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
e5ac3ff6c6
cifs: SMB1 split: cifs_debug.c
...
Split SMB1 bits from cifs_debug.c to smb1debug.c.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
c23e0ce2ae
cifs: SMB1 split: Move inline funcs
...
Move some SMB1-specific inline funcs to smb1proto.h.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
1e6f98f3e8
cifs: Fix cifs_dump_mids() to call ->dump_detail
...
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
fee3181757
cifs: SMB1 split: Don't return smb_hdr from cifs_{,small_}buf_get()
...
Return void* rather than struct smb_hdr* from from cifs_buf_get() and
cifs_small_buf_get() as SMB2/3 shouldn't be accessing smb_hdr.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
efbe45cc03
cifs: SMB1 split: Move BCC access functions
...
Move the BCC access functions to smb1proto.h as they're only applicable to
SMB1.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
8a848efd48
cifs: SMB1 split: Adjust #includes
...
Adjust the #include set after the removal of the SMB1 protocol defs from
cifspdu.h.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
ed1e53796f
cifs: SMB1 split: Split SMB1 protocol defs into smb1pdu.h
...
Split SMB1 protocol defs into smb1pdu.h. This should perhaps go in the
common/ directory.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
a7c7f35bcf
cifs: SMB1 split: Add some #includes
...
Add some #includes to make sure things continue to compile as splitting
occurs.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
282432612a
cifs: SMB1 split: Move some SMB1 received PDU checking bits to smb1transport.c
...
Move some SMB1 received checking bits to smb1transport.c from misc.c
so that they're with the rest of the receive handling code.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
bae7afc4b4
cifs: SMB1 split: Move some SMB1 receive bits to smb1transport.c
...
Move some SMB1 receive bits to smb1transport.c from smb1ops.c where they're
mixed in with unrelated code to do with encoding, decoding and processing
PDUs.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
645427b7a6
cifs: SMB1 split: Separate out SMB1 decls into smb1proto.h
...
Separate out SMB1 declarations scriptedly into smb1proto.h. Script below:
#!/usr/bin/perl -w
use strict;
unless (@ARGV) {
die "Usage: $0 <c_file1> [<c_file2> ...]\n";
}
# Data tracking
my %funcs = (); # Func name => { func prototype }
my %headers = (); # Header filename => { header content }
my %c_files = (); # C filename => { ordered func list, header pref }
my %cmarkers = (); # C filename marker => { header filename it's in }
# Parse state
my $pathname = "-";
my $lineno = 0;
sub error(@) {
print STDERR $pathname, ":", $lineno, ": ", @_, "\n";
exit(1);
}
sub pad($) {
# Reindent the function arguments to line the arguments up with the char
# after the opening bracket on the func argument list
my ($lines) = @_;
return $lines if ($#{$lines} <= 0);
my $has_empty = 0;
for (my $i = 0; $i <= $#{$lines}; $i++) {
$lines->[$i] =~ s/^[ \t]+//;
$has_empty = 1 if ($lines->[$i] eq "");
}
if ($has_empty) {
my @clean = grep /.+/, @{$lines};
$lines = \@clean;
}
my $indlen = index($lines->[0], "(");
return $lines if ($indlen < 0);
my $indent = "";
$indlen++;
$indent .= "\t" x ($indlen / 8);
$indent .= " " x ($indlen % 8);
my @padded = ();
my $acc = "";
my $len = -$indlen;
for (my $i = 0; $i <= $#{$lines}; $i++) {
my $argument = $lines->[$i];
my $arglen = length($argument);
my $last = ($i == $#{$lines} ? 1 : 0);
if ($i == 0 ||
$i == 1) {
$acc .= $argument;
$acc .= ";" if ($last);
$len += $arglen + $last;
next;
}
if (!$acc) {
$acc = $indent . $argument;
$acc .= ";" if ($last);
$len += $arglen + $last;
next;
}
if ($indlen + $len + 1 + $arglen + $last > 79) {
push @padded, $acc;
$acc = $indent . $argument;
$acc .= ";" if ($last);
$len = $arglen + $last;
next;
}
$acc .= " " . $argument;
$acc .= ";" if ($last);
$len += 1 + $arglen + $last;
}
push @padded, $acc if ($acc);
return \@padded;
}
sub earliest(@) {
my $ret = -1;
foreach (@_) {
$ret = $_ if ($ret < 0 || ($_ >= 0 && $_ < $ret));
}
return $ret;
}
foreach my $file (@ARGV) {
# Open the file for reading.
next if $file =~ /trace[.]h$/;
next if $file =~ /smbdirect[.][ch]$/;
open my $fh, "<$file"
or die "Could not open file '$file'";
$pathname = $file;
$lineno = 0;
my $filename;
my @file_content = ();
my @copy = ();
my $state = 0;
my $qual = "";
my $type = "";
my $funcname = "";
my @funcdef = ();
my $bracket = 0;
my $comment = 0;
my $smb1 = 0;
my $header = 0;
my $inline = 0;
my $file_marker = "";
my $config = "";
my $c_file = 0;
$filename = $pathname;
$filename =~ s!.*/!!;
if ($file =~ m!.h$!) {
my %new_h_file = (
path => $pathname,
fname => $filename,
content => [],
);
$header = \%new_h_file;
$headers{$filename} = \%new_h_file;
} elsif ($file =~ m!.c$!) {
my %new_c_file = (
path => $pathname,
fname => $filename,
funcs => [],
);
$c_file = \%new_c_file;
$c_files{$filename} = \%new_c_file;
} else {
warn("Ignoring unexpected file $file\n");
next;
}
$smb1 = 1 if ($file =~ m!/smb1ops.c|/cifssmb.c|/cifstransport.c!);
foreach my $line (<$fh>) {
$lineno++;
chomp($line);
push @copy, $line;
if (!$line) {
# Blank line
push @file_content, @copy;
@copy = ();
next;
}
# Handle continuation or end of block comment. Look for C file
# prototype insertion point markers.
if ($comment) {
if ($line =~ m![*]/!) {
if ($comment == 2 && $file_marker) {
$cmarkers{$file_marker} = $file_marker;
push @copy, "#C_MARKER " . $file_marker;
$file_marker = 0;
}
$comment = 0;
} else {
$comment++;
if ($comment == 2 && $line =~ m! [*] ([a-z][a-z_0-9]*[.][c])$!) {
$file_marker = $1;
print("Found file marker ", $file_marker, " in ", $filename, "\n");
}
}
push @file_content, @copy;
@copy = ();
next;
}
# Check cpp directives, particularly looking for SMB1 bits
if ($line =~ /^[#]/) {
if ($header) {
if ($line =~ /ifdef.*(CONFIG_[A-Z0-9_])/) {
error("multiconfig") if $config;
$config = $1;
$smb1++ if ($config eq "CONFIG_CIFS_ALLOW_INSECURE_LEGACY");
} elsif ($line =~ /endif/) {
$smb1-- if ($config eq "CONFIG_CIFS_ALLOW_INSECURE_LEGACY");
$config = "";
}
}
push @file_content, @copy;
@copy = ();
next;
}
# Exclude interference in finding func names and return types
if ($line =~ /^[{]/ ||
$line =~ /##/ ||
$line =~ /^[_a-z0-9A-Z]+:$/ || # goto label
$line =~ /^do [{]/ ||
$line =~ m!^//!) {
push @file_content, @copy;
@copy = ();
next;
}
# Start of a block comment
if ($line =~ m!^/[*]!) {
$comment = 1 unless ($line =~ m![*]/!);
push @file_content, @copy;
@copy = ();
next;
}
# End of a braced section, such as a function implementation
if ($line =~ /^[}]/) {
$type = "";
$qual = "";
$funcname = "";
@funcdef = ();
push @file_content, @copy;
@copy = ();
next;
}
if ($line =~ /^typedef/) {
$type = "";
$qual = "";
$funcname = "";
@funcdef = ();
push @file_content, @copy;
@copy = ();
next;
}
# Extract function qualifiers. There may be multiple of these in more
# or less any order. Some of them cause the func to be skipped (e.g. inline).
if ($line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)\W/ ||
$line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)$/) {
error("Unexpected qualifier '$1'") if ($state != 0);
while ($line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)\W/ ||
$line =~ /^(static|extern|inline|noinline|noinline_for_stack|__always_inline)$/) {
$qual .= " " if ($qual);
$qual .= $1;
$inline = 1 if ($1 eq "inline");
$inline = 1 if ($1 eq "__always_inline");
$line = substr($line, length($1));
$line =~ s/^\s+//;
}
}
if ($state == 0) {
# Extract what we assume to be the return type
if ($line =~ /^\s/) {
push @file_content, @copy;
@copy = ();
next;
}
while ($line =~ /^(unsigned|signed|bool|char|short|int|long|void|const|volatile|(struct|union|enum)\s+[_a-zA-Z][_a-zA-Z0-9]*|[*]|__init|__exit|__le16|__le32|__le64|__be16|__be32|__be64)/) {
$type .= " " if $type;
$type .= $1;
$line = substr($line, length($1));
$line =~ s/^\s+//;
}
if ($line =~ /^struct [{]/) {
# Ignore structure definitions
$type = "";
$qual = "";
$funcname = "";
@funcdef = ();
push @file_content, @copy;
@copy = ();
next;
}
if (index($line, "=") >= 0) {
# Ignore assignments
$type = "";
$qual = "";
$funcname = "";
@funcdef = "";
push @file_content, @copy;
@copy = ();
next;
}
# Try and extract a function's type and name
while ($line =~ /(^[_a-zA-Z][_a-zA-Z0-9]*)/) {
my $name = $1;
$line = substr($line, length($name));
next if ($line =~ /^[{]/);
$line =~ s/^\s+//;
my $ch = substr($line, 0, 1);
last if ($ch eq "[" || $ch eq ";"); # Global variables
if ($ch eq "(") {
# Found the function name
$state = 1;
$line = substr($line, 1);
$funcname = $name;
my $tmp = $qual . $type . " " . $funcname . "(";
$tmp =~ s/[*] /*/;
push @funcdef, $tmp;
$bracket = 1;
last;
}
if ($type) {
last if (index($line, ";") >= 0 && index($line, "(") == -1);
error("Unexpected name '$name' after '$type'");
}
$type .= " " if $type;
$type .= $name;
if ($line =~ /^(\s*[*]+)/) {
my $ptr = $1;
$type .= $ptr;
$line = substr($line, length($ptr));
}
}
}
# Try and extract a function's argument list
my $from = 0;
if ($state == 1) {
while (1) {
my $o = index($line, "(", $from);
my $c = index($line, ")", $from);
my $m = index($line, ",", $from);
my $b = earliest($o, $c, $m);
if ($b < 0) {
push @funcdef, $line
unless ($line eq "");
last;
}
my $ch = substr($line, $b, 1);
# Push the arguments separately on to the list
if ($ch eq ",") {
push @funcdef, substr($line, 0, $b + 1);
$line = substr($line, $b + 1);
$from = 0;
} elsif ($ch eq "(") {
# Handle brackets in the argument list (e.g. function
# pointers)
$bracket++;
$from = $b + 1;
} elsif ($ch eq ")") {
$bracket--;
if ($bracket == 0) {
push @funcdef, substr($line, 0, $b + 1);
$line = substr($line, $b + 1);
$state = 2;
last;
}
$from = $b + 1;
}
}
}
if ($state == 2) {
$inline = 1 if ($qual =~ /inline/);
#print("QUAL $qual $type $funcname $inline ", $#funcdef, "\n");
if (!$header &&
$qual !~ /static/ &&
$funcname ne "__acquires" &&
$funcname ne "__releases" &&
$funcname ne "module_init" &&
$funcname ne "module_exit" &&
$funcname ne "module_param" &&
$funcname ne "module_param_call" &&
$funcname ne "PROC_FILE_DEFINE" &&
$funcname !~ /MODULE_/ &&
$funcname !~ /DEFINE_/) {
# Okay, we appear to have a function implementation
my $func;
my $dup = 0;
if (exists($funcs{$funcname})) {
$func = $funcs{$funcname};
if (exists $func->{body}) {
print("dup $funcname\n");
$dup = 1;
}
} else {
my %new_func = (
name => $funcname,
cond => "",
legacy => 0,
);
$func = \%new_func;
$funcs{$funcname} = $func;
$func->{body} = pad(\@funcdef);
}
$func->{body} = pad(\@funcdef);
$func->{legacy} = 1 if $smb1;
if ($funcname eq "cifs_inval_name_dfs_link_error") {
$func->{cond} = "#ifdef CONFIG_CIFS_DFS_UPCALL";
} elsif ($funcname eq "cifs_listxattr") {
$func->{cond} = "#ifdef CONFIG_CIFS_XATTR";
}
push @{$c_file->{funcs}}, $func
unless $dup;
} elsif (!$header || $inline) {
# Ignore inline function implementations and other weirdies
push @file_content, @copy;
} elsif ($header && !$inline) {
push @file_content, "#FUNCPROTO " . $funcname;
my $func;
if (exists($funcs{$funcname})) {
$func = $funcs{$funcname};
$func->{lineno} = $lineno;
$func->{pathname} = $pathname;
} else {
my %new_func = (
name => $funcname,
cond => "",
lineno => $lineno,
pathname => $pathname,
legacy => 0,
);
$func = \%new_func;
$funcs{$funcname} = $func;
}
$func->{legacy} = 1 if $smb1;
}
@funcdef = ();
$type = "";
$qual = "";
$funcname = "";
$inline = 0;
$state = 0;
@copy = ();
}
if ($line =~ /;/) {
$type = "";
$qual = "";
$funcname = "";
@funcdef = ();
$state = 0;
push @file_content, @copy;
@copy = ();
}
}
close($fh);
if ($header) {
$header->{content} = \@file_content;
}
}
sub write_header($)
{
my ($header) = @_;
my $path = $header->{path};
my $legacy = 0;
$legacy = 1 if ($path =~ m!smb1proto[.]h!);
my @output = ();
foreach my $line (@{$header->{content}}) {
if ($line =~ "^[#]C_MARKER (.*)") {
my $file_marker = $cmarkers{$1};
my $c_file = $c_files{$file_marker};
print("Found $line\n");
foreach my $func (@{$c_file->{funcs}}) {
print("func ", $func->{name}, "\n");
push @output, @{$func->{body}};
}
next;
} elsif ($line =~ "^[#]FUNCPROTO ([_a-zA-Z0-9]+)") {
my $funcname = $1;
my $func = $funcs{$funcname};
if (!$func->{body}) {
print($func->{pathname}, ":", $func->{lineno}, ": '", $funcname,
"' dead prototype\n");
next;
}
if ($func->{legacy} == $legacy) {
#push @output, $line;
push @output, @{$func->{body}};
}
} else {
push @output, $line;
}
}
open my $fh, ">$path"
or die "Could not open file '$path' for writing";
foreach my $f (@output) {
print($fh $f, "\n") or die $path;
}
close($fh) or die $path;
}
foreach my $h (keys(%headers)) {
write_header($headers{$h});
}
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
86c666506e
cifs: SMB1 split: Create smb1proto.h for SMB1 declarations
...
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
b09eab52b3
cifs: SMB1 split: Rename cifstransport.c
...
Rename cifstransport.c to smb1transport.c in order to give consistent names
SMB1-specific files.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
657f6f9aff
cifs: Scripted clean up fs/smb/client/ntlmssp.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
a90ef3f4ba
cifs: Scripted clean up fs/smb/client/reparse.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
1e009e3346
cifs: Scripted clean up fs/smb/client/smb2proto.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
7e335c003e
cifs: Scripted clean up fs/smb/client/cifs_debug.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:45 -06:00
David Howells
4f8a3a1dfb
cifs: Scripted clean up fs/smb/client/cifs_swn.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:44 -06:00
David Howells
cfda564147
cifs: Scripted clean up fs/smb/client/compress.h
...
Remove externs, correct argument names and reformat declarations.
Signed-off-by: David Howells <dhowells@redhat.com >
cc: Steve French <sfrench@samba.org >
cc: Paulo Alcantara <pc@manguebit.org >
cc: Enzo Matsumiya <ematsumiya@suse.de >
cc: linux-cifs@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
cc: linux-kernel@vger.kernel.org
Acked-by: Enzo Matsumiya <ematsumiya@suse.de >
Signed-off-by: Steve French <stfrench@microsoft.com >
2026-02-08 17:07:44 -06:00