+struct blkdev_info {
+ int index;
+ struct blk_major_name *bd;
+};
+
+/*
+ * iterate over a list of blkdev_info structures. allows
+ * the major_names array to be iterated over from outside this file
+ * must be called with the block_subsys_sem held
+ */
+void *get_next_blkdev(void *dev)
+{
+ struct blkdev_info *info;
+
+ if (dev == NULL) {
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
+ if (!info)
+ goto out;
+ info->index=0;
+ info->bd = major_names[info->index];
+ if (info->bd)
+ goto out;
+ } else {
+ info = dev;
+ }
+
+ while (info->index < ARRAY_SIZE(major_names)) {
+ if (info->bd)
+ info->bd = info->bd->next;
+ if (info->bd)
+ goto out;
+ /*
+ * No devices on this chain, move to the next
+ */
+ info->index++;
+ info->bd = (info->index < ARRAY_SIZE(major_names)) ?
+ major_names[info->index] : NULL;
+ if (info->bd)
+ goto out;
+ }
+
+out:
+ return info;
+}
+
+void *acquire_blkdev_list(void)
+{
+ down(&block_subsys_sem);
+ return get_next_blkdev(NULL);
+}
+
+void release_blkdev_list(void *dev)
+{
+ up(&block_subsys_sem);
+ kfree(dev);
+}
+
+
+/*
+ * Count the number of records in the blkdev_list.
+ * must be called with the block_subsys_sem held
+ */
+int count_blkdev_list(void)