diff options
author | Kay Sievers <kay.sievers@vrfy.org> | 2007-05-21 16:08:01 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2008-01-24 23:40:36 -0500 |
commit | edfaa7c36574f1bf09c65ad602412db9da5f96bf (patch) | |
tree | d591b80ff9229e4845e41d68e2f4c5aadb017027 | |
parent | 09f82ea92822a7bbb7e816508abbda47ed54a77f (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.c | 416 | ||||
-rw-r--r-- | block/ll_rw_blk.c | 4 | ||||
-rw-r--r-- | drivers/base/class.c | 7 | ||||
-rw-r--r-- | drivers/base/core.c | 20 | ||||
-rw-r--r-- | drivers/block/aoe/aoeblk.c | 51 | ||||
-rw-r--r-- | drivers/block/nbd.c | 15 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 2 | ||||
-rw-r--r-- | drivers/md/dm.c | 4 | ||||
-rw-r--r-- | drivers/md/md.c | 8 | ||||
-rw-r--r-- | fs/block_dev.c | 8 | ||||
-rw-r--r-- | fs/partitions/check.c | 315 | ||||
-rw-r--r-- | include/linux/genhd.h | 37 | ||||
-rw-r--r-- | init/do_mounts.c | 108 |
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 | ||
20 | struct kset *block_kset; | 20 | static DEFINE_MUTEX(block_class_lock); |
21 | static struct kset_uevent_ops block_uevent_ops; | 21 | #ifndef CONFIG_SYSFS_DEPRECATED |
22 | static DEFINE_MUTEX(block_subsys_lock); | 22 | struct 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 | |||
42 | void blkdev_show(struct seq_file *f, off_t offset) | 42 | void 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 | ||
56 | int register_blkdev(unsigned int major, const char *name) | 55 | int 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 | } |
105 | out: | 104 | out: |
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 | */ |
141 | void blk_register_region(dev_t dev, unsigned long range, struct module *module, | 140 | void 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 | ||
148 | EXPORT_SYMBOL(blk_register_region); | 147 | EXPORT_SYMBOL(blk_register_region); |
149 | 148 | ||
150 | void blk_unregister_region(dev_t dev, unsigned long range) | 149 | void 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 | ||
155 | EXPORT_SYMBOL(blk_unregister_region); | 154 | EXPORT_SYMBOL(blk_unregister_region); |
156 | 155 | ||
157 | static struct kobject *exact_match(dev_t dev, int *part, void *data) | 156 | static 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 | ||
163 | static int exact_lock(dev_t dev, void *data) | 163 | static 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 | */ |
207 | struct gendisk *get_gendisk(dev_t dev, int *part) | 205 | struct 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 | */ |
218 | void __init printk_all_partitions(void) | 218 | void __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 */ |
268 | static void *part_start(struct seq_file *part, loff_t *pos) | 271 | static 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 | ||
280 | static void *part_next(struct seq_file *part, void *v, loff_t *pos) | 286 | static 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 | ||
288 | static void part_stop(struct seq_file *part, void *v) | 300 | static 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 | ||
293 | static int show_partition(struct seq_file *part, void *v) | 305 | static 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 | ||
328 | struct seq_operations partitions_op = { | 340 | struct 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 | ||
337 | extern int blk_dev_init(void); | 349 | extern int blk_dev_init(void); |
338 | 350 | ||
339 | static struct kobject *base_probe(dev_t dev, int *part, void *data) | 351 | static 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 | ||
347 | static int __init genhd_device_init(void) | 359 | static 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 | ||
359 | subsys_initcall(genhd_device_init); | 372 | subsys_initcall(genhd_device_init); |
360 | 373 | ||
361 | 374 | static 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 | */ | ||
366 | static 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 | ||
379 | static ssize_t disk_attr_store(struct kobject * kobj, struct attribute * attr, | 382 | static 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 | ||
392 | static struct sysfs_ops disk_sysfs_ops = { | 391 | static 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 | |||
397 | static 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 | } | ||
403 | static 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 | } | ||
408 | static ssize_t disk_range_read(struct gendisk * disk, char *page) | ||
409 | { | ||
410 | return sprintf(page, "%d\n", disk->minors); | ||
411 | } | ||
412 | static 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 | } |
418 | static ssize_t disk_size_read(struct gendisk * disk, char *page) | 398 | |
419 | { | 399 | static 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 | } | ||
422 | static 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 | } |
426 | static ssize_t disk_stats_read(struct gendisk * disk, char *page) | 406 | |
407 | static 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 | } |
448 | static struct disk_attribute disk_attr_uevent = { | ||
449 | .attr = {.name = "uevent", .mode = S_IWUSR }, | ||
450 | .store = disk_uevent_store | ||
451 | }; | ||
452 | static struct disk_attribute disk_attr_dev = { | ||
453 | .attr = {.name = "dev", .mode = S_IRUGO }, | ||
454 | .show = disk_dev_read | ||
455 | }; | ||
456 | static struct disk_attribute disk_attr_range = { | ||
457 | .attr = {.name = "range", .mode = S_IRUGO }, | ||
458 | .show = disk_range_read | ||
459 | }; | ||
460 | static struct disk_attribute disk_attr_removable = { | ||
461 | .attr = {.name = "removable", .mode = S_IRUGO }, | ||
462 | .show = disk_removable_read | ||
463 | }; | ||
464 | static struct disk_attribute disk_attr_size = { | ||
465 | .attr = {.name = "size", .mode = S_IRUGO }, | ||
466 | .show = disk_size_read | ||
467 | }; | ||
468 | static struct disk_attribute disk_attr_capability = { | ||
469 | .attr = {.name = "capability", .mode = S_IRUGO }, | ||
470 | .show = disk_capability_read | ||
471 | }; | ||
472 | static 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 |
434 | static 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 | ||
479 | static ssize_t disk_fail_store(struct gendisk * disk, | 442 | static 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 | } |
493 | static 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 | } | ||
497 | static 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 | ||
505 | static struct attribute * default_attrs[] = { | 461 | static DEVICE_ATTR(range, S_IRUGO, disk_range_show, NULL); |
506 | &disk_attr_uevent.attr, | 462 | static DEVICE_ATTR(removable, S_IRUGO, disk_removable_show, NULL); |
507 | &disk_attr_dev.attr, | 463 | static DEVICE_ATTR(size, S_IRUGO, disk_size_show, NULL); |
508 | &disk_attr_range.attr, | 464 | static DEVICE_ATTR(capability, S_IRUGO, disk_capability_show, NULL); |
509 | &disk_attr_removable.attr, | 465 | static 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, | 467 | static 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 | |
471 | static 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 | |||
483 | static struct attribute_group disk_attr_group = { | ||
484 | .attrs = disk_attrs, | ||
485 | }; | ||
486 | |||
487 | static struct attribute_group *disk_attr_groups[] = { | ||
488 | &disk_attr_group, | ||
489 | NULL | ||
517 | }; | 490 | }; |
518 | 491 | ||
519 | static void disk_release(struct kobject * kobj) | 492 | static 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 | 501 | struct class block_class = { | |
528 | static 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 | ||
534 | extern struct kobj_type ktype_part; | 505 | struct device_type disk_type = { |
535 | 506 | .name = "disk", | |
536 | static 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 | |||
543 | static 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 | |||
582 | static 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 */ | ||
598 | static void *diskstats_start(struct seq_file *part, loff_t *pos) | 519 | static 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 | ||
610 | static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) | 534 | static 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 | ||
618 | static void diskstats_stop(struct seq_file *part, void *v) | 549 | static 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 | ||
623 | static int diskstats_show(struct seq_file *s, void *v) | 554 | static 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 | } |
693 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); | 624 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); |
694 | 625 | ||
626 | dev_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 | |||
643 | EXPORT_SYMBOL(blk_lookup_devt); | ||
644 | |||
695 | struct gendisk *alloc_disk(int minors) | 645 | struct 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); | |||
756 | void put_disk(struct gendisk *disk) | 706 | void 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 | ||
762 | EXPORT_SYMBOL(put_disk); | 712 | EXPORT_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 | ||
709 | out_device: | 710 | out_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"); |
712 | out_busid: | 713 | out_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 | */ |
926 | void put_device(struct device * dev) | 929 | void 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 | ||
16 | static struct kmem_cache *buf_pool_cache; | 16 | static struct kmem_cache *buf_pool_cache; |
17 | 17 | ||
18 | static ssize_t aoedisk_show_state(struct gendisk * disk, char *page) | 18 | static 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 | } |
29 | static ssize_t aoedisk_show_mac(struct gendisk * disk, char *page) | 31 | static 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 | } |
36 | static ssize_t aoedisk_show_netif(struct gendisk * disk, char *page) | 40 | static 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 */ |
43 | static ssize_t aoedisk_show_fwver(struct gendisk * disk, char *page) | 49 | static 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 | ||
50 | static struct disk_attribute disk_attr_state = { | 58 | static DEVICE_ATTR(state, S_IRUGO, aoedisk_show_state, NULL); |
51 | .attr = {.name = "state", .mode = S_IRUGO }, | 59 | static DEVICE_ATTR(mac, S_IRUGO, aoedisk_show_mac, NULL); |
52 | .show = aoedisk_show_state | 60 | static DEVICE_ATTR(netif, S_IRUGO, aoedisk_show_netif, NULL); |
53 | }; | 61 | static struct device_attribute dev_attr_firmware_version = { |
54 | static 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 | }; | ||
58 | static struct disk_attribute disk_attr_netif = { | ||
59 | .attr = {.name = "netif", .mode = S_IRUGO }, | ||
60 | .show = aoedisk_show_netif | ||
61 | }; | ||
62 | static struct disk_attribute disk_attr_fwver = { | ||
63 | .attr = {.name = "firmware-version", .mode = S_IRUGO }, | ||
64 | .show = aoedisk_show_fwver | ||
65 | }; | 64 | }; |
66 | 65 | ||
67 | static struct attribute *aoe_attrs[] = { | 66 | static 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 | ||
75 | static const struct attribute_group attr_group = { | 74 | static const struct attribute_group attr_group = { |
@@ -79,12 +78,12 @@ static const struct attribute_group attr_group = { | |||
79 | static int | 78 | static int |
80 | aoedisk_add_sysfs(struct aoedev *d) | 79 | aoedisk_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 | } |
84 | void | 83 | void |
85 | aoedisk_rm_sysfs(struct aoedev *d) | 84 | aoedisk_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 | ||
90 | static int | 89 | static 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 | ||
378 | static ssize_t pid_show(struct gendisk *disk, char *page) | 378 | static 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 | ||
384 | static struct disk_attribute pid_attr = { | 387 | static 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 | ||
1179 | static int exact_lock(dev_t dev, void *data) | 1179 | static 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 | *---------------------------------------------------------------*/ |
1531 | void dm_kobject_uevent(struct mapped_device *md) | 1531 | void 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 | ||
1536 | uint32_t dm_next_uevent_seq(struct mapped_device *md) | 1536 | uint32_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); | |||
738 | static struct kobject *bdev_get_kobj(struct block_device *bdev) | 738 | static 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 | ||
746 | static struct kobject *bdev_get_holder(struct block_device *bdev) | 746 | static 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 | /* | 198 | static ssize_t part_start_show(struct device *dev, |
199 | * sysfs bindings for partitions | 199 | struct device_attribute *attr, char *buf) |
200 | */ | ||
201 | |||
202 | struct 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 | |||
208 | static ssize_t | ||
209 | part_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 | } | ||
218 | static ssize_t | ||
219 | part_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 | ||
231 | static struct sysfs_ops part_sysfs_ops = { | 206 | static 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 | |||
236 | static 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 | } |
242 | static ssize_t part_dev_read(struct hd_struct * p, char *page) | 212 | |
243 | { | 213 | static 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 | } | ||
248 | static 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 | } | ||
252 | static 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 | } | ||
256 | static 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 | } |
262 | static struct part_attribute part_attr_uevent = { | ||
263 | .attr = {.name = "uevent", .mode = S_IWUSR }, | ||
264 | .store = part_uevent_store | ||
265 | }; | ||
266 | static struct part_attribute part_attr_dev = { | ||
267 | .attr = {.name = "dev", .mode = S_IRUGO }, | ||
268 | .show = part_dev_read | ||
269 | }; | ||
270 | static struct part_attribute part_attr_start = { | ||
271 | .attr = {.name = "start", .mode = S_IRUGO }, | ||
272 | .show = part_start_read | ||
273 | }; | ||
274 | static struct part_attribute part_attr_size = { | ||
275 | .attr = {.name = "size", .mode = S_IRUGO }, | ||
276 | .show = part_size_read | ||
277 | }; | ||
278 | static 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 |
224 | static 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 | ||
285 | static ssize_t part_fail_store(struct hd_struct * p, | 229 | return sprintf(buf, "%d\n", p->make_it_fail); |
230 | } | ||
231 | |||
232 | static 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 | } |
295 | static 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 | } | ||
299 | static 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 | ||
246 | static DEVICE_ATTR(start, S_IRUGO, part_start_show, NULL); | ||
247 | static DEVICE_ATTR(size, S_IRUGO, part_size_show, NULL); | ||
248 | static DEVICE_ATTR(stat, S_IRUGO, part_stat_show, NULL); | ||
249 | #ifdef CONFIG_FAIL_MAKE_REQUEST | ||
250 | static 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 | ||
307 | static struct attribute * default_attrs[] = { | 254 | static 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 | ||
319 | extern struct kset *block_kset; | 264 | static struct attribute_group part_attr_group = { |
265 | .attrs = part_attrs, | ||
266 | }; | ||
320 | 267 | ||
321 | static void part_release(struct kobject *kobj) | 268 | static struct attribute_group *part_attr_groups[] = { |
269 | &part_attr_group, | ||
270 | NULL | ||
271 | }; | ||
272 | |||
273 | static 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 | ||
327 | struct kobj_type ktype_part = { | 279 | struct 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 | ||
333 | static inline void partition_sysfs_add_subdir(struct hd_struct *p) | 285 | static 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) | |||
352 | void delete_partition(struct gendisk *disk, int part) | 304 | void 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 | ||
371 | void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len, int flags) | 322 | void 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 | ||
409 | static 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 | |||
429 | static 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 | |||
460 | err_out_disk_name_lnk: | ||
461 | if (target) { | ||
462 | sysfs_remove_link(&target->kobj, disk_name); | ||
463 | err_out_dev_link: | ||
464 | sysfs_remove_link(&disk->kobj, "device"); | ||
465 | err_out_disk_name: | ||
466 | kfree(disk_name); | ||
467 | err_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 | ||
517 | exit: | 419 | exit: |
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 | |||
21 | extern struct device_type disk_type; | ||
22 | extern struct device_type part_type; | ||
23 | extern struct kobject *block_depr; | ||
24 | extern struct class block_class; | ||
25 | |||
16 | enum { | 26 | enum { |
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 { | |||
84 | struct hd_struct { | 94 | struct 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 */ | ||
147 | struct 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 | ||
414 | char *disk_name (struct gendisk *hd, int part, char *buf); | 416 | extern dev_t blk_lookup_devt(const char *name); |
417 | extern char *disk_name (struct gendisk *hd, int part, char *buf); | ||
415 | 418 | ||
416 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); | 419 | extern int rescan_partitions(struct gendisk *disk, struct block_device *bdev); |
417 | extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); | 420 | extern void add_partition(struct gendisk *, int, sector_t, sector_t, int); |
@@ -423,12 +426,12 @@ extern struct gendisk *alloc_disk(int minors); | |||
423 | extern struct kobject *get_disk(struct gendisk *disk); | 426 | extern struct kobject *get_disk(struct gendisk *disk); |
424 | extern void put_disk(struct gendisk *disk); | 427 | extern void put_disk(struct gendisk *disk); |
425 | extern void genhd_media_change_notify(struct gendisk *disk); | 428 | extern void genhd_media_change_notify(struct gendisk *disk); |
426 | extern void blk_register_region(dev_t dev, unsigned long range, | 429 | extern 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); |
431 | extern void blk_unregister_region(dev_t dev, unsigned long range); | 434 | extern void blk_unregister_region(dev_t devt, unsigned long range); |
432 | 435 | ||
433 | static inline struct block_device *bdget_disk(struct gendisk *disk, int index) | 436 | static 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 | ||
442 | static inline void printk_all_partitions(void) { } | 445 | static inline void printk_all_partitions(void) { } |
443 | 446 | ||
447 | static 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 | ||
58 | static 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; | ||
117 | fail: | ||
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 | ||
140 | dev_t name_to_dev_t(char *name) | 75 | dev_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])) | 114 | fail: |
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); | ||
199 | done: | 116 | done: |
200 | #ifdef CONFIG_SYSFS | ||
201 | sys_umount("/sys", 0); | ||
202 | out: | ||
203 | if (!mkdir_err) | ||
204 | sys_rmdir("/sys"); | ||
205 | #endif | ||
206 | return res; | 117 | return res; |
207 | fail: | ||
208 | res = 0; | ||
209 | goto done; | ||
210 | } | 118 | } |
211 | 119 | ||
212 | static int __init root_dev_setup(char *line) | 120 | static int __init root_dev_setup(char *line) |