sysfs: Invoke iomem_get_mapping() from the sysfs open callback
authorKrzysztof Wilczyński <kw@linux.com>
Thu, 29 Jul 2021 23:32:34 +0000 (23:32 +0000)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 5 Aug 2021 12:47:31 +0000 (14:47 +0200)
Defer invocation of the iomem_get_mapping() to the sysfs open callback
so that it can be executed as needed when the binary sysfs object has
been accessed.

To do that, convert the "mapping" member of the struct bin_attribute
from a pointer to the struct address_space into a function pointer with
a signature that requires the same return type, and then updates the
sysfs_kf_bin_open() to invoke provided function should the function
pointer be valid.

Also, convert every invocation of iomem_get_mapping() into a function
pointer assignment, therefore allowing for the iomem_get_mapping()
invocation to be deferred to when the sysfs open callback runs.

Thus, this change removes the need for the fs_initcalls to complete
before any other sub-system that uses the iomem_get_mapping() would be
able to invoke it safely without leading to a failure and an Oops
related to an invalid iomem_get_mapping() access.

Suggested-by: Dan Williams <dan.j.williams@intel.com>
Reviewed-by: Dan Williams <dan.j.williams@intel.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Krzysztof Wilczyński <kw@linux.com>
Link: https://lore.kernel.org/r/20210729233235.1508920-2-kw@linux.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/pci/pci-sysfs.c
fs/sysfs/file.c
include/linux/sysfs.h

index 5d63df7c18206ae416f800fa5f35ea37cb0aab9b..76e5545d0e73c29df6d69fb1812c8189150a471b 100644 (file)
@@ -965,7 +965,7 @@ void pci_create_legacy_files(struct pci_bus *b)
        b->legacy_io->read = pci_read_legacy_io;
        b->legacy_io->write = pci_write_legacy_io;
        b->legacy_io->mmap = pci_mmap_legacy_io;
-       b->legacy_io->mapping = iomem_get_mapping();
+       b->legacy_io->mapping = iomem_get_mapping;
        pci_adjust_legacy_attr(b, pci_mmap_io);
        error = device_create_bin_file(&b->dev, b->legacy_io);
        if (error)
@@ -978,7 +978,7 @@ void pci_create_legacy_files(struct pci_bus *b)
        b->legacy_mem->size = 1024*1024;
        b->legacy_mem->attr.mode = 0600;
        b->legacy_mem->mmap = pci_mmap_legacy_mem;
-       b->legacy_io->mapping = iomem_get_mapping();
+       b->legacy_io->mapping = iomem_get_mapping;
        pci_adjust_legacy_attr(b, pci_mmap_mem);
        error = device_create_bin_file(&b->dev, b->legacy_mem);
        if (error)
@@ -1195,7 +1195,7 @@ static int pci_create_attr(struct pci_dev *pdev, int num, int write_combine)
                }
        }
        if (res_attr->mmap)
-               res_attr->mapping = iomem_get_mapping();
+               res_attr->mapping = iomem_get_mapping;
        res_attr->attr.name = res_attr_name;
        res_attr->attr.mode = 0600;
        res_attr->size = pci_resource_len(pdev, num);
index 9aefa7779b29af4197894f00fd4091eb1315725c..a3ee4c32a264d03a77a0eb33601d9bdc9e839213 100644 (file)
@@ -175,7 +175,7 @@ static int sysfs_kf_bin_open(struct kernfs_open_file *of)
        struct bin_attribute *battr = of->kn->priv;
 
        if (battr->mapping)
-               of->file->f_mapping = battr->mapping;
+               of->file->f_mapping = battr->mapping();
 
        return 0;
 }
index a12556a4b93ad0d1de96aca38c15f9c27ae7ace3..d5bcc897583c30f6ead527e9b8a4a0c7a14beb59 100644 (file)
@@ -176,7 +176,7 @@ struct bin_attribute {
        struct attribute        attr;
        size_t                  size;
        void                    *private;
-       struct address_space    *mapping;
+       struct address_space *(*mapping)(void);
        ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *,
                        char *, loff_t, size_t);
        ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *,