[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251208062100.3268777-9-chenxiaosong.chenxiaosong@linux.dev>
Date: Mon, 8 Dec 2025 14:20:38 +0800
From: chenxiaosong.chenxiaosong@...ux.dev
To: sfrench@...ba.org,
smfrench@...il.com,
linkinjeon@...nel.org,
linkinjeon@...ba.org
Cc: linux-cifs@...r.kernel.org,
linux-kernel@...r.kernel.org,
liuzhengyuan@...inos.cn,
huhai@...inos.cn,
liuyun01@...inos.cn,
ChenXiaoSong <chenxiaosong@...inos.cn>
Subject: [PATCH 08/30] smb/client: sort ntstatus_to_dos_map array
From: ChenXiaoSong <chenxiaosong@...inos.cn>
Sort the array in ascending order, and then we can use binary search
algorithm to quickly find the target NT error code.
The array is sorted only once in smb1_init_maperror() when cifs.ko
is loaded.
Signed-off-by: ChenXiaoSong <chenxiaosong@...inos.cn>
---
fs/smb/client/cifsfs.c | 2 ++
fs/smb/client/cifsproto.h | 1 +
fs/smb/client/netmisc.c | 20 ++++++++++++++++++--
3 files changed, 21 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 77d14b3dd650..3e3affce585e 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -49,6 +49,7 @@
#endif
#include "fs_context.h"
#include "cached_dir.h"
+#include "cifsproto.h"
#include "smb2proto.h"
/*
@@ -1909,6 +1910,7 @@ static int __init
init_cifs(void)
{
int rc = 0;
+ smb_init_maperror();
smb2_init_maperror();
cifs_proc_init();
INIT_LIST_HEAD(&cifs_tcp_ses_list);
diff --git a/fs/smb/client/cifsproto.h b/fs/smb/client/cifsproto.h
index 3528c365a452..675413d701b3 100644
--- a/fs/smb/client/cifsproto.h
+++ b/fs/smb/client/cifsproto.h
@@ -188,6 +188,7 @@ extern int cifs_convert_address(struct sockaddr *dst, const char *src, int len);
extern void cifs_set_port(struct sockaddr *addr, const unsigned short int port);
extern int map_smb_to_linux_error(char *buf, bool logErr);
extern int map_and_check_smb_error(struct mid_q_entry *mid, bool logErr);
+extern void smb_init_maperror(void);
extern void header_assemble(struct smb_hdr *, char /* command */ ,
const struct cifs_tcon *, int /* length of
fixed section (word count) in two byte units */);
diff --git a/fs/smb/client/netmisc.c b/fs/smb/client/netmisc.c
index 73c40ae91607..54ede1db2c7f 100644
--- a/fs/smb/client/netmisc.c
+++ b/fs/smb/client/netmisc.c
@@ -16,6 +16,7 @@
#include <asm/div64.h>
#include <asm/byteorder.h>
#include <linux/inet.h>
+#include <linux/sort.h>
#include "cifsfs.h"
#include "cifspdu.h"
#include "cifsglob.h"
@@ -216,11 +217,13 @@ cifs_set_port(struct sockaddr *addr, const unsigned short int port)
convert a NT status code to a dos class/code
*****************************************************************************/
/* NT status -> dos error map */
-static const struct {
+struct ntstatus_to_dos {
__u8 dos_class;
__u16 dos_code;
__u32 ntstatus;
-} ntstatus_to_dos_map[] = {
+};
+
+static struct ntstatus_to_dos ntstatus_to_dos_map[] = {
{
ERRDOS, ERRgeneral, NT_STATUS_UNSUCCESSFUL}, {
ERRDOS, ERRbadfunc, NT_STATUS_NOT_IMPLEMENTED}, {
@@ -778,6 +781,12 @@ static const struct {
0, 0, 0 }
};
+static unsigned int ntstatus_to_dos_num = sizeof(ntstatus_to_dos_map) /
+ sizeof(struct ntstatus_to_dos);
+
+/* cmp_ntstatus_to_dos */
+DEFINE_CMP_FUNC(ntstatus_to_dos, ntstatus);
+
/*****************************************************************************
Print an error message from the status code
*****************************************************************************/
@@ -1040,3 +1049,10 @@ struct timespec64 cnvrtDosUnixTm(__le16 le_date, __le16 le_time, int offset)
ts.tv_nsec = 0;
return ts;
}
+
+void smb_init_maperror(void)
+{
+ /* Sort in ascending order */
+ sort(ntstatus_to_dos_map, ntstatus_to_dos_num,
+ sizeof(struct ntstatus_to_dos), cmp_ntstatus_to_dos, NULL);
+}
--
2.43.0
Powered by blists - more mailing lists