Instead of using class_dev_iter directly, abstract disk iteration into
disk_iter and helpers which are exported.  This simplifies the callers
a bit and allows external users to iterate over disks.

Signed-off-by: Tejun Heo <[email protected]>
---
This is one of the prep patches for ioblame which currently is in use
in google.  I'm working to upstream ioblame but this one seems good as
a stand-alone cleanup.

Thanks.

 block/genhd.c         |   98 +++++++++++++++++++++++++++++++++-----------------
 include/linux/genhd.h |   10 ++++-
 2 files changed, 75 insertions(+), 33 deletions(-)

--- a/block/genhd.c
+++ b/block/genhd.c
@@ -41,6 +41,47 @@ static void disk_del_events(struct gendi
 static void disk_release_events(struct gendisk *disk);
 
 /**
+ * disk_iter_init - initialize disk iterator
+ * @diter: iterator to initialize
+ *
+ * Initialize @diter so that it iterates over all disks
+ */
+void disk_iter_init(struct disk_iter *diter)
+{
+       class_dev_iter_init(&diter->cdev_iter, &block_class, NULL, &disk_type);
+}
+EXPORT_SYMBOL_GPL(disk_iter_init);
+
+/**
+ * disk_iter_next - proceed iterator to the next disk and return it
+ * @diter: iterator to proceed
+ *
+ * Proceed @diter to the next disk and return it.
+ */
+struct gendisk *disk_iter_next(struct disk_iter *diter)
+{
+       struct device *dev;
+
+       dev = class_dev_iter_next(&diter->cdev_iter);
+       if (dev)
+               return dev_to_disk(dev);
+       return NULL;
+}
+EXPORT_SYMBOL_GPL(disk_iter_next);
+
+/**
+ * disk_iter_exit - finish up disk iteration
+ * @diter: iter to exit
+ *
+ * Called when iteration is over.  Cleans up @diter.
+ */
+void disk_iter_exit(struct disk_iter *diter)
+{
+       class_dev_iter_exit(&diter->cdev_iter);
+}
+EXPORT_SYMBOL_GPL(disk_iter_exit);
+
+/**
  * disk_get_part - get partition
  * @disk: disk to look partition from
  * @partno: partition number
@@ -733,12 +774,11 @@ EXPORT_SYMBOL(bdget_disk);
  */
 void __init printk_all_partitions(void)
 {
-       struct class_dev_iter iter;
-       struct device *dev;
+       struct disk_iter diter;
+       struct gendisk *disk;
 
-       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
-       while ((dev = class_dev_iter_next(&iter))) {
-               struct gendisk *disk = dev_to_disk(dev);
+       disk_iter_init(&diter);
+       while ((disk = disk_iter_next(&diter))) {
                struct disk_part_iter piter;
                struct hd_struct *part;
                char name_buf[BDEVNAME_SIZE];
@@ -778,7 +818,7 @@ void __init printk_all_partitions(void)
                }
                disk_part_iter_exit(&piter);
        }
-       class_dev_iter_exit(&iter);
+       disk_iter_exit(&diter);
 }
 
 #ifdef CONFIG_PROC_FS
@@ -786,44 +826,38 @@ void __init printk_all_partitions(void)
 static void *disk_seqf_start(struct seq_file *seqf, loff_t *pos)
 {
        loff_t skip = *pos;
-       struct class_dev_iter *iter;
-       struct device *dev;
+       struct disk_iter *diter;
+       struct gendisk *disk;
 
-       iter = kmalloc(sizeof(*iter), GFP_KERNEL);
-       if (!iter)
+       diter = kmalloc(sizeof(*diter), GFP_KERNEL);
+       if (!diter)
                return ERR_PTR(-ENOMEM);
 
-       seqf->private = iter;
-       class_dev_iter_init(iter, &block_class, NULL, &disk_type);
+       seqf->private = diter;
+       disk_iter_init(diter);
        do {
-               dev = class_dev_iter_next(iter);
-               if (!dev)
+               disk = disk_iter_next(diter);
+               if (!disk)
                        return NULL;
        } while (skip--);
 
-       return dev_to_disk(dev);
+       return disk;
 }
 
 static void *disk_seqf_next(struct seq_file *seqf, void *v, loff_t *pos)
 {
-       struct device *dev;
-
        (*pos)++;
-       dev = class_dev_iter_next(seqf->private);
-       if (dev)
-               return dev_to_disk(dev);
-
-       return NULL;
+       return disk_iter_next(seqf->private);
 }
 
 static void disk_seqf_stop(struct seq_file *seqf, void *v)
 {
-       struct class_dev_iter *iter = seqf->private;
+       struct disk_iter *diter = seqf->private;
 
        /* stop is called even after start failed :-( */
-       if (iter) {
-               class_dev_iter_exit(iter);
-               kfree(iter);
+       if (diter) {
+               disk_iter_exit(diter);
+               kfree(diter);
        }
 }
 
@@ -1205,12 +1239,12 @@ module_init(proc_genhd_init);
 dev_t blk_lookup_devt(const char *name, int partno)
 {
        dev_t devt = MKDEV(0, 0);
-       struct class_dev_iter iter;
-       struct device *dev;
+       struct disk_iter diter;
+       struct gendisk *disk;
 
-       class_dev_iter_init(&iter, &block_class, NULL, &disk_type);
-       while ((dev = class_dev_iter_next(&iter))) {
-               struct gendisk *disk = dev_to_disk(dev);
+       disk_iter_init(&diter);
+       while ((disk = disk_iter_next(&diter))) {
+               struct device *dev = disk_to_dev(disk);
                struct hd_struct *part;
 
                if (strcmp(dev_name(dev), name))
@@ -1232,7 +1266,7 @@ dev_t blk_lookup_devt(const char *name,
                }
                disk_put_part(part);
        }
-       class_dev_iter_exit(&iter);
+       disk_iter_exit(&diter);
        return devt;
 }
 EXPORT_SYMBOL(blk_lookup_devt);
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -263,8 +263,16 @@ static inline void disk_put_part(struct
 }
 
 /*
- * Smarter partition iterator without context limits.
+ * Smarter disk and partition iterators without context limits.
  */
+struct disk_iter {
+       struct class_dev_iter   cdev_iter;
+};
+
+extern void disk_iter_init(struct disk_iter *diter);
+extern struct gendisk *disk_iter_next(struct disk_iter *diter);
+extern void disk_iter_exit(struct disk_iter *diter);
+
 #define DISK_PITER_REVERSE     (1 << 0) /* iterate in the reverse direction */
 #define DISK_PITER_INCL_EMPTY  (1 << 1) /* include 0-sized parts */
 #define DISK_PITER_INCL_PART0  (1 << 2) /* include partition 0 */
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

Reply via email to