mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 15:41:52 +02:00
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>
This commit is contained in:
parent
453382f15b
commit
75563adbb9
|
|
@ -30,13 +30,36 @@ static const struct status_to_posix_error smb2_error_map_table[] = {
|
|||
#include "smb2_mapping_table.c"
|
||||
};
|
||||
|
||||
static __always_inline int cmp_smb2_status(const void *_key, const void *_pivot)
|
||||
{
|
||||
__u32 key = *(__u32 *)_key;
|
||||
const struct status_to_posix_error *pivot = _pivot;
|
||||
|
||||
if (key < pivot->smb2_status)
|
||||
return -1;
|
||||
if (key > pivot->smb2_status)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct status_to_posix_error *smb2_get_err_map(__u32 smb2_status)
|
||||
{
|
||||
const struct status_to_posix_error *err_map;
|
||||
|
||||
err_map = __inline_bsearch(&smb2_status, smb2_error_map_table,
|
||||
ARRAY_SIZE(smb2_error_map_table),
|
||||
sizeof(struct status_to_posix_error),
|
||||
cmp_smb2_status);
|
||||
return err_map;
|
||||
}
|
||||
|
||||
int
|
||||
map_smb2_to_linux_error(char *buf, bool log_err)
|
||||
{
|
||||
struct smb2_hdr *shdr = (struct smb2_hdr *)buf;
|
||||
unsigned int i;
|
||||
int rc = -EIO;
|
||||
__le32 smb2err = shdr->Status;
|
||||
const struct status_to_posix_error *err_map;
|
||||
|
||||
if (smb2err == 0) {
|
||||
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)
|
|||
(smb2err != STATUS_END_OF_FILE)) ||
|
||||
(cifsFYI & CIFS_RC);
|
||||
|
||||
for (i = 0; i < sizeof(smb2_error_map_table) /
|
||||
sizeof(struct status_to_posix_error); i++) {
|
||||
if (smb2_error_map_table[i].smb2_status == smb2err) {
|
||||
if (log_err)
|
||||
pr_notice("Status code returned 0x%08x %s\n", smb2err,
|
||||
smb2_error_map_table[i].status_string);
|
||||
rc = smb2_error_map_table[i].posix_error;
|
||||
break;
|
||||
}
|
||||
}
|
||||
err_map = smb2_get_err_map(le32_to_cpu(smb2err));
|
||||
if (!err_map)
|
||||
goto out;
|
||||
|
||||
rc = err_map->posix_error;
|
||||
if (log_err)
|
||||
pr_notice("Status code returned 0x%08x %s\n",
|
||||
err_map->smb2_status, err_map->status_string);
|
||||
|
||||
out:
|
||||
/* on error mapping not found - return EIO */
|
||||
|
||||
cifs_dbg(FYI, "Mapping SMB2 status code 0x%08x to POSIX err %d\n",
|
||||
__le32_to_cpu(smb2err), rc);
|
||||
le32_to_cpu(smb2err), rc);
|
||||
|
||||
trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
|
||||
le64_to_cpu(shdr->SessionId),
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user