summaryrefslogtreecommitdiffstats
path: root/scripts/extract-vmlinux
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@manguebit.org>2026-09-26 19:20:30 -0300
committerPaulo Alcantara <pc@manguebit.org>2026-09-30 14:24:12 -0300
commitdd05add7b2b6004c5fa3a1f276f56d8668f86b65 (patch)
tree23efdcaa0b8031f6ac6f57b6734d18d6c1adc6f2 /scripts/extract-vmlinux
downloadlinux-stable-dd05add7b2b6004c5fa3a1f276f56d8668f86b65.tar.gz
linux-stable-dd05add7b2b6004c5fa3a1f276f56d8668f86b65.zip
netfs: zero the tail of a short DIO/unbuffered readgrafted
The buffered read collector zero-fills the tail of a short read that stops below the inode's i_size (netfs_clear_unread()), so a read that races an extending write still returns the expected number of bytes. The non-buffered collector path does no such thing: it just records how much was transferred. Add the same zero-fill for the non-buffered case, gated on NETFS_SREQ_CLEAR_TAIL: a subreq's source sets that flag when a short result from it is known to be safe to treat as a hole, as opposed to NETFS_SREQ_HIT_EOF, which means the read genuinely ran off the end of the file and should be reported short as-is. Only CLEAR_TAIL should zero-fill here; a real EOF must stay a real short read. No source currently sets CLEAR_TAIL on an unbuffered/DIO subrequest, so this is inert on its own -- a following change teaches cifs to set it in the one case that needs it. Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item") Reviewed-by: David Howells <dhowells@redhat.com> Reviewed-by: Namjae Jeon <linkinjeon@kernel.org> Signed-off-by: Paulo Alcantara <pc@manguebit.org> Cc: Christian Brauner <brauner@kernel.org> Cc: Matthew Wilcox <willy@infradead.org> Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com> Cc: Shyam Prasad N <sprasad@microsoft.com> Cc: Tom Talpey <tom@talpey.com> Cc: Bharath SM <bharathsm@microsoft.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'scripts/extract-vmlinux')
-rwxr-xr-xscripts/extract-vmlinux65
1 files changed, 65 insertions, 0 deletions
diff --git a/scripts/extract-vmlinux b/scripts/extract-vmlinux
new file mode 100755
index 000000000..266df9bc7
--- /dev/null
+++ b/scripts/extract-vmlinux
@@ -0,0 +1,65 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-only
+# ----------------------------------------------------------------------
+# extract-vmlinux - Extract uncompressed vmlinux from a kernel image
+#
+# Inspired from extract-ikconfig
+# (c) 2009,2010 Dick Streefland <dick@streefland.net>
+#
+# (c) 2011 Corentin Chary <corentin.chary@gmail.com>
+#
+# ----------------------------------------------------------------------
+
+me=${0##*/}
+
+check_vmlinux()
+{
+ if file "$1" | grep -q 'Linux kernel.*boot executable' ||
+ readelf -h "$1" > /dev/null 2>&1
+ then
+ cat "$1"
+ echo "$me: Extracted vmlinux using '$2' from offset $3" >&2
+ exit 0
+ fi
+}
+
+try_decompress()
+{
+ # The obscure use of the "tr" filter is to work around older versions of
+ # "grep" that report the byte offset of the line instead of the pattern.
+
+ # Try to find the header ($1) and decompress from here
+ for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
+ do
+ pos=${pos%%:*}
+ tail -c+$pos "$img" | $3 > $tmp 2> /dev/null
+ check_vmlinux $tmp "$3" $pos
+ done
+}
+
+# Check invocation:
+img=$1
+if [ $# -ne 1 -o ! -s "$img" ]
+then
+ echo "Usage: $me <kernel-image>" >&2
+ exit 2
+fi
+
+# Prepare temp files:
+tmp=$(mktemp /tmp/vmlinux-XXX)
+trap "rm -f $tmp" 0
+
+# That didn't work, so retry after decompression.
+try_decompress '\037\213\010' xy gunzip
+try_decompress '\3757zXZ\000' abcde unxz
+try_decompress 'BZh' xy bunzip2
+try_decompress '\135\0\0\0' xxx unlzma
+try_decompress '\211\114\132' xy 'lzop -d'
+try_decompress '\002!L\030' xxx 'lz4 -d'
+try_decompress '(\265/\375' xxx unzstd
+
+# Finally check for uncompressed images or objects:
+check_vmlinux "$img" cat 0
+
+# Bail out:
+echo "$me: Cannot find vmlinux." >&2