]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
smb/client: use binary search for NT status to DOS mapping
authorHuiwen He <hehuiwen@kylinos.cn>
Thu, 2 Apr 2026 14:18:31 +0000 (14:18 +0000)
committerSteve French <stfrench@microsoft.com>
Mon, 6 Apr 2026 00:58:40 +0000 (19:58 -0500)
The ntstatus_to_dos_map[] table is sorted now. Replace the linear search
with binary search to improve lookup performance.

Also remove the sentinel entry as it is no longer needed with ARRAY_SIZE().

Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/smb/client/smb1maperror.c

index c906f233ac6454c9b22fd5ae74529e49d845951f..fb985d2fc0d97b1121795f827f042bd86d0945c2 100644 (file)
@@ -106,6 +106,19 @@ static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
 /*****************************************************************************
  *convert a NT status code to a dos class/code
  *****************************************************************************/
+
+static __always_inline int ntstatus_to_dos_cmp(const void *_key, const void *_pivot)
+{
+       __u32 key = *(__u32 *)_key;
+       const struct ntstatus_to_dos_err *pivot = _pivot;
+
+       if (key < pivot->ntstatus)
+               return -1;
+       if (key > pivot->ntstatus)
+               return 1;
+       return 0;
+}
+
 /* NT status -> dos error map */
 static const struct ntstatus_to_dos_err ntstatus_to_dos_map[] = {
 /*
@@ -113,22 +126,15 @@ static const struct ntstatus_to_dos_err ntstatus_to_dos_map[] = {
  * sorted by NT status code (ascending).
  */
 #include "smb1_mapping_table.c"
-       {0, 0, 0, NULL}
 };
 
 static const struct ntstatus_to_dos_err *
-ntstatus_to_dos(__u32 ntstatus)
+search_ntstatus_to_dos_map(__u32 ntstatus)
 {
-       int i;
-
-       /* Check nt_errstr to allow mapping of NT_STATUS_OK (0) */
-       for (i = 0; ntstatus_to_dos_map[i].nt_errstr; i++) {
-               if (ntstatus == ntstatus_to_dos_map[i].ntstatus) {
-                       return &ntstatus_to_dos_map[i];
-               }
-       }
-
-       return NULL;
+       return __inline_bsearch(&ntstatus, ntstatus_to_dos_map,
+                               ARRAY_SIZE(ntstatus_to_dos_map),
+                               sizeof(struct ntstatus_to_dos_err),
+                               ntstatus_to_dos_cmp);
 }
 
 int
@@ -150,7 +156,7 @@ map_smb_to_linux_error(char *buf, bool logErr)
                /* translate the newer STATUS codes to old style SMB errors
                 * and then to POSIX errors */
                __u32 err = le32_to_cpu(smb->Status.CifsError);
-               const struct ntstatus_to_dos_err *map = ntstatus_to_dos(err);
+               const struct ntstatus_to_dos_err *map = search_ntstatus_to_dos_map(err);
 
                if (map) {
                        if ((logErr && err != NT_STATUS_MORE_PROCESSING_REQUIRED) ||