Skip to content

Commit 75563ad

Browse files
ChenXiaoSongsmfrench
authored andcommitted
smb/client: use bsearch() to find target in smb2_error_map_table
The smb2_error_map_table array currently has 1740 elements. When searching for the last element, the original loop-based search method requires 1740 comparisons, while binary search algorithm requires only 10 comparisons. Suggested-by: David Howells <dhowells@redhat.com> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Reviewed-by: David Howells <dhowells@redhat.com> Link: https://lore.kernel.org/linux-cifs/20260106071507.1420900-5-chenxiaosong.chenxiaosong@linux.dev/ Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: Steve French <stfrench@microsoft.com>
1 parent 453382f commit 75563ad

1 file changed

Lines changed: 34 additions & 12 deletions

File tree

fs/smb/client/smb2maperror.c

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,36 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
3030
#include "smb2_mapping_table.c"
3131
};
3232

33+
static __always_inline int cmp_smb2_status(const void *_key, const void *_pivot)
34+
{
35+
__u32 key = *(__u32 *)_key;
36+
const struct status_to_posix_error *pivot = _pivot;
37+
38+
if (key < pivot->smb2_status)
39+
return -1;
40+
if (key > pivot->smb2_status)
41+
return 1;
42+
return 0;
43+
}
44+
45+
static const struct status_to_posix_error *smb2_get_err_map(__u32 smb2_status)
46+
{
47+
const struct status_to_posix_error *err_map;
48+
49+
err_map = __inline_bsearch(&smb2_status, smb2_error_map_table,
50+
ARRAY_SIZE(smb2_error_map_table),
51+
sizeof(struct status_to_posix_error),
52+
cmp_smb2_status);
53+
return err_map;
54+
}
55+
3356
int
3457
map_smb2_to_linux_error(char *buf, bool log_err)
3558
{
3659
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
37-
unsigned int i;
3860
int rc = -EIO;
3961
__le32 smb2err = shdr->Status;
62+
const struct status_to_posix_error *err_map;
4063

4164
if (smb2err == 0) {
4265
trace_smb3_cmd_done(le32_to_cpu(shdr->Id.SyncId.TreeId),
@@ -50,21 +73,20 @@ map_smb2_to_linux_error(char *buf, bool log_err)
5073
(smb2err != STATUS_END_OF_FILE)) ||
5174
(cifsFYI & CIFS_RC);
5275

53-
for (i = 0; i < sizeof(smb2_error_map_table) /
54-
sizeof(struct status_to_posix_error); i++) {
55-
if (smb2_error_map_table[i].smb2_status == smb2err) {
56-
if (log_err)
57-
pr_notice("Status code returned 0x%08x %s\n", smb2err,
58-
smb2_error_map_table[i].status_string);
59-
rc = smb2_error_map_table[i].posix_error;
60-
break;
61-
}
62-
}
76+
err_map = smb2_get_err_map(le32_to_cpu(smb2err));
77+
if (!err_map)
78+
goto out;
79+
80+
rc = err_map->posix_error;
81+
if (log_err)
82+
pr_notice("Status code returned 0x%08x %s\n",
83+
err_map->smb2_status, err_map->status_string);
6384

85+
out:
6486
/* on error mapping not found - return EIO */
6587

6688
cifs_dbg(FYI, "Mapping SMB2 status code 0x%08x to POSIX err %d\n",
67-
__le32_to_cpu(smb2err), rc);
89+
le32_to_cpu(smb2err), rc);
6890

6991
trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
7092
le64_to_cpu(shdr->SessionId),

0 commit comments

Comments
 (0)