From 487b52c2f9f0c341d515f08491fcc24ba05211b2 Mon Sep 17 00:00:00 2001 From: Gleb Chesnokov Date: Wed, 26 Aug 2026 14:59:08 +0300 Subject: [PATCH] scripts/specialize-patch: Rebuild filtered hunks The regression became visible after commit 91517609cdf8 ("scripts/generate-kernel-patch: Preserve split patches") preserved split output that had previously been empty without diffstat. specialize-patch kept the original hunk coordinates after dropping version-dependent lines, so GNU patch rejected the generated qla.h patch. Recalculate hunk coordinates and context after specialization removes added lines. This prevents GNU patch from rejecting QLogic qla.h hunks for Linux 7.1 and 7.2. Add a focused regression test for the normal and matching-line-number specialization modes. --- scripts/specialize-patch | 43 +++++++++++-- scripts/test-specialize-patch | 116 ++++++++++++++++++++++++++++++++++ 2 files changed, 154 insertions(+), 5 deletions(-) create mode 100755 scripts/test-specialize-patch diff --git a/scripts/specialize-patch b/scripts/specialize-patch index bca31f5cb..7aa0dee57 100755 --- a/scripts/specialize-patch +++ b/scripts/specialize-patch @@ -613,21 +613,48 @@ function reset_hunk_state_variables() { function dump_lines() { # Detect empty hunks first_modif = -1 + last_modif = -1 for (i = 0; i < lines; i++) { if (line[i] ~ "^[+-]") { - first_modif = i - break + if (first_modif < 0) + first_modif = i + last_modif = i } } # Dump line[] as a hunk, but only if the hunk is not empty. if (first_modif >= 0) { - if (h[0] != "") - printf "@@ -%d,%d +%d,%d @@%s\n",h[1],h[2]-lines_less_deleted,h[3],h[4]-lines_less_added,h[5] - for (i = 0; i < lines; i++) { + # Restore standard unified diff context after discarding added lines. + first_line = first_modif > context_lines ? first_modif - context_lines : 0 + last_line = last_modif + context_lines < lines ? \ + last_modif + context_lines : lines - 1 + + if (h[0] != "") { + old_start = h[1] + new_start = h[3] + new_line_adjustment + for (i = 0; i < first_line; i++) { + if (line[i] !~ "^\\+" && line[i] !~ "^\\\\") + old_start++ + if (line[i] !~ "^-" && line[i] !~ "^\\\\") + new_start++ + } + + old_count = 0 + new_count = 0 + for (i = first_line; i <= last_line; i++) { + if (line[i] !~ "^\\+" && line[i] !~ "^\\\\") + old_count++ + if (line[i] !~ "^-" && line[i] !~ "^\\\\") + new_count++ + } + + printf "@@ -%d,%d +%d,%d @@%s\n", old_start, old_count, \ + new_start, new_count, h[5] + } + for (i = first_line; i <= last_line; i++) { modifier = (LINUX_VERSION_CODE < version_code("4.19.0") && (RHEL_MAJOR == "" || RHEL_MAJOR * 256 + RHEL_MINOR < 7 * 256 + 7 || @@ -638,6 +665,9 @@ function dump_lines() { print line[i] } } + + if (h[0] != "") + new_line_adjustment += lines_less_deleted - lines_less_added } BEGIN { @@ -660,6 +690,7 @@ BEGIN { if (config_tcp_zero_copy_transfer_completion_notification_undefined != 0 && config_tcp_zero_copy_transfer_completion_notification_undefined != 1) config_tcp_zero_copy_transfer_completion_notification_undefined = 0 # Variable initialization. + context_lines = 3 process_file = 0 reset_hunk_state_variables() } @@ -667,11 +698,13 @@ BEGIN { { if (match($0, "^diff[ \t]+[^ \t]+[ \t]+[^ \t]+[ \t]+([^ \t]+)$", filename) \ + || match($0, "^---[ \t]+([^ \t]+)[ \t]+", filename) \ || match($0, "^\\+\\+\\+[ \t]+([^ \t]+)[ \t]+", filename)) { # Start of new file. dump_lines() reset_hunk_state_variables() + new_line_adjustment = 0 process_file = match(filename[1], "\\.[ch]$") != 0 && match(filename[1], "drivers/scsi/qla2xxx/") == 0 } diff --git a/scripts/test-specialize-patch b/scripts/test-specialize-patch new file mode 100755 index 000000000..161a600a6 --- /dev/null +++ b/scripts/test-specialize-patch @@ -0,0 +1,116 @@ +#!/bin/bash + +set -euo pipefail + +script_dir="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)" +scst_dir="$(dirname -- "$script_dir")" +test_dir="$(mktemp -d)" + +trap 'rm -rf -- "$test_dir"' EXIT + +mkdir -p "$test_dir/orig" + +cat > "$test_dir/orig/qla.h" <<'EOF' +/* SPDX-License-Identifier: GPL-2.0 */ +#if !defined(_TRACE_QLA_H_) || defined(TRACE_HEADER_MULTI_READ) +#define _TRACE_QLA_H_ + +#include + +#undef TRACE_SYSTEM +#define TRACE_SYSTEM qla + +#define QLA_MSG_MAX 256 + +#pragma GCC diagnostic push +#ifndef __clang__ +#pragma GCC diagnostic ignored "-Wsuggest-attribute=format" +#endif + +DECLARE_EVENT_CLASS(qla_log_event, + TP_PROTO(const char *buf, + struct va_format *vaf), + + TP_ARGS(buf, vaf), + + TP_STRUCT__entry( + __string(buf, buf) + __vstring(msg, vaf->fmt, vaf->va) + ), + TP_fast_assign( + __assign_str(buf); + __assign_vstr(msg, vaf->fmt, vaf->va); + ), + + TP_printk("%s %s", __get_str(buf), __get_str(msg)) +); + +#pragma GCC diagnostic pop + +DEFINE_EVENT(qla_log_event, ql_dbg_log, + TP_PROTO(const char *buf, struct va_format *vaf), + TP_ARGS(buf, vaf) +); + +#endif /* _TRACE_QLA_H */ + +#define TRACE_INCLUDE_FILE qla + +#include +EOF + +if diff -up "$test_dir/orig/qla.h" \ + "$scst_dir/qla2x00t-32gbit/include/trace/events/qla.h" \ + > "$test_dir/qla.raw.patch"; then + echo "Error: qla.h test inputs do not differ." >&2 + exit 1 +else + diff_status=$? + if [ "$diff_status" -gt 1 ]; then + exit "$diff_status" + fi +fi + +for kernel_version in 7.1 7.2; do + mkdir -p "$test_dir/linux-$kernel_version/include/trace/events" + cp "$test_dir/orig/qla.h" \ + "$test_dir/linux-$kernel_version/include/trace/events/qla.h" + + sed -e "s:^--- [^ ]*:--- linux-$kernel_version/include/trace/events/qla.h:" \ + -e "s:^+++ [^ ]*:+++ linux-$kernel_version/include/trace/events/qla.h:" \ + < "$test_dir/qla.raw.patch" > "$test_dir/qla-$kernel_version.patch" + + cat >> "$test_dir/qla-$kernel_version.patch" < "$test_dir/linux-$kernel_version/drivers/scst/next.c" + + "$script_dir/specialize-patch" -v delete_disabled_code=1 \ + -v kernel_version="$kernel_version" -v SCST_IO_CONTEXT=0 \ + < "$test_dir/qla-$kernel_version.patch" \ + > "$test_dir/qla-$kernel_version.specialized.patch" + + grep -qF '@@ -9,8 +9,8 @@' \ + "$test_dir/qla-$kernel_version.specialized.patch" + grep -qF '@@ -32,13 +32,15 @@' \ + "$test_dir/qla-$kernel_version.specialized.patch" + + patch --dry-run -f -s -p0 -d "$test_dir" \ + < "$test_dir/qla-$kernel_version.specialized.patch" + + "$script_dir/specialize-patch" -v blank_deleted_code=1 \ + -v kernel_version="$kernel_version" -v SCST_IO_CONTEXT=0 \ + < "$test_dir/qla-$kernel_version.patch" \ + > "$test_dir/qla-$kernel_version.specialized-n.patch" + + patch --dry-run -f -s -p0 -d "$test_dir" \ + < "$test_dir/qla-$kernel_version.specialized-n.patch" +done + +echo "specialize-patch qla.h regression: PASS"