From: huiwen.he@linux.dev
To: smfrench@gmail.com, linkinjeon@kernel.org, dhowells@redhat.com,
chenxiaosong@kylinos.cn, chenxiaosong@chenxiaosong.com,
tangyouling@kylinos.cn
Cc: linux-cifs@vger.kernel.org, Huiwen He <hehuiwen@kylinos.cn>
Subject: [PATCH v3 11/13] smb/client: use binary search for SMB1 DOS/SRV error mapping
Date: Thu, 2 Apr 2026 14:18:37 +0000 [thread overview]
Message-ID: <20260402141839.461257-12-huiwen.he@linux.dev> (raw)
In-Reply-To: <20260402141839.461257-1-huiwen.he@linux.dev>
From: Huiwen He <hehuiwen@kylinos.cn>
Currently, map_smb_to_linux_error() uses linear searches for both
mapping_table_ERRDOS[] and mapping_table_ERRSRV[].
Refactor this by introducing search_mapping_table_ERRDOS() and
search_mapping_table_ERRSRV() that implements binary search(as the tables
are sorted).This improves lookup performance and reduces code duplication.
Also remove the sentinel entries from the mapping tables as they are no
longer needed with ARRAY_SIZE().
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
---
fs/smb/client/smb1maperror.c | 67 ++++++++++++++++++++----------------
1 file changed, 37 insertions(+), 30 deletions(-)
diff --git a/fs/smb/client/smb1maperror.c b/fs/smb/client/smb1maperror.c
index 294ac9646bff..28e1c84fa83b 100644
--- a/fs/smb/client/smb1maperror.c
+++ b/fs/smb/client/smb1maperror.c
@@ -9,6 +9,7 @@
* Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
*/
+#include <linux/bsearch.h>
#include "cifsproto.h"
#include "smb1proto.h"
#include "smberr.h"
@@ -20,13 +21,24 @@ struct smb_to_posix_error {
int posix_code;
};
+static __always_inline int smb1_posix_error_cmp(const void *_key, const void *_pivot)
+{
+ __u16 key = *(__u16 *)_key;
+ const struct smb_to_posix_error *pivot = _pivot;
+
+ if (key < pivot->smb_err)
+ return -1;
+ if (key > pivot->smb_err)
+ return 1;
+ return 0;
+}
+
static const struct smb_to_posix_error mapping_table_ERRDOS[] = {
/*
* Automatically generated by the `gen_smb1_mapping` script,
* sorted by DOS error code (ascending).
*/
#include "smb1_err_dos_map.c"
- {0, 0}
};
static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
@@ -35,7 +47,6 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
* sorted by SRV error code (ascending).
*/
#include "smb1_err_srv_map.c"
- {0, 0}
};
/*****************************************************************************
@@ -72,14 +83,32 @@ search_ntstatus_to_dos_map(__u32 ntstatus)
ntstatus_to_dos_cmp);
}
+static const struct smb_to_posix_error *
+search_mapping_table_ERRDOS(__u16 smb_err)
+{
+ return __inline_bsearch(&smb_err, mapping_table_ERRDOS,
+ ARRAY_SIZE(mapping_table_ERRDOS),
+ sizeof(struct smb_to_posix_error),
+ smb1_posix_error_cmp);
+}
+
+static const struct smb_to_posix_error *
+search_mapping_table_ERRSRV(__u16 smb_err)
+{
+ return __inline_bsearch(&smb_err, mapping_table_ERRSRV,
+ ARRAY_SIZE(mapping_table_ERRSRV),
+ sizeof(struct smb_to_posix_error),
+ smb1_posix_error_cmp);
+}
+
int
map_smb_to_linux_error(char *buf, bool logErr)
{
struct smb_hdr *smb = (struct smb_hdr *)buf;
- unsigned int i;
int rc = -EIO; /* if transport error smb error may not be set */
__u8 smberrclass;
__u16 smberrcode;
+ const struct smb_to_posix_error *err_map = NULL;
/* BB if NT Status codes - map NT BB */
@@ -112,38 +141,16 @@ map_smb_to_linux_error(char *buf, bool logErr)
/* old style errors */
- /* DOS class smb error codes - map DOS */
if (smberrclass == ERRDOS) {
+ /* DOS class smb error codes - map DOS */
/* 1 byte field no need to byte reverse */
- for (i = 0;
- i <
- sizeof(mapping_table_ERRDOS) /
- sizeof(struct smb_to_posix_error); i++) {
- if (mapping_table_ERRDOS[i].smb_err == 0)
- break;
- else if (mapping_table_ERRDOS[i].smb_err ==
- smberrcode) {
- rc = mapping_table_ERRDOS[i].posix_code;
- break;
- }
- /* else try next error mapping one to see if match */
- }
+ err_map = search_mapping_table_ERRDOS(smberrcode);
} else if (smberrclass == ERRSRV) {
/* server class of error codes */
- for (i = 0;
- i <
- sizeof(mapping_table_ERRSRV) /
- sizeof(struct smb_to_posix_error); i++) {
- if (mapping_table_ERRSRV[i].smb_err == 0)
- break;
- else if (mapping_table_ERRSRV[i].smb_err ==
- smberrcode) {
- rc = mapping_table_ERRSRV[i].posix_code;
- break;
- }
- /* else try next error mapping to see if match */
- }
+ err_map = search_mapping_table_ERRSRV(smberrcode);
}
+ if (err_map)
+ rc = err_map->posix_code;
/* else ERRHRD class errors or junk - return EIO */
/* special cases for NT status codes which cannot be translated to DOS codes */
--
2.53.0
next prev parent reply other threads:[~2026-04-02 14:20 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-02 14:18 [PATCH v3 00/13] smb: improve search speed of SMB1 maperror huiwen.he
2026-04-02 14:18 ` [PATCH v3 01/13] smb/client: annotate nterr.h with DOS error codes huiwen.he
2026-04-02 22:35 ` Steve French
2026-04-02 14:18 ` [PATCH v3 02/13] smb/client: autogenerate SMB1 NT status to DOS error mapping huiwen.he
2026-04-02 14:18 ` [PATCH v3 03/13] smb/client: replace nt_errs with ntstatus_to_dos_map huiwen.he
2026-04-02 14:18 ` [PATCH v3 04/13] smb/client: refactor ntstatus_to_dos() to return mapping entry huiwen.he
2026-04-02 14:18 ` [PATCH v3 05/13] smb/client: use binary search for NT status to DOS mapping huiwen.he
2026-04-02 14:18 ` [PATCH v3 06/13] smb/client: check if ntstatus_to_dos_map is sorted huiwen.he
2026-04-02 14:18 ` [PATCH v3 07/13] smb/client: introduce KUnit test to check ntstatus_to_dos_map search huiwen.he
2026-04-02 14:18 ` [PATCH v3 08/13] smb/client: move ERRnetlogonNotStarted to DOS error class huiwen.he
2026-04-02 14:18 ` [PATCH v3 09/13] smb/client: annotate smberr.h with POSIX error codes huiwen.he
2026-04-02 14:18 ` [PATCH v3 10/13] smb/client: autogenerate SMB1 DOS/SRV to POSIX error mapping huiwen.he
2026-04-02 14:18 ` huiwen.he [this message]
2026-04-02 14:18 ` [PATCH v3 12/13] smb/client: check if SMB1 DOS/SRV error mapping arrays are sorted huiwen.he
2026-04-02 14:18 ` [PATCH v3 13/13] smb/client: introduce KUnit tests to check DOS/SRV err mapping search huiwen.he
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260402141839.461257-12-huiwen.he@linux.dev \
--to=huiwen.he@linux.dev \
--cc=chenxiaosong@chenxiaosong.com \
--cc=chenxiaosong@kylinos.cn \
--cc=dhowells@redhat.com \
--cc=hehuiwen@kylinos.cn \
--cc=linkinjeon@kernel.org \
--cc=linux-cifs@vger.kernel.org \
--cc=smfrench@gmail.com \
--cc=tangyouling@kylinos.cn \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox