[Crash-utility] [PATCH] Fix "dev -d" option on Linux 5.11-rc1 and later kernels

HAGIO KAZUHITO(萩尾 一仁) k-hagio-ab at nec.com
Tue Jan 19 06:03:39 UTC 2021


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 at nec.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.18.4





More information about the Crash-utility mailing list