crash/0010-Fix-dev-d-option-on-Linux-5.11-rc1-and-later-kernels.patch
Lianbo Jiang 5a0c1d8fb7 Update to the latest upstream: commit <fdb41f0b6fa4>
Release crash-7.2.9-4

Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
2021-02-05 14:16:10 +08:00

111 lines
4.2 KiB
Diff

From b922a2c8aeecfe8b1033ba419b475dfd4e51ef16 Mon Sep 17 00:00:00 2001
From: Kazuhito Hagio <k-hagio-ab@nec.com>
Date: Tue, 19 Jan 2021 15:03:39 +0900
Subject: [PATCH 10/13] Fix "dev -d" option on Linux 5.11-rc1 and later kernels
Fix the "dev -d" option on Linux 5.11-rc1 and later kernels that
contains commit 0d02129e76edf91cf04fabf1efbc3a9a1f1d729a
("block: merge struct block_device and struct hd_struct").
Without the patch, the option fails with the error message
"dev: invalid structure member offset: hd_struct_dev".
Signed-off-by: Kazuhito Hagio <k-hagio-ab@nec.com>
Signed-off-by: Lianbo Jiang <lijiang@redhat.com>
---
defs.h | 2 ++
dev.c | 29 +++++++++++++++++++++++++----
symbols.c | 4 ++++
3 files changed, 31 insertions(+), 4 deletions(-)
diff --git a/defs.h b/defs.h
index e468b1d99fcf..ffbe73bfb508 100644
--- a/defs.h
+++ b/defs.h
@@ -2128,6 +2128,8 @@ struct offset_table { /* stash of commonly-used offsets */
long prb_data_ring_size_bits;
long prb_data_ring_data;
long atomic_long_t_counter;
+ long block_device_bd_device;
+ long block_device_bd_stats;
};
struct size_table { /* stash of commonly-used sizes */
diff --git a/dev.c b/dev.c
index 56e84ab9007c..effe789f38d8 100644
--- a/dev.c
+++ b/dev.c
@@ -4067,13 +4067,22 @@ get_gendisk_5(unsigned long entry)
{
unsigned long device_address;
unsigned long device_private_address;
+ unsigned long gendisk;
device_private_address = entry - OFFSET(device_private_knode_class);
readmem(device_private_address + OFFSET(device_private_device),
KVADDR, &device_address, sizeof(device_address),
"device_private.device", FAULT_ON_ERROR);
- return device_address - OFFSET(hd_struct_dev) - OFFSET(gendisk_part0);
+ if (VALID_MEMBER(hd_struct_dev))
+ return device_address - OFFSET(hd_struct_dev) - OFFSET(gendisk_part0);
+
+ /* kernel version >= 5.11 */
+ readmem(device_address - OFFSET(block_device_bd_device) +
+ OFFSET(block_device_bd_disk), KVADDR, &gendisk,
+ sizeof(ulong), "block_device.bd_disk", FAULT_ON_ERROR);
+
+ return gendisk;
}
/* 2.6.24 < kernel version <= 2.6.27 */
@@ -4290,9 +4299,19 @@ get_diskio_1(unsigned long rq, unsigned long gendisk, struct diskio *io)
io->read = count[0];
io->write = count[1];
} else {
- readmem(gendisk + OFFSET(gendisk_part0) +
- OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
- sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ if (VALID_MEMBER(hd_struct_dkstats))
+ readmem(gendisk + OFFSET(gendisk_part0) +
+ OFFSET(hd_struct_dkstats), KVADDR, &dkstats,
+ sizeof(ulong), "gendisk.part0.dkstats", FAULT_ON_ERROR);
+ else { /* kernel version >= 5.11 */
+ ulong block_device;
+ readmem(gendisk + OFFSET(gendisk_part0), KVADDR, &block_device,
+ sizeof(ulong), "gendisk.part0", FAULT_ON_ERROR);
+ readmem(block_device + OFFSET(block_device_bd_stats), KVADDR,
+ &dkstats, sizeof(ulong), "block_device.bd_stats",
+ FAULT_ON_ERROR);
+ }
+
get_one_diskio_from_dkstats(dkstats, io_counts);
io->read = io_counts[0];
@@ -4549,6 +4568,8 @@ void diskio_init(void)
MEMBER_OFFSET_INIT(gendisk_queue, "gendisk", "queue");
MEMBER_OFFSET_INIT(hd_struct_dev, "hd_struct", "__dev");
MEMBER_OFFSET_INIT(hd_struct_dkstats, "hd_struct", "dkstats");
+ MEMBER_OFFSET_INIT(block_device_bd_device, "block_device", "bd_device");
+ MEMBER_OFFSET_INIT(block_device_bd_stats, "block_device", "bd_stats");
MEMBER_OFFSET_INIT(klist_k_list, "klist", "k_list");
MEMBER_OFFSET_INIT(klist_node_n_klist, "klist_node", "n_klist");
MEMBER_OFFSET_INIT(klist_node_n_node, "klist_node", "n_node");
diff --git a/symbols.c b/symbols.c
index a51078d58e6b..ed5f731fa1b3 100644
--- a/symbols.c
+++ b/symbols.c
@@ -9291,6 +9291,10 @@ dump_offset_table(char *spec, ulong makestruct)
OFFSET(block_device_bd_list));
fprintf(fp, " block_device_bd_disk: %ld\n",
OFFSET(block_device_bd_disk));
+ fprintf(fp, " block_device_bd_device: %ld\n",
+ OFFSET(block_device_bd_device));
+ fprintf(fp, " block_device_bd_stats: %ld\n",
+ OFFSET(block_device_bd_stats));
fprintf(fp, " address_space_nrpages: %ld\n",
OFFSET(address_space_nrpages));
fprintf(fp, " address_space_page_tree: %ld\n",
--
2.17.1