aboutsummaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:34:42 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2008-01-25 11:35:13 -0500
commitdf8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch)
treebc3799a43e8b94fa84b32e37b1c124d5e4868f50 /block
parent556a169dab38b5100df6f4a45b655dddd3db94c1 (diff)
parent4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas: - Documentation updates (language translations and fixes, as well as kobject and kset documenatation updates.) - major kset/kobject/ktype rework and fixes. This cleans up the kset and kobject and ktype relationship and architecture, making sense of things now, and good documenation and samples are provided for others to use. Also the attributes for kobjects are much easier to handle now. This cleaned up a LOT of code all through the kernel, making kobjects easier to use if you want to. - struct bus_type has been reworked to now handle the lifetime rules properly, as the kobject is properly dynamic. - struct driver has also been reworked, and now the lifetime issues are resolved. - the block subsystem has been converted to use struct device now, and not "raw" kobjects. This patch has been in the -mm tree for over a year now, and finally all the issues are worked out with it. Older distros now properly work with new kernels, and no userspace updates are needed at all. - nozomi driver is added. This has also been in -mm for a long time, and many people have asked for it to go in. It is now in good enough shape to do so. - lots of class_device conversions to use struct device instead. The tree is almost all cleaned up now, only SCSI and IB is the remaining code to fix up... * git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits) Driver core: coding style fixes Kobject: fix coding style issues in kobject c files Kobject: fix coding style issues in kobject.h Driver core: fix coding style issues in device.h spi: use class iteration api scsi: use class iteration api rtc: use class iteration api power supply : use class iteration api ieee1394: use class iteration api Driver Core: add class iteration api Driver core: Cleanup get_device_parent() in device_add() and device_move() UIO: constify function pointer tables Driver Core: constify the name passed to platform_device_register_simple driver core: fix build with SYSFS=n sysfs: make SYSFS_DEPRECATED depend on SYSFS Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init kobject: add sample code for how to use ksets/ktypes/kobjects kobject: add sample code for how to use kobjects in a simple manner. kobject: update the kobject/kset documentation kobject: remove old, outdated documentation. ...
Diffstat (limited to 'block')
-rw-r--r--block/elevator.c8
-rw-r--r--block/genhd.c419
-rw-r--r--block/ll_rw_blk.c11
3 files changed, 190 insertions, 248 deletions
diff --git a/block/elevator.c b/block/elevator.c
index e452deb80395..f9736fbdab03 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -185,9 +185,7 @@ static elevator_t *elevator_alloc(struct request_queue *q,
185 185
186 eq->ops = &e->ops; 186 eq->ops = &e->ops;
187 eq->elevator_type = e; 187 eq->elevator_type = e;
188 kobject_init(&eq->kobj); 188 kobject_init(&eq->kobj, &elv_ktype);
189 kobject_set_name(&eq->kobj, "%s", "iosched");
190 eq->kobj.ktype = &elv_ktype;
191 mutex_init(&eq->sysfs_lock); 189 mutex_init(&eq->sysfs_lock);
192 190
193 eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, 191 eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES,
@@ -931,9 +929,7 @@ int elv_register_queue(struct request_queue *q)
931 elevator_t *e = q->elevator; 929 elevator_t *e = q->elevator;
932 int error; 930 int error;
933 931
934 e->kobj.parent = &q->kobj; 932 error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched");
935
936 error = kobject_add(&e->kobj);
937 if (!error) { 933 if (!error) {
938 struct elv_fs_entry *attr = e->elevator_type->elevator_attrs; 934 struct elv_fs_entry *attr = e->elevator_type->elevator_attrs;
939 if (attr) { 935 if (attr) {
diff --git a/block/genhd.c b/block/genhd.c
index f2ac914160d1..5e4ab4b37d9f 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,8 +17,10 @@
17#include <linux/buffer_head.h> 17#include <linux/buffer_head.h>
18#include <linux/mutex.h> 18#include <linux/mutex.h>
19 19
20struct kset block_subsys; 20static DEFINE_MUTEX(block_class_lock);
21static DEFINE_MUTEX(block_subsys_lock); 21#ifndef CONFIG_SYSFS_DEPRECATED
22struct kobject *block_depr;
23#endif
22 24
23/* 25/*
24 * Can be deleted altogether. Later. 26 * Can be deleted altogether. Later.
@@ -37,19 +39,17 @@ static inline int major_to_index(int major)
37} 39}
38 40
39#ifdef CONFIG_PROC_FS 41#ifdef CONFIG_PROC_FS
40
41void blkdev_show(struct seq_file *f, off_t offset) 42void blkdev_show(struct seq_file *f, off_t offset)
42{ 43{
43 struct blk_major_name *dp; 44 struct blk_major_name *dp;
44 45
45 if (offset < BLKDEV_MAJOR_HASH_SIZE) { 46 if (offset < BLKDEV_MAJOR_HASH_SIZE) {
46 mutex_lock(&block_subsys_lock); 47 mutex_lock(&block_class_lock);
47 for (dp = major_names[offset]; dp; dp = dp->next) 48 for (dp = major_names[offset]; dp; dp = dp->next)
48 seq_printf(f, "%3d %s\n", dp->major, dp->name); 49 seq_printf(f, "%3d %s\n", dp->major, dp->name);
49 mutex_unlock(&block_subsys_lock); 50 mutex_unlock(&block_class_lock);
50 } 51 }
51} 52}
52
53#endif /* CONFIG_PROC_FS */ 53#endif /* CONFIG_PROC_FS */
54 54
55int register_blkdev(unsigned int major, const char *name) 55int register_blkdev(unsigned int major, const char *name)
@@ -57,7 +57,7 @@ int register_blkdev(unsigned int major, const char *name)
57 struct blk_major_name **n, *p; 57 struct blk_major_name **n, *p;
58 int index, ret = 0; 58 int index, ret = 0;
59 59
60 mutex_lock(&block_subsys_lock); 60 mutex_lock(&block_class_lock);
61 61
62 /* temporary */ 62 /* temporary */
63 if (major == 0) { 63 if (major == 0) {
@@ -102,7 +102,7 @@ int register_blkdev(unsigned int major, const char *name)
102 kfree(p); 102 kfree(p);
103 } 103 }
104out: 104out:
105 mutex_unlock(&block_subsys_lock); 105 mutex_unlock(&block_class_lock);
106 return ret; 106 return ret;
107} 107}
108 108
@@ -114,7 +114,7 @@ void unregister_blkdev(unsigned int major, const char *name)
114 struct blk_major_name *p = NULL; 114 struct blk_major_name *p = NULL;
115 int index = major_to_index(major); 115 int index = major_to_index(major);
116 116
117 mutex_lock(&block_subsys_lock); 117 mutex_lock(&block_class_lock);
118 for (n = &major_names[index]; *n; n = &(*n)->next) 118 for (n = &major_names[index]; *n; n = &(*n)->next)
119 if ((*n)->major == major) 119 if ((*n)->major == major)
120 break; 120 break;
@@ -124,7 +124,7 @@ void unregister_blkdev(unsigned int major, const char *name)
124 p = *n; 124 p = *n;
125 *n = p->next; 125 *n = p->next;
126 } 126 }
127 mutex_unlock(&block_subsys_lock); 127 mutex_unlock(&block_class_lock);
128 kfree(p); 128 kfree(p);
129} 129}
130 130
@@ -137,29 +137,30 @@ static struct kobj_map *bdev_map;
137 * range must be nonzero 137 * range must be nonzero
138 * The hash chain is sorted on range, so that subranges can override. 138 * The hash chain is sorted on range, so that subranges can override.
139 */ 139 */
140void blk_register_region(dev_t dev, unsigned long range, struct module *module, 140void blk_register_region(dev_t devt, unsigned long range, struct module *module,
141 struct kobject *(*probe)(dev_t, int *, void *), 141 struct kobject *(*probe)(dev_t, int *, void *),
142 int (*lock)(dev_t, void *), void *data) 142 int (*lock)(dev_t, void *), void *data)
143{ 143{
144 kobj_map(bdev_map, dev, range, module, probe, lock, data); 144 kobj_map(bdev_map, devt, range, module, probe, lock, data);
145} 145}
146 146
147EXPORT_SYMBOL(blk_register_region); 147EXPORT_SYMBOL(blk_register_region);
148 148
149void blk_unregister_region(dev_t dev, unsigned long range) 149void blk_unregister_region(dev_t devt, unsigned long range)
150{ 150{
151 kobj_unmap(bdev_map, dev, range); 151 kobj_unmap(bdev_map, devt, range);
152} 152}
153 153
154EXPORT_SYMBOL(blk_unregister_region); 154EXPORT_SYMBOL(blk_unregister_region);
155 155
156static struct kobject *exact_match(dev_t dev, int *part, void *data) 156static struct kobject *exact_match(dev_t devt, int *part, void *data)
157{ 157{
158 struct gendisk *p = data; 158 struct gendisk *p = data;
159 return &p->kobj; 159
160 return &p->dev.kobj;
160} 161}
161 162
162static int exact_lock(dev_t dev, void *data) 163static int exact_lock(dev_t devt, void *data)
163{ 164{
164 struct gendisk *p = data; 165 struct gendisk *p = data;
165 166
@@ -194,8 +195,6 @@ void unlink_gendisk(struct gendisk *disk)
194 disk->minors); 195 disk->minors);
195} 196}
196 197
197#define to_disk(obj) container_of(obj,struct gendisk,kobj)
198
199/** 198/**
200 * get_gendisk - get partitioning information for a given device 199 * get_gendisk - get partitioning information for a given device
201 * @dev: device to get partitioning information for 200 * @dev: device to get partitioning information for
@@ -203,10 +202,12 @@ void unlink_gendisk(struct gendisk *disk)
203 * This function gets the structure containing partitioning 202 * This function gets the structure containing partitioning
204 * information for the given device @dev. 203 * information for the given device @dev.
205 */ 204 */
206struct gendisk *get_gendisk(dev_t dev, int *part) 205struct gendisk *get_gendisk(dev_t devt, int *part)
207{ 206{
208 struct kobject *kobj = kobj_lookup(bdev_map, dev, part); 207 struct kobject *kobj = kobj_lookup(bdev_map, devt, part);
209 return kobj ? to_disk(kobj) : NULL; 208 struct device *dev = kobj_to_dev(kobj);
209
210 return kobj ? dev_to_disk(dev) : NULL;
210} 211}
211 212
212/* 213/*
@@ -216,13 +217,17 @@ struct gendisk *get_gendisk(dev_t dev, int *part)
216 */ 217 */
217void __init printk_all_partitions(void) 218void __init printk_all_partitions(void)
218{ 219{
219 int n; 220 struct device *dev;
220 struct gendisk *sgp; 221 struct gendisk *sgp;
222 char buf[BDEVNAME_SIZE];
223 int n;
221 224
222 mutex_lock(&block_subsys_lock); 225 mutex_lock(&block_class_lock);
223 /* For each block device... */ 226 /* For each block device... */
224 list_for_each_entry(sgp, &block_subsys.list, kobj.entry) { 227 list_for_each_entry(dev, &block_class.devices, node) {
225 char buf[BDEVNAME_SIZE]; 228 if (dev->type != &disk_type)
229 continue;
230 sgp = dev_to_disk(dev);
226 /* 231 /*
227 * Don't show empty devices or things that have been surpressed 232 * Don't show empty devices or things that have been surpressed
228 */ 233 */
@@ -255,38 +260,46 @@ void __init printk_all_partitions(void)
255 sgp->major, n + 1 + sgp->first_minor, 260 sgp->major, n + 1 + sgp->first_minor,
256 (unsigned long long)sgp->part[n]->nr_sects >> 1, 261 (unsigned long long)sgp->part[n]->nr_sects >> 1,
257 disk_name(sgp, n + 1, buf)); 262 disk_name(sgp, n + 1, buf));
258 } /* partition subloop */ 263 }
259 } /* Block device loop */ 264 }
260 265
261 mutex_unlock(&block_subsys_lock); 266 mutex_unlock(&block_class_lock);
262 return;
263} 267}
264 268
265#ifdef CONFIG_PROC_FS 269#ifdef CONFIG_PROC_FS
266/* iterator */ 270/* iterator */
267static void *part_start(struct seq_file *part, loff_t *pos) 271static void *part_start(struct seq_file *part, loff_t *pos)
268{ 272{
269 struct list_head *p; 273 loff_t k = *pos;
270 loff_t l = *pos; 274 struct device *dev;
271 275
272 mutex_lock(&block_subsys_lock); 276 mutex_lock(&block_class_lock);
273 list_for_each(p, &block_subsys.list) 277 list_for_each_entry(dev, &block_class.devices, node) {
274 if (!l--) 278 if (dev->type != &disk_type)
275 return list_entry(p, struct gendisk, kobj.entry); 279 continue;
280 if (!k--)
281 return dev_to_disk(dev);
282 }
276 return NULL; 283 return NULL;
277} 284}
278 285
279static void *part_next(struct seq_file *part, void *v, loff_t *pos) 286static void *part_next(struct seq_file *part, void *v, loff_t *pos)
280{ 287{
281 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 288 struct gendisk *gp = v;
289 struct device *dev;
282 ++*pos; 290 ++*pos;
283 return p==&block_subsys.list ? NULL : 291 list_for_each_entry(dev, &gp->dev.node, node) {
284 list_entry(p, struct gendisk, kobj.entry); 292 if (&dev->node == &block_class.devices)
293 return NULL;
294 if (dev->type == &disk_type)
295 return dev_to_disk(dev);
296 }
297 return NULL;
285} 298}
286 299
287static void part_stop(struct seq_file *part, void *v) 300static void part_stop(struct seq_file *part, void *v)
288{ 301{
289 mutex_unlock(&block_subsys_lock); 302 mutex_unlock(&block_class_lock);
290} 303}
291 304
292static int show_partition(struct seq_file *part, void *v) 305static int show_partition(struct seq_file *part, void *v)
@@ -295,7 +308,7 @@ static int show_partition(struct seq_file *part, void *v)
295 int n; 308 int n;
296 char buf[BDEVNAME_SIZE]; 309 char buf[BDEVNAME_SIZE];
297 310
298 if (&sgp->kobj.entry == block_subsys.list.next) 311 if (&sgp->dev.node == block_class.devices.next)
299 seq_puts(part, "major minor #blocks name\n\n"); 312 seq_puts(part, "major minor #blocks name\n\n");
300 313
301 /* Don't show non-partitionable removeable devices or empty devices */ 314 /* Don't show non-partitionable removeable devices or empty devices */
@@ -325,110 +338,81 @@ static int show_partition(struct seq_file *part, void *v)
325} 338}
326 339
327struct seq_operations partitions_op = { 340struct seq_operations partitions_op = {
328 .start =part_start, 341 .start = part_start,
329 .next = part_next, 342 .next = part_next,
330 .stop = part_stop, 343 .stop = part_stop,
331 .show = show_partition 344 .show = show_partition
332}; 345};
333#endif 346#endif
334 347
335 348
336extern int blk_dev_init(void); 349extern int blk_dev_init(void);
337 350
338static struct kobject *base_probe(dev_t dev, int *part, void *data) 351static struct kobject *base_probe(dev_t devt, int *part, void *data)
339{ 352{
340 if (request_module("block-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0) 353 if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0)
341 /* Make old-style 2.4 aliases work */ 354 /* Make old-style 2.4 aliases work */
342 request_module("block-major-%d", MAJOR(dev)); 355 request_module("block-major-%d", MAJOR(devt));
343 return NULL; 356 return NULL;
344} 357}
345 358
346static int __init genhd_device_init(void) 359static int __init genhd_device_init(void)
347{ 360{
348 int err; 361 class_register(&block_class);
349 362 bdev_map = kobj_map_init(base_probe, &block_class_lock);
350 bdev_map = kobj_map_init(base_probe, &block_subsys_lock);
351 blk_dev_init(); 363 blk_dev_init();
352 err = subsystem_register(&block_subsys); 364
353 if (err < 0) 365#ifndef CONFIG_SYSFS_DEPRECATED
354 printk(KERN_WARNING "%s: subsystem_register error: %d\n", 366 /* create top-level block dir */
355 __FUNCTION__, err); 367 block_depr = kobject_create_and_add("block", NULL);
356 return err; 368#endif
369 return 0;
357} 370}
358 371
359subsys_initcall(genhd_device_init); 372subsys_initcall(genhd_device_init);
360 373
361 374static ssize_t disk_range_show(struct device *dev,
362 375 struct device_attribute *attr, char *buf)
363/*
364 * kobject & sysfs bindings for block devices
365 */
366static ssize_t disk_attr_show(struct kobject *kobj, struct attribute *attr,
367 char *page)
368{ 376{
369 struct gendisk *disk = to_disk(kobj); 377 struct gendisk *disk = dev_to_disk(dev);
370 struct disk_attribute *disk_attr =
371 container_of(attr,struct disk_attribute,attr);
372 ssize_t ret = -EIO;
373 378
374 if (disk_attr->show) 379 return sprintf(buf, "%d\n", disk->minors);
375 ret = disk_attr->show(disk,page);
376 return ret;
377} 380}
378 381
379static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr, 382static ssize_t disk_removable_show(struct device *dev,
380 const char *page, size_t count) 383 struct device_attribute *attr, char *buf)
381{ 384{
382 struct gendisk *disk = to_disk(kobj); 385 struct gendisk *disk = dev_to_disk(dev);
383 struct disk_attribute *disk_attr =
384 container_of(attr,struct disk_attribute,attr);
385 ssize_t ret = 0;
386 386
387 if (disk_attr->store) 387 return sprintf(buf, "%d\n",
388 ret = disk_attr->store(disk, page, count); 388 (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
389 return ret;
390} 389}
391 390
392static struct sysfs_ops disk_sysfs_ops = { 391static ssize_t disk_size_show(struct device *dev,
393 .show = &disk_attr_show, 392 struct device_attribute *attr, char *buf)
394 .store = &disk_attr_store,
395};
396
397static ssize_t disk_uevent_store(struct gendisk * disk,
398 const char *buf, size_t count)
399{
400 kobject_uevent(&disk->kobj, KOBJ_ADD);
401 return count;
402}
403static ssize_t disk_dev_read(struct gendisk * disk, char *page)
404{
405 dev_t base = MKDEV(disk->major, disk->first_minor);
406 return print_dev_t(page, base);
407}
408static ssize_t disk_range_read(struct gendisk * disk, char *page)
409{ 393{
410 return sprintf(page, "%d\n", disk->minors); 394 struct gendisk *disk = dev_to_disk(dev);
411}
412static ssize_t disk_removable_read(struct gendisk * disk, char *page)
413{
414 return sprintf(page, "%d\n",
415 (disk->flags & GENHD_FL_REMOVABLE ? 1 : 0));
416 395
396 return sprintf(buf, "%llu\n", (unsigned long long)get_capacity(disk));
417} 397}
418static ssize_t disk_size_read(struct gendisk * disk, char *page) 398
419{ 399static ssize_t disk_capability_show(struct device *dev,
420 return sprintf(page, "%llu\n", (unsigned long long)get_capacity(disk)); 400 struct device_attribute *attr, char *buf)
421}
422static ssize_t disk_capability_read(struct gendisk *disk, char *page)
423{ 401{
424 return sprintf(page, "%x\n", disk->flags); 402 struct gendisk *disk = dev_to_disk(dev);
403
404 return sprintf(buf, "%x\n", disk->flags);
425} 405}
426static ssize_t disk_stats_read(struct gendisk * disk, char *page) 406
407static ssize_t disk_stat_show(struct device *dev,
408 struct device_attribute *attr, char *buf)
427{ 409{
410 struct gendisk *disk = dev_to_disk(dev);
411
428 preempt_disable(); 412 preempt_disable();
429 disk_round_stats(disk); 413 disk_round_stats(disk);
430 preempt_enable(); 414 preempt_enable();
431 return sprintf(page, 415 return sprintf(buf,
432 "%8lu %8lu %8llu %8u " 416 "%8lu %8lu %8llu %8u "
433 "%8lu %8lu %8llu %8u " 417 "%8lu %8lu %8llu %8u "
434 "%8u %8u %8u" 418 "%8u %8u %8u"
@@ -445,40 +429,21 @@ static ssize_t disk_stats_read(struct gendisk * disk, char *page)
445 jiffies_to_msecs(disk_stat_read(disk, io_ticks)), 429 jiffies_to_msecs(disk_stat_read(disk, io_ticks)),
446 jiffies_to_msecs(disk_stat_read(disk, time_in_queue))); 430 jiffies_to_msecs(disk_stat_read(disk, time_in_queue)));
447} 431}
448static struct disk_attribute disk_attr_uevent = {
449 .attr = {.name = "uevent", .mode = S_IWUSR },
450 .store = disk_uevent_store
451};
452static struct disk_attribute disk_attr_dev = {
453 .attr = {.name = "dev", .mode = S_IRUGO },
454 .show = disk_dev_read
455};
456static struct disk_attribute disk_attr_range = {
457 .attr = {.name = "range", .mode = S_IRUGO },
458 .show = disk_range_read
459};
460static struct disk_attribute disk_attr_removable = {
461 .attr = {.name = "removable", .mode = S_IRUGO },
462 .show = disk_removable_read
463};
464static struct disk_attribute disk_attr_size = {
465 .attr = {.name = "size", .mode = S_IRUGO },
466 .show = disk_size_read
467};
468static struct disk_attribute disk_attr_capability = {
469 .attr = {.name = "capability", .mode = S_IRUGO },
470 .show = disk_capability_read
471};
472static struct disk_attribute disk_attr_stat = {
473 .attr = {.name = "stat", .mode = S_IRUGO },
474 .show = disk_stats_read
475};
476 432
477#ifdef CONFIG_FAIL_MAKE_REQUEST 433#ifdef CONFIG_FAIL_MAKE_REQUEST
434static ssize_t disk_fail_show(struct device *dev,
435 struct device_attribute *attr, char *buf)
436{
437 struct gendisk *disk = dev_to_disk(dev);
438
439 return sprintf(buf, "%d\n", disk->flags & GENHD_FL_FAIL ? 1 : 0);
440}
478 441
479static ssize_t disk_fail_store(struct gendisk * disk, 442static ssize_t disk_fail_store(struct device *dev,
443 struct device_attribute *attr,
480 const char *buf, size_t count) 444 const char *buf, size_t count)
481{ 445{
446 struct gendisk *disk = dev_to_disk(dev);
482 int i; 447 int i;
483 448
484 if (count > 0 && sscanf(buf, "%d", &i) > 0) { 449 if (count > 0 && sscanf(buf, "%d", &i) > 0) {
@@ -490,136 +455,100 @@ static ssize_t disk_fail_store(struct gendisk * disk,
490 455
491 return count; 456 return count;
492} 457}
493static ssize_t disk_fail_read(struct gendisk * disk, char *page)
494{
495 return sprintf(page, "%d\n", disk->flags & GENHD_FL_FAIL ? 1 : 0);
496}
497static struct disk_attribute disk_attr_fail = {
498 .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR },
499 .store = disk_fail_store,
500 .show = disk_fail_read
501};
502 458
503#endif 459#endif
504 460
505static struct attribute * default_attrs[] = { 461static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL);
506 &disk_attr_uevent.attr, 462static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL);
507 &disk_attr_dev.attr, 463static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL);
508 &disk_attr_range.attr, 464static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL);
509 &disk_attr_removable.attr, 465static DEVICE_ATTR(stat, S_IRUGO, disk_stat_show, NULL);
510 &disk_attr_size.attr, 466#ifdef CONFIG_FAIL_MAKE_REQUEST
511 &disk_attr_stat.attr, 467static struct device_attribute dev_attr_fail =
512 &disk_attr_capability.attr, 468 __ATTR(make-it-fail, S_IRUGO|S_IWUSR, disk_fail_show, disk_fail_store);
469#endif
470
471static struct attribute *disk_attrs[] = {
472 &dev_attr_range.attr,
473 &dev_attr_removable.attr,
474 &dev_attr_size.attr,
475 &dev_attr_capability.attr,
476 &dev_attr_stat.attr,
513#ifdef CONFIG_FAIL_MAKE_REQUEST 477#ifdef CONFIG_FAIL_MAKE_REQUEST
514 &disk_attr_fail.attr, 478 &dev_attr_fail.attr,
515#endif 479#endif
516 NULL, 480 NULL
481};
482
483static struct attribute_group disk_attr_group = {
484 .attrs = disk_attrs,
517}; 485};
518 486
519static void disk_release(struct kobject * kobj) 487static struct attribute_group *disk_attr_groups[] = {
488 &disk_attr_group,
489 NULL
490};
491
492static void disk_release(struct device *dev)
520{ 493{
521 struct gendisk *disk = to_disk(kobj); 494 struct gendisk *disk = dev_to_disk(dev);
495
522 kfree(disk->random); 496 kfree(disk->random);
523 kfree(disk->part); 497 kfree(disk->part);
524 free_disk_stats(disk); 498 free_disk_stats(disk);
525 kfree(disk); 499 kfree(disk);
526} 500}
527 501struct class block_class = {
528static struct kobj_type ktype_block = { 502 .name = "block",
529 .release = disk_release,
530 .sysfs_ops = &disk_sysfs_ops,
531 .default_attrs = default_attrs,
532}; 503};
533 504
534extern struct kobj_type ktype_part; 505struct device_type disk_type = {
535 506 .name = "disk",
536static int block_uevent_filter(struct kset *kset, struct kobject *kobj) 507 .groups = disk_attr_groups,
537{ 508 .release = disk_release,
538 struct kobj_type *ktype = get_ktype(kobj);
539
540 return ((ktype == &ktype_block) || (ktype == &ktype_part));
541}
542
543static int block_uevent(struct kset *kset, struct kobject *kobj,
544 struct kobj_uevent_env *env)
545{
546 struct kobj_type *ktype = get_ktype(kobj);
547 struct device *physdev;
548 struct gendisk *disk;
549 struct hd_struct *part;
550
551 if (ktype == &ktype_block) {
552 disk = container_of(kobj, struct gendisk, kobj);
553 add_uevent_var(env, "MINOR=%u", disk->first_minor);
554 } else if (ktype == &ktype_part) {
555 disk = container_of(kobj->parent, struct gendisk, kobj);
556 part = container_of(kobj, struct hd_struct, kobj);
557 add_uevent_var(env, "MINOR=%u",
558 disk->first_minor + part->partno);
559 } else
560 return 0;
561
562 add_uevent_var(env, "MAJOR=%u", disk->major);
563
564 /* add physical device, backing this device */
565 physdev = disk->driverfs_dev;
566 if (physdev) {
567 char *path = kobject_get_path(&physdev->kobj, GFP_KERNEL);
568
569 add_uevent_var(env, "PHYSDEVPATH=%s", path);
570 kfree(path);
571
572 if (physdev->bus)
573 add_uevent_var(env, "PHYSDEVBUS=%s", physdev->bus->name);
574
575 if (physdev->driver)
576 add_uevent_var(env, physdev->driver->name);
577 }
578
579 return 0;
580}
581
582static struct kset_uevent_ops block_uevent_ops = {
583 .filter = block_uevent_filter,
584 .uevent = block_uevent,
585}; 509};
586 510
587decl_subsys(block, &ktype_block, &block_uevent_ops);
588
589/* 511/*
590 * aggregate disk stat collector. Uses the same stats that the sysfs 512 * aggregate disk stat collector. Uses the same stats that the sysfs
591 * entries do, above, but makes them available through one seq_file. 513 * entries do, above, but makes them available through one seq_file.
592 * Watching a few disks may be efficient through sysfs, but watching
593 * all of them will be more efficient through this interface.
594 * 514 *
595 * The output looks suspiciously like /proc/partitions with a bunch of 515 * The output looks suspiciously like /proc/partitions with a bunch of
596 * extra fields. 516 * extra fields.
597 */ 517 */
598 518
599/* iterator */
600static void *diskstats_start(struct seq_file *part, loff_t *pos) 519static void *diskstats_start(struct seq_file *part, loff_t *pos)
601{ 520{
602 loff_t k = *pos; 521 loff_t k = *pos;
603 struct list_head *p; 522 struct device *dev;
604 523
605 mutex_lock(&block_subsys_lock); 524 mutex_lock(&block_class_lock);
606 list_for_each(p, &block_subsys.list) 525 list_for_each_entry(dev, &block_class.devices, node) {
526 if (dev->type != &disk_type)
527 continue;
607 if (!k--) 528 if (!k--)
608 return list_entry(p, struct gendisk, kobj.entry); 529 return dev_to_disk(dev);
530 }
609 return NULL; 531 return NULL;
610} 532}
611 533
612static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) 534static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos)
613{ 535{
614 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 536 struct gendisk *gp = v;
537 struct device *dev;
538
615 ++*pos; 539 ++*pos;
616 return p==&block_subsys.list ? NULL : 540 list_for_each_entry(dev, &gp->dev.node, node) {
617 list_entry(p, struct gendisk, kobj.entry); 541 if (&dev->node == &block_class.devices)
542 return NULL;
543 if (dev->type == &disk_type)
544 return dev_to_disk(dev);
545 }
546 return NULL;
618} 547}
619 548
620static void diskstats_stop(struct seq_file *part, void *v) 549static void diskstats_stop(struct seq_file *part, void *v)
621{ 550{
622 mutex_unlock(&block_subsys_lock); 551 mutex_unlock(&block_class_lock);
623} 552}
624 553
625static int diskstats_show(struct seq_file *s, void *v) 554static int diskstats_show(struct seq_file *s, void *v)
@@ -629,7 +558,7 @@ static int diskstats_show(struct seq_file *s, void *v)
629 int n = 0; 558 int n = 0;
630 559
631 /* 560 /*
632 if (&sgp->kobj.entry == block_subsys.kset.list.next) 561 if (&gp->dev.kobj.entry == block_class.devices.next)
633 seq_puts(s, "major minor name" 562 seq_puts(s, "major minor name"
634 " rio rmerge rsect ruse wio wmerge " 563 " rio rmerge rsect ruse wio wmerge "
635 "wsect wuse running use aveq" 564 "wsect wuse running use aveq"
@@ -683,7 +612,7 @@ static void media_change_notify_thread(struct work_struct *work)
683 * set enviroment vars to indicate which event this is for 612 * set enviroment vars to indicate which event this is for
684 * so that user space will know to go check the media status. 613 * so that user space will know to go check the media status.
685 */ 614 */
686 kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); 615 kobject_uevent_env(&gd->dev.kobj, KOBJ_CHANGE, envp);
687 put_device(gd->driverfs_dev); 616 put_device(gd->driverfs_dev);
688} 617}
689 618
@@ -694,6 +623,25 @@ void genhd_media_change_notify(struct gendisk *disk)
694} 623}
695EXPORT_SYMBOL_GPL(genhd_media_change_notify); 624EXPORT_SYMBOL_GPL(genhd_media_change_notify);
696 625
626dev_t blk_lookup_devt(const char *name)
627{
628 struct device *dev;
629 dev_t devt = MKDEV(0, 0);
630
631 mutex_lock(&block_class_lock);
632 list_for_each_entry(dev, &block_class.devices, node) {
633 if (strcmp(dev->bus_id, name) == 0) {
634 devt = dev->devt;
635 break;
636 }
637 }
638 mutex_unlock(&block_class_lock);
639
640 return devt;
641}
642
643EXPORT_SYMBOL(blk_lookup_devt);
644
697struct gendisk *alloc_disk(int minors) 645struct gendisk *alloc_disk(int minors)
698{ 646{
699 return alloc_disk_node(minors, -1); 647 return alloc_disk_node(minors, -1);
@@ -721,9 +669,10 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
721 } 669 }
722 } 670 }
723 disk->minors = minors; 671 disk->minors = minors;
724 kobj_set_kset_s(disk,block_subsys);
725 kobject_init(&disk->kobj);
726 rand_initialize_disk(disk); 672 rand_initialize_disk(disk);
673 disk->dev.class = &block_class;
674 disk->dev.type = &disk_type;
675 device_initialize(&disk->dev);
727 INIT_WORK(&disk->async_notify, 676 INIT_WORK(&disk->async_notify,
728 media_change_notify_thread); 677 media_change_notify_thread);
729 } 678 }
@@ -743,7 +692,7 @@ struct kobject *get_disk(struct gendisk *disk)
743 owner = disk->fops->owner; 692 owner = disk->fops->owner;
744 if (owner && !try_module_get(owner)) 693 if (owner && !try_module_get(owner))
745 return NULL; 694 return NULL;
746 kobj = kobject_get(&disk->kobj); 695 kobj = kobject_get(&disk->dev.kobj);
747 if (kobj == NULL) { 696 if (kobj == NULL) {
748 module_put(owner); 697 module_put(owner);
749 return NULL; 698 return NULL;
@@ -757,7 +706,7 @@ EXPORT_SYMBOL(get_disk);
757void put_disk(struct gendisk *disk) 706void put_disk(struct gendisk *disk)
758{ 707{
759 if (disk) 708 if (disk)
760 kobject_put(&disk->kobj); 709 kobject_put(&disk->dev.kobj);
761} 710}
762 711
763EXPORT_SYMBOL(put_disk); 712EXPORT_SYMBOL(put_disk);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 8b919940b2ab..5ccec8aa964b 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -1862,9 +1862,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
1862 1862
1863 init_timer(&q->unplug_timer); 1863 init_timer(&q->unplug_timer);
1864 1864
1865 kobject_set_name(&q->kobj, "%s", "queue"); 1865 kobject_init(&q->kobj, &queue_ktype);
1866 q->kobj.ktype = &queue_ktype;
1867 kobject_init(&q->kobj);
1868 1866
1869 mutex_init(&q->sysfs_lock); 1867 mutex_init(&q->sysfs_lock);
1870 1868
@@ -4182,9 +4180,8 @@ int blk_register_queue(struct gendisk *disk)
4182 if (!q || !q->request_fn) 4180 if (!q || !q->request_fn)
4183 return -ENXIO; 4181 return -ENXIO;
4184 4182
4185 q->kobj.parent = kobject_get(&disk->kobj); 4183 ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj),
4186 4184 "%s", "queue");
4187 ret = kobject_add(&q->kobj);
4188 if (ret < 0) 4185 if (ret < 0)
4189 return ret; 4186 return ret;
4190 4187
@@ -4209,6 +4206,6 @@ void blk_unregister_queue(struct gendisk *disk)
4209 4206
4210 kobject_uevent(&q->kobj, KOBJ_REMOVE); 4207 kobject_uevent(&q->kobj, KOBJ_REMOVE);
4211 kobject_del(&q->kobj); 4208 kobject_del(&q->kobj);
4212 kobject_put(&disk->kobj); 4209 kobject_put(&disk->dev.kobj);
4213 } 4210 }
4214} 4211}