Commit c527e13a authored by David Howells's avatar David Howells Committed by Steve French
Browse files

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: default avatarDavid Howells <dhowells@redhat.com>
cc: Steve French <stfrench@microsoft.com>
cc: ChenXiaoSong <chenxiaosong@kylinos.cn>
cc: linux-cifs@vger.kernel.org
Signed-off-by: default avatarChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: default avatarDavid Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/linux-cifs/20260106071507.1420900-3-chenxiaosong.chenxiaosong@linux.dev/


Signed-off-by: default avatarSteve French <stfrench@microsoft.com>
parent 10dfb073
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -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
+86 −0
Original line number Diff line number Diff line
#!/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;
+6 −2396

File changed.

Preview size limit exceeded, changes collapsed.

+6 −0
Original line number Diff line number Diff line
@@ -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