![Logan Gunthorpe](/assets/img/avatar_default.png)
Presently, the order of the block devices listed in /proc/devices is not entirely sequential. If a block device has a major number greater than BLKDEV_MAJOR_HASH_SIZE (255), it will be ordered as if its major were module 255. For example, 511 appears after 1. This patch cleans that up and prints each major number in the correct order, regardless of where they are stored in the hash table. In order to do this, we introduce BLKDEV_MAJOR_MAX as an artificial limit (chosen to be 512). It will then print all devices in major order number from 0 to the maximum. Signed-off-by: Logan Gunthorpe <logang@deltatee.com> Cc: Jens Axboe <axboe@kernel.dk> Cc: Jeff Layton <jlayton@poochiereds.net> Cc: "J. Bruce Fields" <bfields@fieldses.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
71 lines
1.4 KiB
C
71 lines
1.4 KiB
C
#include <linux/fs.h>
|
|
#include <linux/init.h>
|
|
#include <linux/proc_fs.h>
|
|
#include <linux/seq_file.h>
|
|
|
|
static int devinfo_show(struct seq_file *f, void *v)
|
|
{
|
|
int i = *(loff_t *) v;
|
|
|
|
if (i < CHRDEV_MAJOR_MAX) {
|
|
if (i == 0)
|
|
seq_puts(f, "Character devices:\n");
|
|
chrdev_show(f, i);
|
|
}
|
|
#ifdef CONFIG_BLOCK
|
|
else {
|
|
i -= CHRDEV_MAJOR_MAX;
|
|
if (i == 0)
|
|
seq_puts(f, "\nBlock devices:\n");
|
|
blkdev_show(f, i);
|
|
}
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static void *devinfo_start(struct seq_file *f, loff_t *pos)
|
|
{
|
|
if (*pos < (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
|
|
return pos;
|
|
return NULL;
|
|
}
|
|
|
|
static void *devinfo_next(struct seq_file *f, void *v, loff_t *pos)
|
|
{
|
|
(*pos)++;
|
|
if (*pos >= (BLKDEV_MAJOR_MAX + CHRDEV_MAJOR_MAX))
|
|
return NULL;
|
|
return pos;
|
|
}
|
|
|
|
static void devinfo_stop(struct seq_file *f, void *v)
|
|
{
|
|
/* Nothing to do */
|
|
}
|
|
|
|
static const struct seq_operations devinfo_ops = {
|
|
.start = devinfo_start,
|
|
.next = devinfo_next,
|
|
.stop = devinfo_stop,
|
|
.show = devinfo_show
|
|
};
|
|
|
|
static int devinfo_open(struct inode *inode, struct file *filp)
|
|
{
|
|
return seq_open(filp, &devinfo_ops);
|
|
}
|
|
|
|
static const struct file_operations proc_devinfo_operations = {
|
|
.open = devinfo_open,
|
|
.read = seq_read,
|
|
.llseek = seq_lseek,
|
|
.release = seq_release,
|
|
};
|
|
|
|
static int __init proc_devices_init(void)
|
|
{
|
|
proc_create("devices", 0, NULL, &proc_devinfo_operations);
|
|
return 0;
|
|
}
|
|
fs_initcall(proc_devices_init);
|