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"