block: abstract disk iteration into disk_iter
PATCH 1/1 block: abstract disk iteration into disk_iter
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(-)
block/genhd.c +66 -32
@@ -41,6 +41,47 @@ static void disk_del_events(struct gendistatic 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);
include/linux/genhd.h +9 -1
@@ -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 */