summaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2020-10-29 15:58:28 +0100
committerJens Axboe <axboe@kernel.dk>2020-11-16 16:14:30 +0100
commita160c6159d4a0cf82f28bc1658a958e278ec3688 (patch)
tree2026376f6fe335c63633b974f34e6826e81f4e3e /block/genhd.c
parentblock: rework requesting modules for unclaimed devices (diff)
downloadlinux-a160c6159d4a0cf82f28bc1658a958e278ec3688.tar.xz
linux-a160c6159d4a0cf82f28bc1658a958e278ec3688.zip
block: add an optional probe callback to major_names
Add a callback to the major_names array that allows a driver to override how to probe for dev_t that doesn't currently have a gendisk registered. This will help separating the lookup of the gendisk by dev_t vs probe action for a not currently registered dev_t. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Jens Axboe <axboe@kernel.dk>
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 81017bd3b333..20521163fd06 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -402,6 +402,7 @@ static struct blk_major_name {
struct blk_major_name *next;
int major;
char name[16];
+ void (*probe)(dev_t devt);
} *major_names[BLKDEV_MAJOR_HASH_SIZE];
static DEFINE_MUTEX(major_names_lock);
@@ -444,7 +445,8 @@ void blkdev_show(struct seq_file *seqf, off_t offset)
* See Documentation/admin-guide/devices.txt for the list of allocated
* major numbers.
*/
-int register_blkdev(unsigned int major, const char *name)
+int __register_blkdev(unsigned int major, const char *name,
+ void (*probe)(dev_t devt))
{
struct blk_major_name **n, *p;
int index, ret = 0;
@@ -483,6 +485,7 @@ int register_blkdev(unsigned int major, const char *name)
}
p->major = major;
+ p->probe = probe;
strlcpy(p->name, name, sizeof(p->name));
p->next = NULL;
index = major_to_index(major);
@@ -505,8 +508,7 @@ out:
mutex_unlock(&major_names_lock);
return ret;
}
-
-EXPORT_SYMBOL(register_blkdev);
+EXPORT_SYMBOL(__register_blkdev);
void unregister_blkdev(unsigned int major, const char *name)
{
@@ -1033,6 +1035,19 @@ static ssize_t disk_badblocks_store(struct device *dev,
static void request_gendisk_module(dev_t devt)
{
+ unsigned int major = MAJOR(devt);
+ struct blk_major_name **n;
+
+ mutex_lock(&major_names_lock);
+ for (n = &major_names[major_to_index(major)]; *n; n = &(*n)->next) {
+ if ((*n)->major == major && (*n)->probe) {
+ (*n)->probe(devt);
+ mutex_unlock(&major_names_lock);
+ return;
+ }
+ }
+ mutex_unlock(&major_names_lock);
+
if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
/* Make old-style 2.4 aliases work */
request_module("block-major-%d", MAJOR(devt));