* Copyright (C) Luke Kenneth Casson Leighton 1997-2001.
*/
+#include <linux/bsearch.h>
#include "cifsproto.h"
#include "smb1proto.h"
#include "smberr.h"
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[] = {
* sorted by SRV error code (ascending).
*/
#include "smb1_err_srv_map.c"
- {0, 0}
};
/*****************************************************************************
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 */
/* 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 */