aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKay Sievers <kay.sievers@vrfy.org>2007-05-21 16:08:01 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2008-01-24 23:40:36 -0500
commitedfaa7c36574f1bf09c65ad602412db9da5f96bf (patch)
treed591b80ff9229e4845e41d68e2f4c5aadb017027
parent09f82ea92822a7bbb7e816508abbda47ed54a77f (diff)
Driver core: convert block from raw kobjects to core devices
This moves the block devices to /sys/class/block. It will create a flat list of all block devices, with the disks and partitions in one directory. For compatibility /sys/block is created and contains symlinks to the disks. /sys/class/block |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1 |-- sda10 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda10 |-- sda5 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda5 |-- sda6 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda6 |-- sda7 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda7 |-- sda8 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda8 |-- sda9 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda9 `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0 /sys/block/ |-- sda -> ../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda `-- sr0 -> ../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0 Signed-off-by: Kay Sievers <kay.sievers@vrfy.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--block/genhd.c416
-rw-r--r--block/ll_rw_blk.c4
-rw-r--r--drivers/base/class.c7
-rw-r--r--drivers/base/core.c20
-rw-r--r--drivers/block/aoe/aoeblk.c51
-rw-r--r--drivers/block/nbd.c15
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/md/dm.c4
-rw-r--r--drivers/md/md.c8
-rw-r--r--fs/block_dev.c8
-rw-r--r--fs/partitions/check.c315
-rw-r--r--include/linux/genhd.h37
-rw-r--r--init/do_mounts.c108
13 files changed, 385 insertions, 610 deletions
diff --git a/block/genhd.c b/block/genhd.c
index 69aa7389d484..5e4ab4b37d9f 100644
--- a/block/genhd.c
+++ b/block/genhd.c
@@ -17,9 +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_kset; 20static DEFINE_MUTEX(block_class_lock);
21static struct kset_uevent_ops block_uevent_ops; 21#ifndef CONFIG_SYSFS_DEPRECATED
22static DEFINE_MUTEX(block_subsys_lock); 22struct kobject *block_depr;
23#endif
23 24
24/* 25/*
25 * Can be deleted altogether. Later. 26 * Can be deleted altogether. Later.
@@ -38,19 +39,17 @@ static inline int major_to_index(int major)
38} 39}
39 40
40#ifdef CONFIG_PROC_FS 41#ifdef CONFIG_PROC_FS
41
42void blkdev_show(struct seq_file *f, off_t offset) 42void blkdev_show(struct seq_file *f, off_t offset)
43{ 43{
44 struct blk_major_name *dp; 44 struct blk_major_name *dp;
45 45
46 if (offset < BLKDEV_MAJOR_HASH_SIZE) { 46 if (offset < BLKDEV_MAJOR_HASH_SIZE) {
47 mutex_lock(&block_subsys_lock); 47 mutex_lock(&block_class_lock);
48 for (dp = major_names[offset]; dp; dp = dp->next) 48 for (dp = major_names[offset]; dp; dp = dp->next)
49 seq_printf(f, "%3d %s\n", dp->major, dp->name); 49 seq_printf(f, "%3d %s\n", dp->major, dp->name);
50 mutex_unlock(&block_subsys_lock); 50 mutex_unlock(&block_class_lock);
51 } 51 }
52} 52}
53
54#endif /* CONFIG_PROC_FS */ 53#endif /* CONFIG_PROC_FS */
55 54
56int register_blkdev(unsigned int major, const char *name) 55int register_blkdev(unsigned int major, const char *name)
@@ -58,7 +57,7 @@ int register_blkdev(unsigned int major, const char *name)
58 struct blk_major_name **n, *p; 57 struct blk_major_name **n, *p;
59 int index, ret = 0; 58 int index, ret = 0;
60 59
61 mutex_lock(&block_subsys_lock); 60 mutex_lock(&block_class_lock);
62 61
63 /* temporary */ 62 /* temporary */
64 if (major == 0) { 63 if (major == 0) {
@@ -103,7 +102,7 @@ int register_blkdev(unsigned int major, const char *name)
103 kfree(p); 102 kfree(p);
104 } 103 }
105out: 104out:
106 mutex_unlock(&block_subsys_lock); 105 mutex_unlock(&block_class_lock);
107 return ret; 106 return ret;
108} 107}
109 108
@@ -115,7 +114,7 @@ void unregister_blkdev(unsigned int major, const char *name)
115 struct blk_major_name *p = NULL; 114 struct blk_major_name *p = NULL;
116 int index = major_to_index(major); 115 int index = major_to_index(major);
117 116
118 mutex_lock(&block_subsys_lock); 117 mutex_lock(&block_class_lock);
119 for (n = &major_names[index]; *n; n = &(*n)->next) 118 for (n = &major_names[index]; *n; n = &(*n)->next)
120 if ((*n)->major == major) 119 if ((*n)->major == major)
121 break; 120 break;
@@ -125,7 +124,7 @@ void unregister_blkdev(unsigned int major, const char *name)
125 p = *n; 124 p = *n;
126 *n = p->next; 125 *n = p->next;
127 } 126 }
128 mutex_unlock(&block_subsys_lock); 127 mutex_unlock(&block_class_lock);
129 kfree(p); 128 kfree(p);
130} 129}
131 130
@@ -138,29 +137,30 @@ static struct kobj_map *bdev_map;
138 * range must be nonzero 137 * range must be nonzero
139 * 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.
140 */ 139 */
141void 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,
142 struct kobject *(*probe)(dev_t, int *, void *), 141 struct kobject *(*probe)(dev_t, int *, void *),
143 int (*lock)(dev_t, void *), void *data) 142 int (*lock)(dev_t, void *), void *data)
144{ 143{
145 kobj_map(bdev_map, dev, range, module, probe, lock, data); 144 kobj_map(bdev_map, devt, range, module, probe, lock, data);
146} 145}
147 146
148EXPORT_SYMBOL(blk_register_region); 147EXPORT_SYMBOL(blk_register_region);
149 148
150void blk_unregister_region(dev_t dev, unsigned long range) 149void blk_unregister_region(dev_t devt, unsigned long range)
151{ 150{
152 kobj_unmap(bdev_map, dev, range); 151 kobj_unmap(bdev_map, devt, range);
153} 152}
154 153
155EXPORT_SYMBOL(blk_unregister_region); 154EXPORT_SYMBOL(blk_unregister_region);
156 155
157static struct kobject *exact_match(dev_t dev, int *part, void *data) 156static struct kobject *exact_match(dev_t devt, int *part, void *data)
158{ 157{
159 struct gendisk *p = data; 158 struct gendisk *p = data;
160 return &p->kobj; 159
160 return &p->dev.kobj;
161} 161}
162 162
163static int exact_lock(dev_t dev, void *data) 163static int exact_lock(dev_t devt, void *data)
164{ 164{
165 struct gendisk *p = data; 165 struct gendisk *p = data;
166 166
@@ -195,8 +195,6 @@ void unlink_gendisk(struct gendisk *disk)
195 disk->minors); 195 disk->minors);
196} 196}
197 197
198#define to_disk(obj) container_of(obj,struct gendisk,kobj)
199
200/** 198/**
201 * get_gendisk - get partitioning information for a given device 199 * get_gendisk - get partitioning information for a given device
202 * @dev: device to get partitioning information for 200 * @dev: device to get partitioning information for
@@ -204,10 +202,12 @@ void unlink_gendisk(struct gendisk *disk)
204 * This function gets the structure containing partitioning 202 * This function gets the structure containing partitioning
205 * information for the given device @dev. 203 * information for the given device @dev.
206 */ 204 */
207struct gendisk *get_gendisk(dev_t dev, int *part) 205struct gendisk *get_gendisk(dev_t devt, int *part)
208{ 206{
209 struct kobject *kobj = kobj_lookup(bdev_map, dev, part); 207 struct kobject *kobj = kobj_lookup(bdev_map, devt, part);
210 return kobj ? to_disk(kobj) : NULL; 208 struct device *dev = kobj_to_dev(kobj);
209
210 return kobj ? dev_to_disk(dev) : NULL;
211} 211}
212 212
213/* 213/*
@@ -217,13 +217,17 @@ struct gendisk *get_gendisk(dev_t dev, int *part)
217 */ 217 */
218void __init printk_all_partitions(void) 218void __init printk_all_partitions(void)
219{ 219{
220 int n; 220 struct device *dev;
221 struct gendisk *sgp; 221 struct gendisk *sgp;
222 char buf[BDEVNAME_SIZE];
223 int n;
222 224
223 mutex_lock(&block_subsys_lock); 225 mutex_lock(&block_class_lock);
224 /* For each block device... */ 226 /* For each block device... */
225 list_for_each_entry(sgp, &block_kset->list, kobj.entry) { 227 list_for_each_entry(dev, &block_class.devices, node) {
226 char buf[BDEVNAME_SIZE]; 228 if (dev->type != &disk_type)
229 continue;
230 sgp = dev_to_disk(dev);
227 /* 231 /*
228 * Don't show empty devices or things that have been surpressed 232 * Don't show empty devices or things that have been surpressed
229 */ 233 */
@@ -256,38 +260,46 @@ void __init printk_all_partitions(void)
256 sgp->major, n + 1 + sgp->first_minor, 260 sgp->major, n + 1 + sgp->first_minor,
257 (unsigned long long)sgp->part[n]->nr_sects >> 1, 261 (unsigned long long)sgp->part[n]->nr_sects >> 1,
258 disk_name(sgp, n + 1, buf)); 262 disk_name(sgp, n + 1, buf));
259 } /* partition subloop */ 263 }
260 } /* Block device loop */ 264 }
261 265
262 mutex_unlock(&block_subsys_lock); 266 mutex_unlock(&block_class_lock);
263 return;
264} 267}
265 268
266#ifdef CONFIG_PROC_FS 269#ifdef CONFIG_PROC_FS
267/* iterator */ 270/* iterator */
268static void *part_start(struct seq_file *part, loff_t *pos) 271static void *part_start(struct seq_file *part, loff_t *pos)
269{ 272{
270 struct list_head *p; 273 loff_t k = *pos;
271 loff_t l = *pos; 274 struct device *dev;
272 275
273 mutex_lock(&block_subsys_lock); 276 mutex_lock(&block_class_lock);
274 list_for_each(p, &block_kset->list) 277 list_for_each_entry(dev, &block_class.devices, node) {
275 if (!l--) 278 if (dev->type != &disk_type)
276 return list_entry(p, struct gendisk, kobj.entry); 279 continue;
280 if (!k--)
281 return dev_to_disk(dev);
282 }
277 return NULL; 283 return NULL;
278} 284}
279 285
280static 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)
281{ 287{
282 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 288 struct gendisk *gp = v;
289 struct device *dev;
283 ++*pos; 290 ++*pos;
284 return p==&block_kset->list ? NULL : 291 list_for_each_entry(dev, &gp->dev.node, node) {
285 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;
286} 298}
287 299
288static void part_stop(struct seq_file *part, void *v) 300static void part_stop(struct seq_file *part, void *v)
289{ 301{
290 mutex_unlock(&block_subsys_lock); 302 mutex_unlock(&block_class_lock);
291} 303}
292 304
293static int show_partition(struct seq_file *part, void *v) 305static int show_partition(struct seq_file *part, void *v)
@@ -296,7 +308,7 @@ static int show_partition(struct seq_file *part, void *v)
296 int n; 308 int n;
297 char buf[BDEVNAME_SIZE]; 309 char buf[BDEVNAME_SIZE];
298 310
299 if (&sgp->kobj.entry == block_kset->list.next) 311 if (&sgp->dev.node == block_class.devices.next)
300 seq_puts(part, "major minor #blocks name\n\n"); 312 seq_puts(part, "major minor #blocks name\n\n");
301 313
302 /* Don't show non-partitionable removeable devices or empty devices */ 314 /* Don't show non-partitionable removeable devices or empty devices */
@@ -326,109 +338,81 @@ static int show_partition(struct seq_file *part, void *v)
326} 338}
327 339
328struct seq_operations partitions_op = { 340struct seq_operations partitions_op = {
329 .start =part_start, 341 .start = part_start,
330 .next = part_next, 342 .next = part_next,
331 .stop = part_stop, 343 .stop = part_stop,
332 .show = show_partition 344 .show = show_partition
333}; 345};
334#endif 346#endif
335 347
336 348
337extern int blk_dev_init(void); 349extern int blk_dev_init(void);
338 350
339static struct kobject *base_probe(dev_t dev, int *part, void *data) 351static struct kobject *base_probe(dev_t devt, int *part, void *data)
340{ 352{
341 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)
342 /* Make old-style 2.4 aliases work */ 354 /* Make old-style 2.4 aliases work */
343 request_module("block-major-%d", MAJOR(dev)); 355 request_module("block-major-%d", MAJOR(devt));
344 return NULL; 356 return NULL;
345} 357}
346 358
347static int __init genhd_device_init(void) 359static int __init genhd_device_init(void)
348{ 360{
349 bdev_map = kobj_map_init(base_probe, &block_subsys_lock); 361 class_register(&block_class);
362 bdev_map = kobj_map_init(base_probe, &block_class_lock);
350 blk_dev_init(); 363 blk_dev_init();
351 block_kset = kset_create_and_add("block", &block_uevent_ops, NULL); 364
352 if (!block_kset) { 365#ifndef CONFIG_SYSFS_DEPRECATED
353 printk(KERN_WARNING "%s: kset_create error\n", __FUNCTION__); 366 /* create top-level block dir */
354 return -ENOMEM; 367 block_depr = kobject_create_and_add("block", NULL);
355 } 368#endif
356 return 0; 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{ 393{
400 kobject_uevent(&disk->kobj, KOBJ_ADD); 394 struct gendisk *disk = dev_to_disk(dev);
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{
410 return sprintf(page, "%d\n", disk->minors);
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,134 +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,
511 &disk_attr_stat.attr,
512 &disk_attr_capability.attr,
513#ifdef CONFIG_FAIL_MAKE_REQUEST 466#ifdef CONFIG_FAIL_MAKE_REQUEST
514 &disk_attr_fail.attr, 467static struct device_attribute dev_attr_fail =
468 __ATTR(make-it-fail, S_IRUGO|S_IWUSR, disk_fail_show, disk_fail_store);
515#endif 469#endif
516 NULL, 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,
477#ifdef CONFIG_FAIL_MAKE_REQUEST
478 &dev_attr_fail.attr,
479#endif
480 NULL
481};
482
483static struct attribute_group disk_attr_group = {
484 .attrs = disk_attrs,
485};
486
487static struct attribute_group *disk_attr_groups[] = {
488 &disk_attr_group,
489 NULL
517}; 490};
518 491
519static void disk_release(struct kobject * kobj) 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
587/* 511/*
588 * aggregate disk stat collector. Uses the same stats that the sysfs 512 * aggregate disk stat collector. Uses the same stats that the sysfs
589 * entries do, above, but makes them available through one seq_file. 513 * entries do, above, but makes them available through one seq_file.
590 * Watching a few disks may be efficient through sysfs, but watching
591 * all of them will be more efficient through this interface.
592 * 514 *
593 * The output looks suspiciously like /proc/partitions with a bunch of 515 * The output looks suspiciously like /proc/partitions with a bunch of
594 * extra fields. 516 * extra fields.
595 */ 517 */
596 518
597/* iterator */
598static void *diskstats_start(struct seq_file *part, loff_t *pos) 519static void *diskstats_start(struct seq_file *part, loff_t *pos)
599{ 520{
600 loff_t k = *pos; 521 loff_t k = *pos;
601 struct list_head *p; 522 struct device *dev;
602 523
603 mutex_lock(&block_subsys_lock); 524 mutex_lock(&block_class_lock);
604 list_for_each(p, &block_kset->list) 525 list_for_each_entry(dev, &block_class.devices, node) {
526 if (dev->type != &disk_type)
527 continue;
605 if (!k--) 528 if (!k--)
606 return list_entry(p, struct gendisk, kobj.entry); 529 return dev_to_disk(dev);
530 }
607 return NULL; 531 return NULL;
608} 532}
609 533
610static 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)
611{ 535{
612 struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; 536 struct gendisk *gp = v;
537 struct device *dev;
538
613 ++*pos; 539 ++*pos;
614 return p==&block_kset->list ? NULL : 540 list_for_each_entry(dev, &gp->dev.node, node) {
615 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;
616} 547}
617 548
618static void diskstats_stop(struct seq_file *part, void *v) 549static void diskstats_stop(struct seq_file *part, void *v)
619{ 550{
620 mutex_unlock(&block_subsys_lock); 551 mutex_unlock(&block_class_lock);
621} 552}
622 553
623static int diskstats_show(struct seq_file *s, void *v) 554static int diskstats_show(struct seq_file *s, void *v)
@@ -627,7 +558,7 @@ static int diskstats_show(struct seq_file *s, void *v)
627 int n = 0; 558 int n = 0;
628 559
629 /* 560 /*
630 if (&sgp->kobj.entry == block_kset->list.next) 561 if (&gp->dev.kobj.entry == block_class.devices.next)
631 seq_puts(s, "major minor name" 562 seq_puts(s, "major minor name"
632 " rio rmerge rsect ruse wio wmerge " 563 " rio rmerge rsect ruse wio wmerge "
633 "wsect wuse running use aveq" 564 "wsect wuse running use aveq"
@@ -681,7 +612,7 @@ static void media_change_notify_thread(struct work_struct *work)
681 * set enviroment vars to indicate which event this is for 612 * set enviroment vars to indicate which event this is for
682 * 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.
683 */ 614 */
684 kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); 615 kobject_uevent_env(&gd->dev.kobj, KOBJ_CHANGE, envp);
685 put_device(gd->driverfs_dev); 616 put_device(gd->driverfs_dev);
686} 617}
687 618
@@ -692,6 +623,25 @@ void genhd_media_change_notify(struct gendisk *disk)
692} 623}
693EXPORT_SYMBOL_GPL(genhd_media_change_notify); 624EXPORT_SYMBOL_GPL(genhd_media_change_notify);
694 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
695struct gendisk *alloc_disk(int minors) 645struct gendisk *alloc_disk(int minors)
696{ 646{
697 return alloc_disk_node(minors, -1); 647 return alloc_disk_node(minors, -1);
@@ -719,10 +669,10 @@ struct gendisk *alloc_disk_node(int minors, int node_id)
719 } 669 }
720 } 670 }
721 disk->minors = minors; 671 disk->minors = minors;
722 disk->kobj.kset = block_kset;
723 disk->kobj.ktype = &ktype_block;
724 kobject_init(&disk->kobj);
725 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);
726 INIT_WORK(&disk->async_notify, 676 INIT_WORK(&disk->async_notify,
727 media_change_notify_thread); 677 media_change_notify_thread);
728 } 678 }
@@ -742,7 +692,7 @@ struct kobject *get_disk(struct gendisk *disk)
742 owner = disk->fops->owner; 692 owner = disk->fops->owner;
743 if (owner && !try_module_get(owner)) 693 if (owner && !try_module_get(owner))
744 return NULL; 694 return NULL;
745 kobj = kobject_get(&disk->kobj); 695 kobj = kobject_get(&disk->dev.kobj);
746 if (kobj == NULL) { 696 if (kobj == NULL) {
747 module_put(owner); 697 module_put(owner);
748 return NULL; 698 return NULL;
@@ -756,7 +706,7 @@ EXPORT_SYMBOL(get_disk);
756void put_disk(struct gendisk *disk) 706void put_disk(struct gendisk *disk)
757{ 707{
758 if (disk) 708 if (disk)
759 kobject_put(&disk->kobj); 709 kobject_put(&disk->dev.kobj);
760} 710}
761 711
762EXPORT_SYMBOL(put_disk); 712EXPORT_SYMBOL(put_disk);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index 8b919940b2ab..3887b2a33ed0 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -4182,7 +4182,7 @@ int blk_register_queue(struct gendisk *disk)
4182 if (!q || !q->request_fn) 4182 if (!q || !q->request_fn)
4183 return -ENXIO; 4183 return -ENXIO;
4184 4184
4185 q->kobj.parent = kobject_get(&disk->kobj); 4185 q->kobj.parent = kobject_get(&disk->dev.kobj);
4186 4186
4187 ret = kobject_add(&q->kobj); 4187 ret = kobject_add(&q->kobj);
4188 if (ret < 0) 4188 if (ret < 0)
@@ -4209,6 +4209,6 @@ void blk_unregister_queue(struct gendisk *disk)
4209 4209
4210 kobject_uevent(&q->kobj, KOBJ_REMOVE); 4210 kobject_uevent(&q->kobj, KOBJ_REMOVE);
4211 kobject_del(&q->kobj); 4211 kobject_del(&q->kobj);
4212 kobject_put(&disk->kobj); 4212 kobject_put(&disk->dev.kobj);
4213 } 4213 }
4214} 4214}
diff --git a/drivers/base/class.c b/drivers/base/class.c
index ba6745b0fd2f..624b3316e938 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -17,6 +17,7 @@
17#include <linux/kdev_t.h> 17#include <linux/kdev_t.h>
18#include <linux/err.h> 18#include <linux/err.h>
19#include <linux/slab.h> 19#include <linux/slab.h>
20#include <linux/genhd.h>
20#include "base.h" 21#include "base.h"
21 22
22#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr) 23#define to_class_attr(_attr) container_of(_attr, struct class_attribute, attr)
@@ -149,7 +150,13 @@ int class_register(struct class * cls)
149 if (error) 150 if (error)
150 return error; 151 return error;
151 152
153#ifdef CONFIG_SYSFS_DEPRECATED
154 /* let the block class directory show up in the root of sysfs */
155 if (cls != &block_class)
156 cls->subsys.kobj.kset = class_kset;
157#else
152 cls->subsys.kobj.kset = class_kset; 158 cls->subsys.kobj.kset = class_kset;
159#endif
153 cls->subsys.kobj.ktype = &class_ktype; 160 cls->subsys.kobj.ktype = &class_ktype;
154 161
155 error = kset_register(&cls->subsys); 162 error = kset_register(&cls->subsys);
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 13cae18936c5..06e8738ab263 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -671,14 +671,15 @@ static int device_add_class_symlinks(struct device *dev)
671 671
672#ifdef CONFIG_SYSFS_DEPRECATED 672#ifdef CONFIG_SYSFS_DEPRECATED
673 /* stacked class devices need a symlink in the class directory */ 673 /* stacked class devices need a symlink in the class directory */
674 if (dev->kobj.parent != &dev->class->subsys.kobj) { 674 if (dev->kobj.parent != &dev->class->subsys.kobj &&
675 dev->type != &part_type) {
675 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj, 676 error = sysfs_create_link(&dev->class->subsys.kobj, &dev->kobj,
676 dev->bus_id); 677 dev->bus_id);
677 if (error) 678 if (error)
678 goto out_subsys; 679 goto out_subsys;
679 } 680 }
680 681
681 if (dev->parent) { 682 if (dev->parent && dev->type != &part_type) {
682 struct device *parent = dev->parent; 683 struct device *parent = dev->parent;
683 char *class_name; 684 char *class_name;
684 685
@@ -707,10 +708,11 @@ static int device_add_class_symlinks(struct device *dev)
707 return 0; 708 return 0;
708 709
709out_device: 710out_device:
710 if (dev->parent) 711 if (dev->parent && dev->type != &part_type)
711 sysfs_remove_link(&dev->kobj, "device"); 712 sysfs_remove_link(&dev->kobj, "device");
712out_busid: 713out_busid:
713 if (dev->kobj.parent != &dev->class->subsys.kobj) 714 if (dev->kobj.parent != &dev->class->subsys.kobj &&
715 dev->type != &part_type)
714 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); 716 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
715#else 717#else
716 /* link in the class directory pointing to the device */ 718 /* link in the class directory pointing to the device */
@@ -719,7 +721,7 @@ out_busid:
719 if (error) 721 if (error)
720 goto out_subsys; 722 goto out_subsys;
721 723
722 if (dev->parent) { 724 if (dev->parent && dev->type != &part_type) {
723 error = sysfs_create_link(&dev->kobj, &dev->parent->kobj, 725 error = sysfs_create_link(&dev->kobj, &dev->parent->kobj,
724 "device"); 726 "device");
725 if (error) 727 if (error)
@@ -743,7 +745,7 @@ static void device_remove_class_symlinks(struct device *dev)
743 return; 745 return;
744 746
745#ifdef CONFIG_SYSFS_DEPRECATED 747#ifdef CONFIG_SYSFS_DEPRECATED
746 if (dev->parent) { 748 if (dev->parent && dev->type != &part_type) {
747 char *class_name; 749 char *class_name;
748 750
749 class_name = make_class_name(dev->class->name, &dev->kobj); 751 class_name = make_class_name(dev->class->name, &dev->kobj);
@@ -754,10 +756,11 @@ static void device_remove_class_symlinks(struct device *dev)
754 sysfs_remove_link(&dev->kobj, "device"); 756 sysfs_remove_link(&dev->kobj, "device");
755 } 757 }
756 758
757 if (dev->kobj.parent != &dev->class->subsys.kobj) 759 if (dev->kobj.parent != &dev->class->subsys.kobj &&
760 dev->type != &part_type)
758 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); 761 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
759#else 762#else
760 if (dev->parent) 763 if (dev->parent && dev->type != &part_type)
761 sysfs_remove_link(&dev->kobj, "device"); 764 sysfs_remove_link(&dev->kobj, "device");
762 765
763 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id); 766 sysfs_remove_link(&dev->class->subsys.kobj, dev->bus_id);
@@ -925,6 +928,7 @@ struct device * get_device(struct device * dev)
925 */ 928 */
926void put_device(struct device * dev) 929void put_device(struct device * dev)
927{ 930{
931 /* might_sleep(); */
928 if (dev) 932 if (dev)
929 kobject_put(&dev->kobj); 933 kobject_put(&dev->kobj);
930} 934}
diff --git a/drivers/block/aoe/aoeblk.c b/drivers/block/aoe/aoeblk.c
index ad00b3d94711..826d12381e21 100644
--- a/drivers/block/aoe/aoeblk.c
+++ b/drivers/block/aoe/aoeblk.c
@@ -15,8 +15,10 @@
15 15
16static struct kmem_cache *buf_pool_cache; 16static struct kmem_cache *buf_pool_cache;
17 17
18static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) 18static ssize_t aoedisk_show_state(struct device *dev,
19 struct device_attribute *attr, char *page)
19{ 20{
21 struct gendisk *disk = dev_to_disk(dev);
20 struct aoedev *d = disk->private_data; 22 struct aoedev *d = disk->private_data;
21 23
22 return snprintf(page, PAGE_SIZE, 24 return snprintf(page, PAGE_SIZE,
@@ -26,50 +28,47 @@ static ssize_t aoedisk_show_state(struct gendisk * disk, char *page)
26 (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : ""); 28 (d->nopen && !(d->flags & DEVFL_UP)) ? ",closewait" : "");
27 /* I'd rather see nopen exported so we can ditch closewait */ 29 /* I'd rather see nopen exported so we can ditch closewait */
28} 30}
29static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page) 31static ssize_t aoedisk_show_mac(struct device *dev,
32 struct device_attribute *attr, char *page)
30{ 33{
34 struct gendisk *disk = dev_to_disk(dev);
31 struct aoedev *d = disk->private_data; 35 struct aoedev *d = disk->private_data;
32 36
33 return snprintf(page, PAGE_SIZE, "%012llx\n", 37 return snprintf(page, PAGE_SIZE, "%012llx\n",
34 (unsigned long long)mac_addr(d->addr)); 38 (unsigned long long)mac_addr(d->addr));
35} 39}
36static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page) 40static ssize_t aoedisk_show_netif(struct device *dev,
41 struct device_attribute *attr, char *page)
37{ 42{
43 struct gendisk *disk = dev_to_disk(dev);
38 struct aoedev *d = disk->private_data; 44 struct aoedev *d = disk->private_data;
39 45
40 return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name); 46 return snprintf(page, PAGE_SIZE, "%s\n", d->ifp->name);
41} 47}
42/* firmware version */ 48/* firmware version */
43static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page) 49static ssize_t aoedisk_show_fwver(struct device *dev,
50 struct device_attribute *attr, char *page)
44{ 51{
52 struct gendisk *disk = dev_to_disk(dev);
45 struct aoedev *d = disk->private_data; 53 struct aoedev *d = disk->private_data;
46 54
47 return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver); 55 return snprintf(page, PAGE_SIZE, "0x%04x\n", (unsigned int) d->fw_ver);
48} 56}
49 57
50static struct disk_attribute disk_attr_state = { 58static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL);
51 .attr = {.name = "state", .mode = S_IRUGO }, 59static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL);
52 .show = aoedisk_show_state 60static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL);
53}; 61static struct device_attribute dev_attr_firmware_version = {
54static struct disk_attribute disk_attr_mac = { 62 .attr = { .name = "firmware-version", .mode = S_IRUGO, .owner = THIS_MODULE },
55 .attr = {.name = "mac", .mode = S_IRUGO }, 63 .show = aoedisk_show_fwver,
56 .show = aoedisk_show_mac
57};
58static struct disk_attribute disk_attr_netif = {
59 .attr = {.name = "netif", .mode = S_IRUGO },
60 .show = aoedisk_show_netif
61};
62static struct disk_attribute disk_attr_fwver = {
63 .attr = {.name = "firmware-version", .mode = S_IRUGO },
64 .show = aoedisk_show_fwver
65}; 64};
66 65
67static struct attribute *aoe_attrs[] = { 66static struct attribute *aoe_attrs[] = {
68 &disk_attr_state.attr, 67 &dev_attr_state.attr,
69 &disk_attr_mac.attr, 68 &dev_attr_mac.attr,
70 &disk_attr_netif.attr, 69 &dev_attr_netif.attr,
71 &disk_attr_fwver.attr, 70 &dev_attr_firmware_version.attr,
72 NULL 71 NULL,
73}; 72};
74 73
75static const struct attribute_group attr_group = { 74static const struct attribute_group attr_group = {
@@ -79,12 +78,12 @@ static const struct attribute_group attr_group = {
79static int 78static int
80aoedisk_add_sysfs(struct aoedev *d) 79aoedisk_add_sysfs(struct aoedev *d)
81{ 80{
82 return sysfs_create_group(&d->gd->kobj, &attr_group); 81 return sysfs_create_group(&d->gd->dev.kobj, &attr_group);
83} 82}
84void 83void
85aoedisk_rm_sysfs(struct aoedev *d) 84aoedisk_rm_sysfs(struct aoedev *d)
86{ 85{
87 sysfs_remove_group(&d->gd->kobj, &attr_group); 86 sysfs_remove_group(&d->gd->dev.kobj, &attr_group);
88} 87}
89 88
90static int 89static int
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index b4c0888aedc3..ba9b17e507e0 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -375,14 +375,17 @@ harderror:
375 return NULL; 375 return NULL;
376} 376}
377 377
378static ssize_t pid_show(struct gendisk *disk, char *page) 378static ssize_t pid_show(struct device *dev,
379 struct device_attribute *attr, char *buf)
379{ 380{
380 return sprintf(page, "%ld\n", 381 struct gendisk *disk = dev_to_disk(dev);
382
383 return sprintf(buf, "%ld\n",
381 (long) ((struct nbd_device *)disk->private_data)->pid); 384 (long) ((struct nbd_device *)disk->private_data)->pid);
382} 385}
383 386
384static struct disk_attribute pid_attr = { 387static struct device_attribute pid_attr = {
385 .attr = { .name = "pid", .mode = S_IRUGO }, 388 .attr = { .name = "pid", .mode = S_IRUGO, .owner = THIS_MODULE },
386 .show = pid_show, 389 .show = pid_show,
387}; 390};
388 391
@@ -394,7 +397,7 @@ static int nbd_do_it(struct nbd_device *lo)
394 BUG_ON(lo->magic != LO_MAGIC); 397 BUG_ON(lo->magic != LO_MAGIC);
395 398
396 lo->pid = current->pid; 399 lo->pid = current->pid;
397 ret = sysfs_create_file(&lo->disk->kobj, &pid_attr.attr); 400 ret = sysfs_create_file(&lo->disk->dev.kobj, &pid_attr.attr);
398 if (ret) { 401 if (ret) {
399 printk(KERN_ERR "nbd: sysfs_create_file failed!"); 402 printk(KERN_ERR "nbd: sysfs_create_file failed!");
400 return ret; 403 return ret;
@@ -403,7 +406,7 @@ static int nbd_do_it(struct nbd_device *lo)
403 while ((req = nbd_read_stat(lo)) != NULL) 406 while ((req = nbd_read_stat(lo)) != NULL)
404 nbd_end_request(req); 407 nbd_end_request(req);
405 408
406 sysfs_remove_file(&lo->disk->kobj, &pid_attr.attr); 409 sysfs_remove_file(&lo->disk->dev.kobj, &pid_attr.attr);
407 return 0; 410 return 0;
408} 411}
409 412
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 2994523be7bf..0cb3d2bb3ab9 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1173,7 +1173,7 @@ static struct kobject *exact_match(dev_t dev, int *part, void *data)
1173{ 1173{
1174 struct gendisk *p = data; 1174 struct gendisk *p = data;
1175 *part &= (1 << PARTN_BITS) - 1; 1175 *part &= (1 << PARTN_BITS) - 1;
1176 return &p->kobj; 1176 return &p->dev.kobj;
1177} 1177}
1178 1178
1179static int exact_lock(dev_t dev, void *data) 1179static int exact_lock(dev_t dev, void *data)
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 88c0fd657825..f2d24eb3208c 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -1109,7 +1109,7 @@ static void event_callback(void *context)
1109 list_splice_init(&md->uevent_list, &uevents); 1109 list_splice_init(&md->uevent_list, &uevents);
1110 spin_unlock_irqrestore(&md->uevent_lock, flags); 1110 spin_unlock_irqrestore(&md->uevent_lock, flags);
1111 1111
1112 dm_send_uevents(&uevents, &md->disk->kobj); 1112 dm_send_uevents(&uevents, &md->disk->dev.kobj);
1113 1113
1114 atomic_inc(&md->event_nr); 1114 atomic_inc(&md->event_nr);
1115 wake_up(&md->eventq); 1115 wake_up(&md->eventq);
@@ -1530,7 +1530,7 @@ out:
1530 *---------------------------------------------------------------*/ 1530 *---------------------------------------------------------------*/
1531void dm_kobject_uevent(struct mapped_device *md) 1531void dm_kobject_uevent(struct mapped_device *md)
1532{ 1532{
1533 kobject_uevent(&md->disk->kobj, KOBJ_CHANGE); 1533 kobject_uevent(&md->disk->dev.kobj, KOBJ_CHANGE);
1534} 1534}
1535 1535
1536uint32_t dm_next_uevent_seq(struct mapped_device *md) 1536uint32_t dm_next_uevent_seq(struct mapped_device *md)
diff --git a/drivers/md/md.c b/drivers/md/md.c
index c5030863d004..f79efb359215 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -1396,9 +1396,9 @@ static int bind_rdev_to_array(mdk_rdev_t * rdev, mddev_t * mddev)
1396 goto fail; 1396 goto fail;
1397 1397
1398 if (rdev->bdev->bd_part) 1398 if (rdev->bdev->bd_part)
1399 ko = &rdev->bdev->bd_part->kobj; 1399 ko = &rdev->bdev->bd_part->dev.kobj;
1400 else 1400 else
1401 ko = &rdev->bdev->bd_disk->kobj; 1401 ko = &rdev->bdev->bd_disk->dev.kobj;
1402 if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) { 1402 if ((err = sysfs_create_link(&rdev->kobj, ko, "block"))) {
1403 kobject_del(&rdev->kobj); 1403 kobject_del(&rdev->kobj);
1404 goto fail; 1404 goto fail;
@@ -3083,7 +3083,7 @@ static struct kobject *md_probe(dev_t dev, int *part, void *data)
3083 add_disk(disk); 3083 add_disk(disk);
3084 mddev->gendisk = disk; 3084 mddev->gendisk = disk;
3085 mutex_unlock(&disks_mutex); 3085 mutex_unlock(&disks_mutex);
3086 error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->kobj, 3086 error = kobject_init_and_add(&mddev->kobj, &md_ktype, &disk->dev.kobj,
3087 "%s", "md"); 3087 "%s", "md");
3088 if (error) 3088 if (error)
3089 printk(KERN_WARNING "md: cannot register %s/md - name in use\n", 3089 printk(KERN_WARNING "md: cannot register %s/md - name in use\n",
@@ -3361,7 +3361,7 @@ static int do_md_run(mddev_t * mddev)
3361 3361
3362 mddev->changed = 1; 3362 mddev->changed = 1;
3363 md_new_event(mddev); 3363 md_new_event(mddev);
3364 kobject_uevent(&mddev->gendisk->kobj, KOBJ_CHANGE); 3364 kobject_uevent(&mddev->gendisk->dev.kobj, KOBJ_CHANGE);
3365 return 0; 3365 return 0;
3366} 3366}
3367 3367
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 993f78c55221..e48a630ae266 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -738,9 +738,9 @@ EXPORT_SYMBOL(bd_release);
738static struct kobject *bdev_get_kobj(struct block_device *bdev) 738static struct kobject *bdev_get_kobj(struct block_device *bdev)
739{ 739{
740 if (bdev->bd_contains != bdev) 740 if (bdev->bd_contains != bdev)
741 return kobject_get(&bdev->bd_part->kobj); 741 return kobject_get(&bdev->bd_part->dev.kobj);
742 else 742 else
743 return kobject_get(&bdev->bd_disk->kobj); 743 return kobject_get(&bdev->bd_disk->dev.kobj);
744} 744}
745 745
746static struct kobject *bdev_get_holder(struct block_device *bdev) 746static struct kobject *bdev_get_holder(struct block_device *bdev)
@@ -1176,7 +1176,7 @@ static int do_open(struct block_device *bdev, struct file *file, int for_part)
1176 ret = -ENXIO; 1176 ret = -ENXIO;
1177 goto out_first; 1177 goto out_first;
1178 } 1178 }
1179 kobject_get(&p->kobj); 1179 kobject_get(&p->dev.kobj);
1180 bdev->bd_part = p; 1180 bdev->bd_part = p;
1181 bd_set_size(bdev, (loff_t) p->nr_sects << 9); 1181 bd_set_size(bdev, (loff_t) p->nr_sects << 9);
1182 } 1182 }
@@ -1299,7 +1299,7 @@ static int __blkdev_put(struct block_device *bdev, int for_part)
1299 module_put(owner); 1299 module_put(owner);
1300 1300
1301 if (bdev->bd_contains != bdev) { 1301 if (bdev->bd_contains != bdev) {
1302 kobject_put(&bdev->bd_part->kobj); 1302 kobject_put(&bdev->bd_part->dev.kobj);
1303 bdev->bd_part = NULL; 1303 bdev->bd_part = NULL;
1304 } 1304 }
1305 bdev->bd_disk = NULL; 1305 bdev->bd_disk = NULL;
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index 9184215f3ef3..97f3f5f064ee 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -195,96 +195,45 @@ check_partition(struct gendisk *hd, struct block_device *bdev)
195 return ERR_PTR(res); 195 return ERR_PTR(res);
196} 196}
197 197
198/* 198static ssize_t part_start_show(struct device *dev,
199 * sysfs bindings for partitions 199 struct device_attribute *attr, char *buf)
200 */
201
202struct part_attribute {
203 struct attribute attr;
204 ssize_t (*show)(struct hd_struct *,char *);
205 ssize_t (*store)(struct hd_struct *,const char *, size_t);
206};
207
208static ssize_t
209part_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
210{ 200{
211 struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); 201 struct hd_struct *p = dev_to_part(dev);
212 struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
213 ssize_t ret = 0;
214 if (part_attr->show)
215 ret = part_attr->show(p, page);
216 return ret;
217}
218static ssize_t
219part_attr_store(struct kobject * kobj, struct attribute * attr,
220 const char *page, size_t count)
221{
222 struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
223 struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
224 ssize_t ret = 0;
225 202
226 if (part_attr->store) 203 return sprintf(buf, "%llu\n",(unsigned long long)p->start_sect);
227 ret = part_attr->store(p, page, count);
228 return ret;
229} 204}
230 205
231static struct sysfs_ops part_sysfs_ops = { 206static ssize_t part_size_show(struct device *dev,
232 .show = part_attr_show, 207 struct device_attribute *attr, char *buf)
233 .store = part_attr_store,
234};
235
236static ssize_t part_uevent_store(struct hd_struct * p,
237 const char *page, size_t count)
238{ 208{
239 kobject_uevent(&p->kobj, KOBJ_ADD); 209 struct hd_struct *p = dev_to_part(dev);
240 return count; 210 return sprintf(buf, "%llu\n",(unsigned long long)p->nr_sects);
241} 211}
242static ssize_t part_dev_read(struct hd_struct * p, char *page) 212
243{ 213static ssize_t part_stat_show(struct device *dev,
244 struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj); 214 struct device_attribute *attr, char *buf)
245 dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno);
246 return print_dev_t(page, dev);
247}
248static ssize_t part_start_read(struct hd_struct * p, char *page)
249{
250 return sprintf(page, "%llu\n",(unsigned long long)p->start_sect);
251}
252static ssize_t part_size_read(struct hd_struct * p, char *page)
253{
254 return sprintf(page, "%llu\n",(unsigned long long)p->nr_sects);
255}
256static ssize_t part_stat_read(struct hd_struct * p, char *page)
257{ 215{
258 return sprintf(page, "%8u %8llu %8u %8llu\n", 216 struct hd_struct *p = dev_to_part(dev);
217
218 return sprintf(buf, "%8u %8llu %8u %8llu\n",
259 p->ios[0], (unsigned long long)p->sectors[0], 219 p->ios[0], (unsigned long long)p->sectors[0],
260 p->ios[1], (unsigned long long)p->sectors[1]); 220 p->ios[1], (unsigned long long)p->sectors[1]);
261} 221}
262static struct part_attribute part_attr_uevent = {
263 .attr = {.name = "uevent", .mode = S_IWUSR },
264 .store = part_uevent_store
265};
266static struct part_attribute part_attr_dev = {
267 .attr = {.name = "dev", .mode = S_IRUGO },
268 .show = part_dev_read
269};
270static struct part_attribute part_attr_start = {
271 .attr = {.name = "start", .mode = S_IRUGO },
272 .show = part_start_read
273};
274static struct part_attribute part_attr_size = {
275 .attr = {.name = "size", .mode = S_IRUGO },
276 .show = part_size_read
277};
278static struct part_attribute part_attr_stat = {
279 .attr = {.name = "stat", .mode = S_IRUGO },
280 .show = part_stat_read
281};
282 222
283#ifdef CONFIG_FAIL_MAKE_REQUEST 223#ifdef CONFIG_FAIL_MAKE_REQUEST
224static ssize_t part_fail_show(struct device *dev,
225 struct device_attribute *attr, char *buf)
226{
227 struct hd_struct *p = dev_to_part(dev);
284 228
285static ssize_t part_fail_store(struct hd_struct * p, 229 return sprintf(buf, "%d\n", p->make_it_fail);
230}
231
232static ssize_t part_fail_store(struct device *dev,
233 struct device_attribute *attr,
286 const char *buf, size_t count) 234 const char *buf, size_t count)
287{ 235{
236 struct hd_struct *p = dev_to_part(dev);
288 int i; 237 int i;
289 238
290 if (count > 0 && sscanf(buf, "%d", &i) > 0) 239 if (count > 0 && sscanf(buf, "%d", &i) > 0)
@@ -292,49 +241,52 @@ static ssize_t part_fail_store(struct hd_struct * p,
292 241
293 return count; 242 return count;
294} 243}
295static ssize_t part_fail_read(struct hd_struct * p, char *page) 244#endif
296{
297 return sprintf(page, "%d\n", p->make_it_fail);
298}
299static struct part_attribute part_attr_fail = {
300 .attr = {.name = "make-it-fail", .mode = S_IRUGO | S_IWUSR },
301 .store = part_fail_store,
302 .show = part_fail_read
303};
304 245
246static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL);
247static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL);
248static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL);
249#ifdef CONFIG_FAIL_MAKE_REQUEST
250static struct device_attribute dev_attr_fail =
251 __ATTR(make-it-fail, S_IRUGO|S_IWUSR, part_fail_show, part_fail_store);
305#endif 252#endif
306 253
307static struct attribute * default_attrs[] = { 254static struct attribute *part_attrs[] = {
308 &part_attr_uevent.attr, 255 &dev_attr_start.attr,
309 &part_attr_dev.attr, 256 &dev_attr_size.attr,
310 &part_attr_start.attr, 257 &dev_attr_stat.attr,
311 &part_attr_size.attr,
312 &part_attr_stat.attr,
313#ifdef CONFIG_FAIL_MAKE_REQUEST 258#ifdef CONFIG_FAIL_MAKE_REQUEST
314 &part_attr_fail.attr, 259 &dev_attr_fail.attr,
315#endif 260#endif
316 NULL, 261 NULL
317}; 262};
318 263
319extern struct kset *block_kset; 264static struct attribute_group part_attr_group = {
265 .attrs = part_attrs,
266};
320 267
321static void part_release(struct kobject *kobj) 268static struct attribute_group *part_attr_groups[] = {
269 &part_attr_group,
270 NULL
271};
272
273static void part_release(struct device *dev)
322{ 274{
323 struct hd_struct * p = container_of(kobj,struct hd_struct,kobj); 275 struct hd_struct *p = dev_to_part(dev);
324 kfree(p); 276 kfree(p);
325} 277}
326 278
327struct kobj_type ktype_part = { 279struct device_type part_type = {
280 .name = "partition",
281 .groups = part_attr_groups,
328 .release = part_release, 282 .release = part_release,
329 .default_attrs = default_attrs,
330 .sysfs_ops = &part_sysfs_ops,
331}; 283};
332 284
333static inline void partition_sysfs_add_subdir(struct hd_struct *p) 285static inline void partition_sysfs_add_subdir(struct hd_struct *p)
334{ 286{
335 struct kobject *k; 287 struct kobject *k;
336 288
337 k = kobject_get(&p->kobj); 289 k = kobject_get(&p->dev.kobj);
338 p->holder_dir = kobject_create_and_add("holders", k); 290 p->holder_dir = kobject_create_and_add("holders", k);
339 kobject_put(k); 291 kobject_put(k);
340} 292}
@@ -343,7 +295,7 @@ static inline void disk_sysfs_add_subdirs(struct gendisk *disk)
343{ 295{
344 struct kobject *k; 296 struct kobject *k;
345 297
346 k = kobject_get(&disk->kobj); 298 k = kobject_get(&disk->dev.kobj);
347 disk->holder_dir = kobject_create_and_add("holders", k); 299 disk->holder_dir = kobject_create_and_add("holders", k);
348 disk->slave_dir = kobject_create_and_add("slaves", k); 300 disk->slave_dir = kobject_create_and_add("slaves", k);
349 kobject_put(k); 301 kobject_put(k);
@@ -352,6 +304,7 @@ static inline void disk_sysfs_add_subdirs(struct gendisk *disk)
352void delete_partition(struct gendisk *disk, int part) 304void delete_partition(struct gendisk *disk, int part)
353{ 305{
354 struct hd_struct *p = disk->part[part-1]; 306 struct hd_struct *p = disk->part[part-1];
307
355 if (!p) 308 if (!p)
356 return; 309 return;
357 if (!p->nr_sects) 310 if (!p->nr_sects)
@@ -361,113 +314,55 @@ void delete_partition(struct gendisk *disk, int part)
361 p->nr_sects = 0; 314 p->nr_sects = 0;
362 p->ios[0] = p->ios[1] = 0; 315 p->ios[0] = p->ios[1] = 0;
363 p->sectors[0] = p->sectors[1] = 0; 316 p->sectors[0] = p->sectors[1] = 0;
364 sysfs_remove_link(&p->kobj, "subsystem");
365 kobject_unregister(p->holder_dir); 317 kobject_unregister(p->holder_dir);
366 kobject_uevent(&p->kobj, KOBJ_REMOVE); 318 device_del(&p->dev);
367 kobject_del(&p->kobj); 319 put_device(&p->dev);
368 kobject_put(&p->kobj);
369} 320}
370 321
371void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags) 322void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags)
372{ 323{
373 struct hd_struct *p; 324 struct hd_struct *p;
325 int err;
374 326
375 p = kzalloc(sizeof(*p), GFP_KERNEL); 327 p = kzalloc(sizeof(*p), GFP_KERNEL);
376 if (!p) 328 if (!p)
377 return; 329 return;
378 330
379 p->start_sect = start; 331 p->start_sect = start;
380 p->nr_sects = len; 332 p->nr_sects = len;
381 p->partno = part; 333 p->partno = part;
382 p->policy = disk->policy; 334 p->policy = disk->policy;
383 335
384 if (isdigit(disk->kobj.k_name[strlen(disk->kobj.k_name)-1])) 336 if (isdigit(disk->dev.bus_id[strlen(disk->dev.bus_id)-1]))
385 kobject_set_name(&p->kobj, "%sp%d", 337 snprintf(p->dev.bus_id, BUS_ID_SIZE,
386 kobject_name(&disk->kobj), part); 338 "%sp%d", disk->dev.bus_id, part);
387 else 339 else
388 kobject_set_name(&p->kobj, "%s%d", 340 snprintf(p->dev.bus_id, BUS_ID_SIZE,
389 kobject_name(&disk->kobj),part); 341 "%s%d", disk->dev.bus_id, part);
390 p->kobj.parent = &disk->kobj; 342
391 p->kobj.ktype = &ktype_part; 343 device_initialize(&p->dev);
392 kobject_init(&p->kobj); 344 p->dev.devt = MKDEV(disk->major, disk->first_minor + part);
393 kobject_add(&p->kobj); 345 p->dev.class = &block_class;
394 if (!disk->part_uevent_suppress) 346 p->dev.type = &part_type;
395 kobject_uevent(&p->kobj, KOBJ_ADD); 347 p->dev.parent = &disk->dev;
396 sysfs_create_link(&p->kobj, &block_kset->kobj, "subsystem"); 348 disk->part[part-1] = p;
349
350 /* delay uevent until 'holders' subdir is created */
351 p->dev.uevent_suppress = 1;
352 device_add(&p->dev);
353 partition_sysfs_add_subdir(p);
354 p->dev.uevent_suppress = 0;
397 if (flags & ADDPART_FLAG_WHOLEDISK) { 355 if (flags & ADDPART_FLAG_WHOLEDISK) {
398 static struct attribute addpartattr = { 356 static struct attribute addpartattr = {
399 .name = "whole_disk", 357 .name = "whole_disk",
400 .mode = S_IRUSR | S_IRGRP | S_IROTH, 358 .mode = S_IRUSR | S_IRGRP | S_IROTH,
401 }; 359 };
402 360 err = sysfs_create_file(&p->dev.kobj, &addpartattr);
403 sysfs_create_file(&p->kobj, &addpartattr);
404 } 361 }
405 partition_sysfs_add_subdir(p);
406 disk->part[part-1] = p;
407}
408 362
409static char *make_block_name(struct gendisk *disk) 363 /* suppress uevent if the disk supresses it */
410{ 364 if (!disk->dev.uevent_suppress)
411 char *name; 365 kobject_uevent(&p->dev.kobj, KOBJ_ADD);
412 static char *block_str = "block:";
413 int size;
414 char *s;
415
416 size = strlen(block_str) + strlen(disk->disk_name) + 1;
417 name = kmalloc(size, GFP_KERNEL);
418 if (!name)
419 return NULL;
420 strcpy(name, block_str);
421 strcat(name, disk->disk_name);
422 /* ewww... some of these buggers have / in name... */
423 s = strchr(name, '/');
424 if (s)
425 *s = '!';
426 return name;
427}
428
429static int disk_sysfs_symlinks(struct gendisk *disk)
430{
431 struct device *target = get_device(disk->driverfs_dev);
432 int err;
433 char *disk_name = NULL;
434
435 if (target) {
436 disk_name = make_block_name(disk);
437 if (!disk_name) {
438 err = -ENOMEM;
439 goto err_out;
440 }
441
442 err = sysfs_create_link(&disk->kobj, &target->kobj, "device");
443 if (err)
444 goto err_out_disk_name;
445
446 err = sysfs_create_link(&target->kobj, &disk->kobj, disk_name);
447 if (err)
448 goto err_out_dev_link;
449 }
450
451 err = sysfs_create_link(&disk->kobj, &block_kset->kobj,
452 "subsystem");
453 if (err)
454 goto err_out_disk_name_lnk;
455
456 kfree(disk_name);
457
458 return 0;
459
460err_out_disk_name_lnk:
461 if (target) {
462 sysfs_remove_link(&target->kobj, disk_name);
463err_out_dev_link:
464 sysfs_remove_link(&disk->kobj, "device");
465err_out_disk_name:
466 kfree(disk_name);
467err_out:
468 put_device(target);
469 }
470 return err;
471} 366}
472 367
473/* Not exported, helper to add_disk(). */ 368/* Not exported, helper to add_disk(). */
@@ -479,19 +374,29 @@ void register_disk(struct gendisk *disk)
479 struct hd_struct *p; 374 struct hd_struct *p;
480 int err; 375 int err;
481 376
482 kobject_set_name(&disk->kobj, "%s", disk->disk_name); 377 disk->dev.parent = disk->driverfs_dev;
483 /* ewww... some of these buggers have / in name... */ 378 disk->dev.devt = MKDEV(disk->major, disk->first_minor);
484 s = strchr(disk->kobj.k_name, '/'); 379
380 strlcpy(disk->dev.bus_id, disk->disk_name, KOBJ_NAME_LEN);
381 /* ewww... some of these buggers have / in the name... */
382 s = strchr(disk->dev.bus_id, '/');
485 if (s) 383 if (s)
486 *s = '!'; 384 *s = '!';
487 if ((err = kobject_add(&disk->kobj))) 385
386 /* delay uevents, until we scanned partition table */
387 disk->dev.uevent_suppress = 1;
388
389 if (device_add(&disk->dev))
488 return; 390 return;
489 err = disk_sysfs_symlinks(disk); 391#ifndef CONFIG_SYSFS_DEPRECATED
392 err = sysfs_create_link(block_depr, &disk->dev.kobj,
393 kobject_name(&disk->dev.kobj));
490 if (err) { 394 if (err) {
491 kobject_del(&disk->kobj); 395 device_del(&disk->dev);
492 return; 396 return;
493 } 397 }
494 disk_sysfs_add_subdirs(disk); 398#endif
399 disk_sysfs_add_subdirs(disk);
495 400
496 /* No minors to use for partitions */ 401 /* No minors to use for partitions */
497 if (disk->minors == 1) 402 if (disk->minors == 1)
@@ -505,25 +410,23 @@ void register_disk(struct gendisk *disk)
505 if (!bdev) 410 if (!bdev)
506 goto exit; 411 goto exit;
507 412
508 /* scan partition table, but suppress uevents */
509 bdev->bd_invalidated = 1; 413 bdev->bd_invalidated = 1;
510 disk->part_uevent_suppress = 1;
511 err = blkdev_get(bdev, FMODE_READ, 0); 414 err = blkdev_get(bdev, FMODE_READ, 0);
512 disk->part_uevent_suppress = 0;
513 if (err < 0) 415 if (err < 0)
514 goto exit; 416 goto exit;
515 blkdev_put(bdev); 417 blkdev_put(bdev);
516 418
517exit: 419exit:
518 /* announce disk after possible partitions are already created */ 420 /* announce disk after possible partitions are created */
519 kobject_uevent(&disk->kobj, KOBJ_ADD); 421 disk->dev.uevent_suppress = 0;
422 kobject_uevent(&disk->dev.kobj, KOBJ_ADD);
520 423
521 /* announce possible partitions */ 424 /* announce possible partitions */
522 for (i = 1; i < disk->minors; i++) { 425 for (i = 1; i < disk->minors; i++) {
523 p = disk->part[i-1]; 426 p = disk->part[i-1];
524 if (!p || !p->nr_sects) 427 if (!p || !p->nr_sects)
525 continue; 428 continue;
526 kobject_uevent(&p->kobj, KOBJ_ADD); 429 kobject_uevent(&p->dev.kobj, KOBJ_ADD);
527 } 430 }
528} 431}
529 432
@@ -602,19 +505,11 @@ void del_gendisk(struct gendisk *disk)
602 disk_stat_set_all(disk, 0); 505 disk_stat_set_all(disk, 0);
603 disk->stamp = 0; 506 disk->stamp = 0;
604 507
605 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
606 kobject_unregister(disk->holder_dir); 508 kobject_unregister(disk->holder_dir);
607 kobject_unregister(disk->slave_dir); 509 kobject_unregister(disk->slave_dir);
608 if (disk->driverfs_dev) { 510 disk->driverfs_dev = NULL;
609 char *disk_name = make_block_name(disk); 511#ifndef CONFIG_SYSFS_DEPRECATED
610 sysfs_remove_link(&disk->kobj, "device"); 512 sysfs_remove_link(block_depr, disk->dev.bus_id);
611 if (disk_name) { 513#endif
612 sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name); 514 device_del(&disk->dev);
613 kfree(disk_name);
614 }
615 put_device(disk->driverfs_dev);
616 disk->driverfs_dev = NULL;
617 }
618 sysfs_remove_link(&disk->kobj, "subsystem");
619 kobject_del(&disk->kobj);
620} 515}
diff --git a/include/linux/genhd.h b/include/linux/genhd.h
index a47b8025d399..1dbea0ac5693 100644
--- a/include/linux/genhd.h
+++ b/include/linux/genhd.h
@@ -10,9 +10,19 @@
10 */ 10 */
11 11
12#include <linux/types.h> 12#include <linux/types.h>
13#include <linux/kdev_t.h>
13 14
14#ifdef CONFIG_BLOCK 15#ifdef CONFIG_BLOCK
15 16
17#define kobj_to_dev(k) container_of(k, struct device, kobj)
18#define dev_to_disk(device) container_of(device, struct gendisk, dev)
19#define dev_to_part(device) container_of(device, struct hd_struct, dev)
20
21extern struct device_type disk_type;
22extern struct device_type part_type;
23extern struct kobject *block_depr;
24extern struct class block_class;
25
16enum { 26enum {
17/* These three have identical behaviour; use the second one if DOS FDISK gets 27/* These three have identical behaviour; use the second one if DOS FDISK gets
18 confused about extended/logical partitions starting past cylinder 1023. */ 28 confused about extended/logical partitions starting past cylinder 1023. */
@@ -84,7 +94,7 @@ struct partition {
84struct hd_struct { 94struct hd_struct {
85 sector_t start_sect; 95 sector_t start_sect;
86 sector_t nr_sects; 96 sector_t nr_sects;
87 struct kobject kobj; 97 struct device dev;
88 struct kobject *holder_dir; 98 struct kobject *holder_dir;
89 unsigned ios[2], sectors[2]; /* READs and WRITEs */ 99 unsigned ios[2], sectors[2]; /* READs and WRITEs */
90 int policy, partno; 100 int policy, partno;
@@ -117,15 +127,14 @@ struct gendisk {
117 * disks that can't be partitioned. */ 127 * disks that can't be partitioned. */
118 char disk_name[32]; /* name of major driver */ 128 char disk_name[32]; /* name of major driver */
119 struct hd_struct **part; /* [indexed by minor] */ 129 struct hd_struct **part; /* [indexed by minor] */
120 int part_uevent_suppress;
121 struct block_device_operations *fops; 130 struct block_device_operations *fops;
122 struct request_queue *queue; 131 struct request_queue *queue;
123 void *private_data; 132 void *private_data;
124 sector_t capacity; 133 sector_t capacity;
125 134
126 int flags; 135 int flags;
127 struct device *driverfs_dev; 136 struct device *driverfs_dev; // FIXME: remove
128 struct kobject kobj; 137 struct device dev;
129 struct kobject *holder_dir; 138 struct kobject *holder_dir;
130 struct kobject *slave_dir; 139 struct kobject *slave_dir;
131 140
@@ -143,13 +152,6 @@ struct gendisk {
143 struct work_struct async_notify; 152 struct work_struct async_notify;
144}; 153};
145 154
146/* Structure for sysfs attributes on block devices */
147struct disk_attribute {
148 struct attribute attr;
149 ssize_t (*show)(struct gendisk *, char *);
150 ssize_t (*store)(struct gendisk *, const char *, size_t);
151};
152
153/* 155/*
154 * Macros to operate on percpu disk statistics: 156 * Macros to operate on percpu disk statistics:
155 * 157 *
@@ -411,7 +413,8 @@ struct unixware_disklabel {
411#define ADDPART_FLAG_RAID 1 413#define ADDPART_FLAG_RAID 1
412#define ADDPART_FLAG_WHOLEDISK 2 414#define ADDPART_FLAG_WHOLEDISK 2
413 415
414char *disk_name (struct gendisk *hd, int part, char *buf); 416extern dev_t blk_lookup_devt(const char *name);
417extern char *disk_name (struct gendisk *hd, int part, char *buf);
415 418
416extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); 419extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev);
417extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); 420extern void add_partition(struct gendisk *, int, sector_t, sector_t, int);
@@ -423,12 +426,12 @@ extern struct gendisk *alloc_disk(int minors);
423extern struct kobject *get_disk(struct gendisk *disk); 426extern struct kobject *get_disk(struct gendisk *disk);
424extern void put_disk(struct gendisk *disk); 427extern void put_disk(struct gendisk *disk);
425extern void genhd_media_change_notify(struct gendisk *disk); 428extern void genhd_media_change_notify(struct gendisk *disk);
426extern void blk_register_region(dev_t dev, unsigned long range, 429extern void blk_register_region(dev_t devt, unsigned long range,
427 struct module *module, 430 struct module *module,
428 struct kobject *(*probe)(dev_t, int *, void *), 431 struct kobject *(*probe)(dev_t, int *, void *),
429 int (*lock)(dev_t, void *), 432 int (*lock)(dev_t, void *),
430 void *data); 433 void *data);
431extern void blk_unregister_region(dev_t dev, unsigned long range); 434extern void blk_unregister_region(dev_t devt, unsigned long range);
432 435
433static inline struct block_device *bdget_disk(struct gendisk *disk, int index) 436static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
434{ 437{
@@ -441,6 +444,12 @@ static inline struct block_device *bdget_disk(struct gendisk *disk, int index)
441 444
442static inline void printk_all_partitions(void) { } 445static inline void printk_all_partitions(void) { }
443 446
447static inline dev_t blk_lookup_devt(const char *name)
448{
449 dev_t devt = MKDEV(0, 0);
450 return devt;
451}
452
444#endif /* CONFIG_BLOCK */ 453#endif /* CONFIG_BLOCK */
445 454
446#endif 455#endif
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 4efa1e5385e3..2ae5b8462399 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -55,69 +55,6 @@ static int __init readwrite(char *str)
55__setup("ro", readonly); 55__setup("ro", readonly);
56__setup("rw", readwrite); 56__setup("rw", readwrite);
57 57
58static dev_t try_name(char *name, int part)
59{
60 char path[64];
61 char buf[32];
62 int range;
63 dev_t res;
64 char *s;
65 int len;
66 int fd;
67 unsigned int maj, min;
68
69 /* read device number from .../dev */
70
71 sprintf(path, "/sys/block/%s/dev", name);
72 fd = sys_open(path, 0, 0);
73 if (fd < 0)
74 goto fail;
75 len = sys_read(fd, buf, 32);
76 sys_close(fd);
77 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
78 goto fail;
79 buf[len - 1] = '\0';
80 if (sscanf(buf, "%u:%u", &maj, &min) == 2) {
81 /*
82 * Try the %u:%u format -- see print_dev_t()
83 */
84 res = MKDEV(maj, min);
85 if (maj != MAJOR(res) || min != MINOR(res))
86 goto fail;
87 } else {
88 /*
89 * Nope. Try old-style "0321"
90 */
91 res = new_decode_dev(simple_strtoul(buf, &s, 16));
92 if (*s)
93 goto fail;
94 }
95
96 /* if it's there and we are not looking for a partition - that's it */
97 if (!part)
98 return res;
99
100 /* otherwise read range from .../range */
101 sprintf(path, "/sys/block/%s/range", name);
102 fd = sys_open(path, 0, 0);
103 if (fd < 0)
104 goto fail;
105 len = sys_read(fd, buf, 32);
106 sys_close(fd);
107 if (len <= 0 || len == 32 || buf[len - 1] != '\n')
108 goto fail;
109 buf[len - 1] = '\0';
110 range = simple_strtoul(buf, &s, 10);
111 if (*s)
112 goto fail;
113
114 /* if partition is within range - we got it */
115 if (part < range)
116 return res + part;
117fail:
118 return 0;
119}
120
121/* 58/*
122 * Convert a name into device number. We accept the following variants: 59 * Convert a name into device number. We accept the following variants:
123 * 60 *
@@ -129,12 +66,10 @@ fail:
129 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is 66 * 5) /dev/<disk_name>p<decimal> - same as the above, that form is
130 * used when disk name of partitioned disk ends on a digit. 67 * used when disk name of partitioned disk ends on a digit.
131 * 68 *
132 * If name doesn't have fall into the categories above, we return 0. 69 * If name doesn't have fall into the categories above, we return (0,0).
133 * Sysfs is used to check if something is a disk name - it has 70 * block_class is used to check if something is a disk name. If the disk
134 * all known disks under bus/block/devices. If the disk name 71 * name contains slashes, the device name has them replaced with
135 * contains slashes, name of sysfs node has them replaced with 72 * bangs.
136 * bangs. try_name() does the actual checks, assuming that sysfs
137 * is mounted on rootfs /sys.
138 */ 73 */
139 74
140dev_t name_to_dev_t(char *name) 75dev_t name_to_dev_t(char *name)
@@ -142,13 +77,6 @@ dev_t name_to_dev_t(char *name)
142 char s[32]; 77 char s[32];
143 char *p; 78 char *p;
144 dev_t res = 0; 79 dev_t res = 0;
145 int part;
146
147#ifdef CONFIG_SYSFS
148 int mkdir_err = sys_mkdir("/sys", 0700);
149 if (sys_mount("sysfs", "/sys", "sysfs", 0, NULL) < 0)
150 goto out;
151#endif
152 80
153 if (strncmp(name, "/dev/", 5) != 0) { 81 if (strncmp(name, "/dev/", 5) != 0) {
154 unsigned maj, min; 82 unsigned maj, min;
@@ -164,6 +92,7 @@ dev_t name_to_dev_t(char *name)
164 } 92 }
165 goto done; 93 goto done;
166 } 94 }
95
167 name += 5; 96 name += 5;
168 res = Root_NFS; 97 res = Root_NFS;
169 if (strcmp(name, "nfs") == 0) 98 if (strcmp(name, "nfs") == 0)
@@ -178,35 +107,14 @@ dev_t name_to_dev_t(char *name)
178 for (p = s; *p; p++) 107 for (p = s; *p; p++)
179 if (*p == '/') 108 if (*p == '/')
180 *p = '!'; 109 *p = '!';
181 res = try_name(s, 0); 110 res = blk_lookup_devt(s);
182 if (res) 111 if (res)
183 goto done; 112 goto done;
184 113
185 while (p > s && isdigit(p[-1])) 114fail:
186 p--; 115 return 0;
187 if (p == s || !*p || *p == '0')
188 goto fail;
189 part = simple_strtoul(p, NULL, 10);
190 *p = '\0';
191 res = try_name(s, part);
192 if (res)
193 goto done;
194
195 if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p')
196 goto fail;
197 p[-1] = '\0';
198 res = try_name(s, part);
199done: 116done:
200#ifdef CONFIG_SYSFS
201 sys_umount("/sys", 0);
202out:
203 if (!mkdir_err)
204 sys_rmdir("/sys");
205#endif
206 return res; 117 return res;
207fail:
208 res = 0;
209 goto done;
210} 118}
211 119
212static int __init root_dev_setup(char *line) 120static int __init root_dev_setup(char *line)