mirror of
https://github.com/torvalds/linux.git
synced 2026-03-07 23:24:35 +01:00
Build the SMB2 maperror KUnit tests as `smb2maperror_test.ko`. Link: https://lore.kernel.org/linux-cifs/20260210081040.4156383-1-geert@linux-m68k.org/ Suggested-by: Geert Uytterhoeven <geert@linux-m68k.org> Acked-by: Paulo Alcantara (Red Hat) <pc@manguebit.org> Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn> Signed-off-by: Steve French <stfrench@microsoft.com>
126 lines
3.3 KiB
C
126 lines
3.3 KiB
C
// SPDX-License-Identifier: LGPL-2.1
|
|
/*
|
|
*
|
|
* Functions which do error mapping of SMB2 status codes to POSIX errors
|
|
*
|
|
* Copyright (C) International Business Machines Corp., 2009
|
|
* Author(s): Steve French (sfrench@us.ibm.com)
|
|
*
|
|
*/
|
|
#include <linux/errno.h>
|
|
#include "cifsproto.h"
|
|
#include "cifs_debug.h"
|
|
#include "smb2proto.h"
|
|
#include "smb2glob.h"
|
|
#include "../common/smb2status.h"
|
|
#include "trace.h"
|
|
|
|
static const struct status_to_posix_error smb2_error_map_table[] = {
|
|
/*
|
|
* Automatically generated by the `gen_smb2_mapping` script,
|
|
* sorted by NT status code (cpu-endian, ascending)
|
|
*/
|
|
#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;
|
|
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),
|
|
le64_to_cpu(shdr->SessionId),
|
|
le16_to_cpu(shdr->Command),
|
|
le64_to_cpu(shdr->MessageId));
|
|
return 0;
|
|
}
|
|
|
|
log_err = (log_err && (smb2err != STATUS_MORE_PROCESSING_REQUIRED) &&
|
|
(smb2err != STATUS_END_OF_FILE)) ||
|
|
(cifsFYI & CIFS_RC);
|
|
|
|
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);
|
|
|
|
trace_smb3_cmd_err(le32_to_cpu(shdr->Id.SyncId.TreeId),
|
|
le64_to_cpu(shdr->SessionId),
|
|
le16_to_cpu(shdr->Command),
|
|
le64_to_cpu(shdr->MessageId),
|
|
le32_to_cpu(smb2err), rc);
|
|
if (rc == -EIO)
|
|
smb_EIO1(smb_eio_trace_smb2_received_error, le32_to_cpu(smb2err));
|
|
return rc;
|
|
}
|
|
|
|
int __init smb2_init_maperror(void)
|
|
{
|
|
unsigned int i;
|
|
|
|
/* Check whether the array is sorted in ascending order */
|
|
for (i = 1; i < ARRAY_SIZE(smb2_error_map_table); i++) {
|
|
if (smb2_error_map_table[i].smb2_status >=
|
|
smb2_error_map_table[i - 1].smb2_status)
|
|
continue;
|
|
|
|
pr_err("smb2_error_map_table array order is incorrect\n");
|
|
return -EINVAL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#if IS_ENABLED(CONFIG_SMB_KUNIT_TESTS)
|
|
/* Previous prototype for eliminating the build warning. */
|
|
const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status);
|
|
|
|
const struct status_to_posix_error *smb2_get_err_map_test(__u32 smb2_status)
|
|
{
|
|
return smb2_get_err_map(smb2_status);
|
|
}
|
|
EXPORT_SYMBOL_GPL(smb2_get_err_map_test);
|
|
|
|
const struct status_to_posix_error *smb2_error_map_table_test = smb2_error_map_table;
|
|
EXPORT_SYMBOL_GPL(smb2_error_map_table_test);
|
|
|
|
unsigned int smb2_error_map_num = ARRAY_SIZE(smb2_error_map_table);
|
|
EXPORT_SYMBOL_GPL(smb2_error_map_num);
|
|
#endif
|