fix: block: remove disk_part_iter (v5.12)
authorMichael Jeanson <mjeanson@efficios.com>
Mon, 10 May 2021 15:39:24 +0000 (11:39 -0400)
committerMathieu Desnoyers <mathieu.desnoyers@efficios.com>
Wed, 12 May 2021 17:59:33 +0000 (13:59 -0400)
In v5.12 a refactoring of the genhd code was started and the symbols
related to 'disk_part_iter' were unexported. In v5.13 they were
completely removed.

This patch replaces the short lived compat code that is specific to
v5.12 and replaces it with a generic internal implementation that
iterates directly on the 'disk->part_tbl' xarray which will be used
on v5.12 and up.

This seems like a better option than keeping the compat code that will
only work on v5.12 and make maintenance more complicated. The compat was
backported to the stable branches but isn't yet part of a point release
so can be safely replaced.

See the upstream commits:

  commit 3212135a718b06be38811f2d9a320ae842e76409
  Author: Christoph Hellwig <hch@lst.de>
  Date:   Tue Apr 6 08:23:02 2021 +0200

    block: remove disk_part_iter

    Just open code the xa_for_each in the remaining user.

  commit a33df75c6328bf40078b35f2040d8e54d574c357
  Author: Christoph Hellwig <hch@lst.de>
  Date:   Sun Jan 24 11:02:41 2021 +0100

    block: use an xarray for disk->part_tbl

    Now that no fast path lookups in the partition table are left, there is
    no point in micro-optimizing the data structure for it.  Just use a bog
    standard xarray.

Signed-off-by: Michael Jeanson <mjeanson@efficios.com>
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Change-Id: I43d8ef8463cb7a83dc8859a32dc29502cd897ddf

Makefile
lttng-statedump-impl.c
wrapper/genhd.c [deleted file]
wrapper/genhd.h

index d96ce2c7b87474e543cee07b185d4f072973c345..c30580376c4215ad3a2f65584c17edc4a02df99c 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -68,7 +68,6 @@ ifneq ($(KERNELRELEASE),)
                         wrapper/kallsyms.o \
                         wrapper/irqdesc.o \
                         wrapper/fdtable.o \
-                        wrapper/genhd.o \
                         lttng-wrapper-impl.o
 
   ifneq ($(CONFIG_HAVE_SYSCALL_TRACEPOINTS),)
index 6234403cfa25a8c3c1119f65ae6cf79a95a74fbf..fc9e9db2de3ab5e4ee4ca38a52561a0ce3d6291d 100644 (file)
@@ -191,6 +191,61 @@ dev_t lttng_get_part_devt(struct hd_struct *part)
 }
 #endif
 
+#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,12,0))
+static
+int lttng_statedump_each_block_device(struct lttng_session *session, struct gendisk *disk)
+{
+       struct block_device *part;
+       unsigned long idx;
+       int ret = 0;
+
+       /* Include partition 0 */
+       idx = 0;
+
+       rcu_read_lock();
+       xa_for_each(&disk->part_tbl, idx, part) {
+               char name_buf[BDEVNAME_SIZE];
+
+               /* Exclude non-partitions bdev and empty partitions. */
+               if (bdev_is_partition(part) && !bdev_nr_sectors(part))
+                       continue;
+
+               if (lttng_get_part_name(disk, part, name_buf) == -ENOSYS) {
+                       ret = -ENOSYS;
+                       goto end;
+               }
+               trace_lttng_statedump_block_device(session, lttng_get_part_devt(part),
+                               name_buf);
+       }
+end:
+       rcu_read_unlock();
+       return ret;
+}
+#else
+static
+int lttng_statedump_each_block_device(struct lttng_session *session, struct gendisk *disk)
+{
+       struct disk_part_iter piter;
+       LTTNG_PART_STRUCT_TYPE *part;
+
+       disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0);
+
+       while ((part = disk_part_iter_next(&piter))) {
+               char name_buf[BDEVNAME_SIZE];
+
+               if (lttng_get_part_name(disk, part, name_buf) == -ENOSYS) {
+                       disk_part_iter_exit(&piter);
+                       return -ENOSYS;
+               }
+               trace_lttng_statedump_block_device(session, lttng_get_part_devt(part),
+                               name_buf);
+       }
+       disk_part_iter_exit(&piter);
+
+       return 0;
+}
+#endif
+
 static
 int lttng_enumerate_block_devices(struct lttng_session *session)
 {
@@ -212,9 +267,7 @@ int lttng_enumerate_block_devices(struct lttng_session *session)
        }
        class_dev_iter_init(&iter, ptr_block_class, NULL, ptr_disk_type);
        while ((dev = class_dev_iter_next(&iter))) {
-               struct disk_part_iter piter;
                struct gendisk *disk = dev_to_disk(dev);
-               LTTNG_PART_STRUCT_TYPE *part;
 
                /*
                 * Don't show empty devices or things that have been
@@ -224,29 +277,8 @@ int lttng_enumerate_block_devices(struct lttng_session *session)
                    (disk->flags & GENHD_FL_SUPPRESS_PARTITION_INFO))
                        continue;
 
-               /*
-                * The original 'disk_part_iter_init' returns void, but our
-                * wrapper can fail to lookup the original symbol.
-                */
-               if (wrapper_disk_part_iter_init(&piter, disk, DISK_PITER_INCL_PART0) < 0) {
-                       ret = -ENOSYS;
-                       goto iter_exit;
-               }
-
-               while ((part = wrapper_disk_part_iter_next(&piter))) {
-                       char name_buf[BDEVNAME_SIZE];
-
-                       if (lttng_get_part_name(disk, part, name_buf) == -ENOSYS) {
-                               wrapper_disk_part_iter_exit(&piter);
-                               ret = -ENOSYS;
-                               goto iter_exit;
-                       }
-                       trace_lttng_statedump_block_device(session,
-                                       lttng_get_part_devt(part), name_buf);
-               }
-               wrapper_disk_part_iter_exit(&piter);
+               ret = lttng_statedump_each_block_device(session, disk);
        }
-iter_exit:
        class_dev_iter_exit(&iter);
 end:
        return ret;
diff --git a/wrapper/genhd.c b/wrapper/genhd.c
deleted file mode 100644 (file)
index cbec06f..0000000
+++ /dev/null
@@ -1,111 +0,0 @@
-/* SPDX-License-Identifier: (GPL-2.0-only OR LGPL-2.1-only)
- *
- * wrapper/genhd.c
- *
- * Wrapper around disk_part_iter_(init|next|exit). Using KALLSYMS to get the
- * addresses when available, else we need to have a kernel that exports this
- * function to GPL modules. This export was removed in 5.12.
- *
- * Copyright (C) 2021 Michael Jeanson <mjeanson@efficios.com>
- */
-
-#include <lttng-kernel-version.h>
-#include <linux/module.h>
-#include <wrapper/genhd.h>
-
-#if (defined(CONFIG_KALLSYMS) && \
-       (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,12,0)))
-
-#include <wrapper/kallsyms.h>
-
-static
-void (*disk_part_iter_init_sym)(struct disk_part_iter *piter, struct gendisk *disk,
-                       unsigned int flags);
-
-static
-LTTNG_DISK_PART_TYPE *(*disk_part_iter_next_sym)(struct disk_part_iter *piter);
-
-static
-void (*disk_part_iter_exit_sym)(struct disk_part_iter *piter);
-
-/*
- * This wrapper has an 'int' return type instead of the original 'void', to be
- * able to report the symbol lookup failure to the caller.
- *
- * Return 0 on success, -1 on error.
- */
-int wrapper_disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
-                          unsigned int flags)
-{
-       if (!disk_part_iter_init_sym)
-               disk_part_iter_init_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_init");
-
-       if (disk_part_iter_init_sym) {
-               disk_part_iter_init_sym(piter, disk, flags);
-       } else {
-               printk_once(KERN_WARNING "LTTng: disk_part_iter_init symbol lookup failed.\n");
-               return -1;
-       }
-       return 0;
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_init);
-
-LTTNG_DISK_PART_TYPE *wrapper_disk_part_iter_next(struct disk_part_iter *piter)
-{
-       if (!disk_part_iter_next_sym)
-               disk_part_iter_next_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_next");
-
-       if (disk_part_iter_next_sym) {
-               return disk_part_iter_next_sym(piter);
-       } else {
-               printk_once(KERN_WARNING "LTTng: disk_part_iter_next symbol lookup failed.\n");
-               return NULL;
-       }
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_next);
-
-/*
- * We don't return an error on symbol lookup failure here because there is
- * nothing the caller can do to cleanup the iterator.
- */
-void wrapper_disk_part_iter_exit(struct disk_part_iter *piter)
-{
-       if (!disk_part_iter_exit_sym)
-               disk_part_iter_exit_sym = (void *) kallsyms_lookup_funcptr("disk_part_iter_exit");
-
-       if (disk_part_iter_exit_sym) {
-               disk_part_iter_exit_sym(piter);
-       } else {
-               printk_once(KERN_WARNING "LTTng: disk_part_iter_exit symbol lookup failed.\n");
-       }
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_exit);
-
-#else
-
-/*
- * This wrapper has an 'int' return type instead of the original 'void', so the
- * kallsyms variant can report the symbol lookup failure to the caller.
- *
- * This variant always succeeds and returns 0.
- */
-int wrapper_disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
-                          unsigned int flags)
-{
-       disk_part_iter_init(piter, disk, flags);
-       return 0;
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_init);
-
-LTTNG_DISK_PART_TYPE *wrapper_disk_part_iter_next(struct disk_part_iter *piter)
-{
-       return disk_part_iter_next(piter);
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_next);
-
-void wrapper_disk_part_iter_exit(struct disk_part_iter *piter)
-{
-       disk_part_iter_exit(piter);
-}
-EXPORT_SYMBOL_GPL(wrapper_disk_part_iter_exit);
-#endif
index 1b4a420167ef4c7d34b436fc9b64c56903b17c13..98feb57bebde635fb11781209ca2871a8faafa0c 100644 (file)
 #define _LTTNG_WRAPPER_GENHD_H
 
 #include <linux/genhd.h>
-#include <lttng-kernel-version.h>
-
-#if (LTTNG_LINUX_VERSION_CODE >= LTTNG_KERNEL_VERSION(5,11,0))
-#define LTTNG_DISK_PART_TYPE struct block_device
-#else
-#define LTTNG_DISK_PART_TYPE struct hd_struct
-#endif
 
 #ifdef CONFIG_KALLSYMS_ALL
 
@@ -101,59 +94,4 @@ struct device_type *wrapper_get_disk_type(void)
 
 #endif
 
-/*
- * This wrapper has an 'int' return type instead of the original 'void', to be
- * able to report the symbol lookup failure to the caller.
- *
- * Return 0 on success, -1 on error.
- */
-int wrapper_disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
-                          unsigned int flags);
-LTTNG_DISK_PART_TYPE *wrapper_disk_part_iter_next(struct disk_part_iter *piter);
-void wrapper_disk_part_iter_exit(struct disk_part_iter *piter);
-
-/*
- * Canary function to check for 'disk_part_iter_init()' at compile time.
- *
- * From 'include/linux/genhd.h':
- *
- *   extern void disk_part_iter_init(struct disk_part_iter *piter,
- *                                   struct gendisk *disk, unsigned int flags);
- *
- */
-static inline
-void __canary__disk_part_iter_init(struct disk_part_iter *piter, struct gendisk *disk,
-               unsigned int flags)
-{
-       disk_part_iter_init(piter, disk, flags);
-}
-
-/*
- * Canary function to check for 'disk_part_iter_next()' at compile time.
- *
- * From 'include/linux/genhd.h':
- *
- *   struct block_device *disk_part_iter_next(struct disk_part_iter *piter);
- *
- */
-static inline
-LTTNG_DISK_PART_TYPE *__canary__disk_part_iter_next(struct disk_part_iter *piter)
-{
-       return disk_part_iter_next(piter);
-}
-
-/*
- * Canary function to check for 'disk_part_iter_exit()' at compile time.
- *
- * From 'include/linux/genhd.h':
- *
- *   extern void disk_part_iter_exit(struct disk_part_iter *piter);
- *
- */
-static inline
-void __canary__disk_part_iter_exit(struct disk_part_iter *piter)
-{
-       return disk_part_iter_exit(piter);
-}
-
 #endif /* _LTTNG_WRAPPER_GENHD_H */
This page took 0.030353 seconds and 4 git commands to generate.