cifs: Autogenerate SMB2 error mapping table

Autogenerate the SMB2 status to error code mapping table, from the
smb2status.h common header, sorting it by NT status code so that it can be
searched by binary chopping. This also reduces the number of places this
list is duplicated in the source.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Steve French <stfrench@microsoft.com>
cc: ChenXiaoSong <chenxiaosong@kylinos.cn>
cc: linux-cifs@vger.kernel.org
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/linux-cifs/20260106071507.1420900-3-chenxiaosong.chenxiaosong@linux.dev/
Signed-off-by: Steve French <stfrench@microsoft.com>
master
David Howells 2025-12-23 00:05:34 +00:00 committed by Steve French
parent 10dfb0738a
commit c527e13a7a
4 changed files with 112 additions and 2396 deletions

View File

@ -43,3 +43,17 @@ cifs-$(CONFIG_CIFS_ALLOW_INSECURE_LEGACY) += \
smb1transport.o
cifs-$(CONFIG_CIFS_COMPRESSION) += compress.o compress/lz77.o
#
# Build the SMB2 error mapping table from smb2status.h
#
$(obj)/smb2_mapping_table.c: $(src)/../common/smb2status.h \
$(src)/gen_smb2_mapping
$(call cmd,gen_smb2_mapping)
$(obj)/smb2maperror.o: $(obj)/smb2_mapping_table.c
quiet_cmd_gen_smb2_mapping = GEN $@
cmd_gen_smb2_mapping = perl $(src)/gen_smb2_mapping $< $@
clean-files += smb2_mapping_table.c

View File

@ -0,0 +1,86 @@
#!/usr/bin/perl -w
# SPDX-License-Identifier: GPL-2.0-or-later
#
# Generate an SMB2 status -> error mapping table,
# sorted by NT status code (cpu-endian, ascending).
#
# Copyright (C) 2025 Red Hat, Inc. All Rights Reserved.
# Written by David Howells (dhowells@redhat.com)
#
use strict;
if ($#ARGV != 1) {
print STDERR "Format: ", $0, " <in-h-file> <out-c-file>\n";
exit(2);
}
my %statuses = ();
my @list = ();
#
# Read the file
#
open IN_FILE, "<$ARGV[0]" || die;
while (<IN_FILE>) {
chomp;
if (m!^#define\s*([A-Za-z0-9_]+)\s+cpu_to_le32[(]([0-9a-fA-Fx]+)[)]\s+//\s+([-A-Z0-9_]+)!) {
my $status = $1;
my $code = $2;
my $ncode = hex($2);
my $error = $3;
my $s;
next if ($status =~ /^STATUS_SEVERITY/);
die "Duplicate status $status"
if exists($statuses{$status});
my %s = (
status => $status,
code => $code,
ncode => $ncode,
error => $error
);
$statuses{$status} = \%s;
push @list, \%s;
}
}
close IN_FILE || die;
@list = sort( { $a->{ncode} <=> $b->{ncode} } @list);
open OUT_FILE, ">$ARGV[1]" || die;
my $list_size = scalar @list;
my $full_status = "";
for (my $i = 0; $i < $list_size; $i++) {
my $entry = $list[$i];
my $status = $entry->{status};
my $code = $entry->{code};
my $ncode = $entry->{ncode};
my $error = $entry->{error};
next if ($ncode == 0);
$full_status .= $status;
# There may be synonyms
if ($i < $list_size - 1) {
my $next_entry = $list[$i + 1];
my $next_ncode = $next_entry->{ncode};
if ($next_ncode == $ncode) {
$full_status .= " or ";
next;
}
}
my $pad = " ";
if (length($full_status) < 40) {
my $n = 40 - length($full_status);
$pad = "\t" x ((($n-1) / 8) + 1);
}
print(OUT_FILE "{ $code, $error, \"$full_status\" },\n");
$full_status = "";
}
close OUT_FILE || die;

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,12 @@ struct ntstatus {
__le32 Code;
};
/*
* The comment at the end of each definition indicates `posix_error`
* field of `struct status_to_posix_error`, it is used to generate the
* `smb2_error_map_table` array.
*/
#define STATUS_SUCCESS cpu_to_le32(0x00000000) // 0
#define STATUS_WAIT_0 cpu_to_le32(0x00000000) // 0
#define STATUS_WAIT_1 cpu_to_le32(0x00000001) // -EIO