aboutsummaryrefslogtreecommitdiffstats
path: root/block/genhd.c
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2008-08-16 08:30:30 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-08-21 13:15:38 -0400
commit068281d302def5efd96d84a163ba17e85f5ea564 (patch)
treef8d49d6c1e2043bcf3671504b411770a0c8c349c /block/genhd.c
parentf5a6d958b5d0a10e7e7a9dee1862fb31d08c6d26 (diff)
block: fix partial read() of /proc/{partitions,diskstats}
The proc files get truncated if they do not fit into the buffer with a single read(). We need to move the seq_file index from the callback of class_find_device() to the caller of class_find_device(), to keep its value across multiple invocations of the callback. Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'block/genhd.c')
-rw-r--r--block/genhd.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/block/genhd.c b/block/genhd.c
index c13cc77291af..f34befc54847 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -293,25 +293,26 @@ void __init printk_all_partitions(void)
293/* iterator */ 293/* iterator */
294static int find_start(struct device *dev, void *data) 294static int find_start(struct device *dev, void *data)
295{ 295{
296 loff_t k = *(loff_t *)data; 296 loff_t *k = data;
297 297
298 if (dev->type != &disk_type) 298 if (dev->type != &disk_type)
299 return 0; 299 return 0;
300 if (!k--) 300 if (!*k)
301 return 1; 301 return 1;
302 (*k)--;
302 return 0; 303 return 0;
303} 304}
304 305
305static void *part_start(struct seq_file *part, loff_t *pos) 306static void *part_start(struct seq_file *part, loff_t *pos)
306{ 307{
307 struct device *dev; 308 struct device *dev;
308 loff_t n = *pos; 309 loff_t k = *pos;
309 310
310 if (!n) 311 if (!k)
311 seq_puts(part, "major minor #blocks name\n\n"); 312 seq_puts(part, "major minor #blocks name\n\n");
312 313
313 mutex_lock(&block_class_lock); 314 mutex_lock(&block_class_lock);
314 dev = class_find_device(&block_class, NULL, (void *)pos, find_start); 315 dev = class_find_device(&block_class, NULL, &k, find_start);
315 if (dev) 316 if (dev)
316 return dev_to_disk(dev); 317 return dev_to_disk(dev);
317 return NULL; 318 return NULL;
@@ -568,9 +569,10 @@ static struct device_type disk_type = {
568static void *diskstats_start(struct seq_file *part, loff_t *pos) 569static void *diskstats_start(struct seq_file *part, loff_t *pos)
569{ 570{
570 struct device *dev; 571 struct device *dev;
572 loff_t k = *pos;
571 573
572 mutex_lock(&block_class_lock); 574 mutex_lock(&block_class_lock);
573 dev = class_find_device(&block_class, NULL, (void *)pos, find_start); 575 dev = class_find_device(&block_class, NULL, &k, find_start);
574 if (dev) 576 if (dev)
575 return dev_to_disk(dev); 577 return dev_to_disk(dev);
576 return NULL; 578 return NULL;