diff options
Diffstat (limited to 'block')
-rw-r--r-- | block/elevator.c | 8 | ||||
-rw-r--r-- | block/genhd.c | 419 | ||||
-rw-r--r-- | block/ll_rw_blk.c | 11 |
3 files changed, 190 insertions, 248 deletions
diff --git a/block/elevator.c b/block/elevator.c index e452deb80395..f9736fbdab03 100644 --- a/block/elevator.c +++ b/block/elevator.c | |||
@@ -185,9 +185,7 @@ static elevator_t *elevator_alloc(struct request_queue *q, | |||
185 | 185 | ||
186 | eq->ops = &e->ops; | 186 | eq->ops = &e->ops; |
187 | eq->elevator_type = e; | 187 | eq->elevator_type = e; |
188 | kobject_init(&eq->kobj); | 188 | kobject_init(&eq->kobj, &elv_ktype); |
189 | kobject_set_name(&eq->kobj, "%s", "iosched"); | ||
190 | eq->kobj.ktype = &elv_ktype; | ||
191 | mutex_init(&eq->sysfs_lock); | 189 | mutex_init(&eq->sysfs_lock); |
192 | 190 | ||
193 | eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, | 191 | eq->hash = kmalloc_node(sizeof(struct hlist_head) * ELV_HASH_ENTRIES, |
@@ -931,9 +929,7 @@ int elv_register_queue(struct request_queue *q) | |||
931 | elevator_t *e = q->elevator; | 929 | elevator_t *e = q->elevator; |
932 | int error; | 930 | int error; |
933 | 931 | ||
934 | e->kobj.parent = &q->kobj; | 932 | error = kobject_add(&e->kobj, &q->kobj, "%s", "iosched"); |
935 | |||
936 | error = kobject_add(&e->kobj); | ||
937 | if (!error) { | 933 | if (!error) { |
938 | struct elv_fs_entry *attr = e->elevator_type->elevator_attrs; | 934 | struct elv_fs_entry *attr = e->elevator_type->elevator_attrs; |
939 | if (attr) { | 935 | if (attr) { |
diff --git a/block/genhd.c b/block/genhd.c index f2ac914160d1..5e4ab4b37d9f 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -17,8 +17,10 @@ | |||
17 | #include <linux/buffer_head.h> | 17 | #include <linux/buffer_head.h> |
18 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
19 | 19 | ||
20 | struct kset block_subsys; | 20 | static DEFINE_MUTEX(block_class_lock); |
21 | static DEFINE_MUTEX(block_subsys_lock); | 21 | #ifndef CONFIG_SYSFS_DEPRECATED |
22 | struct kobject *block_depr; | ||
23 | #endif | ||
22 | 24 | ||
23 | /* | 25 | /* |
24 | * Can be deleted altogether. Later. | 26 | * Can be deleted altogether. Later. |
@@ -37,19 +39,17 @@ static inline int major_to_index(int major) | |||
37 | } | 39 | } |
38 | 40 | ||
39 | #ifdef CONFIG_PROC_FS | 41 | #ifdef CONFIG_PROC_FS |
40 | |||
41 | void blkdev_show(struct seq_file *f, off_t offset) | 42 | void blkdev_show(struct seq_file *f, off_t offset) |
42 | { | 43 | { |
43 | struct blk_major_name *dp; | 44 | struct blk_major_name *dp; |
44 | 45 | ||
45 | if (offset < BLKDEV_MAJOR_HASH_SIZE) { | 46 | if (offset < BLKDEV_MAJOR_HASH_SIZE) { |
46 | mutex_lock(&block_subsys_lock); | 47 | mutex_lock(&block_class_lock); |
47 | for (dp = major_names[offset]; dp; dp = dp->next) | 48 | for (dp = major_names[offset]; dp; dp = dp->next) |
48 | seq_printf(f, "%3d %s\n", dp->major, dp->name); | 49 | seq_printf(f, "%3d %s\n", dp->major, dp->name); |
49 | mutex_unlock(&block_subsys_lock); | 50 | mutex_unlock(&block_class_lock); |
50 | } | 51 | } |
51 | } | 52 | } |
52 | |||
53 | #endif /* CONFIG_PROC_FS */ | 53 | #endif /* CONFIG_PROC_FS */ |
54 | 54 | ||
55 | int register_blkdev(unsigned int major, const char *name) | 55 | int register_blkdev(unsigned int major, const char *name) |
@@ -57,7 +57,7 @@ int register_blkdev(unsigned int major, const char *name) | |||
57 | struct blk_major_name **n, *p; | 57 | struct blk_major_name **n, *p; |
58 | int index, ret = 0; | 58 | int index, ret = 0; |
59 | 59 | ||
60 | mutex_lock(&block_subsys_lock); | 60 | mutex_lock(&block_class_lock); |
61 | 61 | ||
62 | /* temporary */ | 62 | /* temporary */ |
63 | if (major == 0) { | 63 | if (major == 0) { |
@@ -102,7 +102,7 @@ int register_blkdev(unsigned int major, const char *name) | |||
102 | kfree(p); | 102 | kfree(p); |
103 | } | 103 | } |
104 | out: | 104 | out: |
105 | mutex_unlock(&block_subsys_lock); | 105 | mutex_unlock(&block_class_lock); |
106 | return ret; | 106 | return ret; |
107 | } | 107 | } |
108 | 108 | ||
@@ -114,7 +114,7 @@ void unregister_blkdev(unsigned int major, const char *name) | |||
114 | struct blk_major_name *p = NULL; | 114 | struct blk_major_name *p = NULL; |
115 | int index = major_to_index(major); | 115 | int index = major_to_index(major); |
116 | 116 | ||
117 | mutex_lock(&block_subsys_lock); | 117 | mutex_lock(&block_class_lock); |
118 | for (n = &major_names[index]; *n; n = &(*n)->next) | 118 | for (n = &major_names[index]; *n; n = &(*n)->next) |
119 | if ((*n)->major == major) | 119 | if ((*n)->major == major) |
120 | break; | 120 | break; |
@@ -124,7 +124,7 @@ void unregister_blkdev(unsigned int major, const char *name) | |||
124 | p = *n; | 124 | p = *n; |
125 | *n = p->next; | 125 | *n = p->next; |
126 | } | 126 | } |
127 | mutex_unlock(&block_subsys_lock); | 127 | mutex_unlock(&block_class_lock); |
128 | kfree(p); | 128 | kfree(p); |
129 | } | 129 | } |
130 | 130 | ||
@@ -137,29 +137,30 @@ static struct kobj_map *bdev_map; | |||
137 | * range must be nonzero | 137 | * range must be nonzero |
138 | * The hash chain is sorted on range, so that subranges can override. | 138 | * The hash chain is sorted on range, so that subranges can override. |
139 | */ | 139 | */ |
140 | 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, |
141 | struct kobject *(*probe)(dev_t, int *, void *), | 141 | struct kobject *(*probe)(dev_t, int *, void *), |
142 | int (*lock)(dev_t, void *), void *data) | 142 | int (*lock)(dev_t, void *), void *data) |
143 | { | 143 | { |
144 | kobj_map(bdev_map, dev, range, module, probe, lock, data); | 144 | kobj_map(bdev_map, devt, range, module, probe, lock, data); |
145 | } | 145 | } |
146 | 146 | ||
147 | EXPORT_SYMBOL(blk_register_region); | 147 | EXPORT_SYMBOL(blk_register_region); |
148 | 148 | ||
149 | void blk_unregister_region(dev_t dev, unsigned long range) | 149 | void blk_unregister_region(dev_t devt, unsigned long range) |
150 | { | 150 | { |
151 | kobj_unmap(bdev_map, dev, range); | 151 | kobj_unmap(bdev_map, devt, range); |
152 | } | 152 | } |
153 | 153 | ||
154 | EXPORT_SYMBOL(blk_unregister_region); | 154 | EXPORT_SYMBOL(blk_unregister_region); |
155 | 155 | ||
156 | 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) |
157 | { | 157 | { |
158 | struct gendisk *p = data; | 158 | struct gendisk *p = data; |
159 | return &p->kobj; | 159 | |
160 | return &p->dev.kobj; | ||
160 | } | 161 | } |
161 | 162 | ||
162 | static int exact_lock(dev_t dev, void *data) | 163 | static int exact_lock(dev_t devt, void *data) |
163 | { | 164 | { |
164 | struct gendisk *p = data; | 165 | struct gendisk *p = data; |
165 | 166 | ||
@@ -194,8 +195,6 @@ void unlink_gendisk(struct gendisk *disk) | |||
194 | disk->minors); | 195 | disk->minors); |
195 | } | 196 | } |
196 | 197 | ||
197 | #define to_disk(obj) container_of(obj,struct gendisk,kobj) | ||
198 | |||
199 | /** | 198 | /** |
200 | * get_gendisk - get partitioning information for a given device | 199 | * get_gendisk - get partitioning information for a given device |
201 | * @dev: device to get partitioning information for | 200 | * @dev: device to get partitioning information for |
@@ -203,10 +202,12 @@ void unlink_gendisk(struct gendisk *disk) | |||
203 | * This function gets the structure containing partitioning | 202 | * This function gets the structure containing partitioning |
204 | * information for the given device @dev. | 203 | * information for the given device @dev. |
205 | */ | 204 | */ |
206 | struct gendisk *get_gendisk(dev_t dev, int *part) | 205 | struct gendisk *get_gendisk(dev_t devt, int *part) |
207 | { | 206 | { |
208 | struct kobject *kobj = kobj_lookup(bdev_map, dev, part); | 207 | struct kobject *kobj = kobj_lookup(bdev_map, devt, part); |
209 | return kobj ? to_disk(kobj) : NULL; | 208 | struct device *dev = kobj_to_dev(kobj); |
209 | |||
210 | return kobj ? dev_to_disk(dev) : NULL; | ||
210 | } | 211 | } |
211 | 212 | ||
212 | /* | 213 | /* |
@@ -216,13 +217,17 @@ struct gendisk *get_gendisk(dev_t dev, int *part) | |||
216 | */ | 217 | */ |
217 | void __init printk_all_partitions(void) | 218 | void __init printk_all_partitions(void) |
218 | { | 219 | { |
219 | int n; | 220 | struct device *dev; |
220 | struct gendisk *sgp; | 221 | struct gendisk *sgp; |
222 | char buf[BDEVNAME_SIZE]; | ||
223 | int n; | ||
221 | 224 | ||
222 | mutex_lock(&block_subsys_lock); | 225 | mutex_lock(&block_class_lock); |
223 | /* For each block device... */ | 226 | /* For each block device... */ |
224 | list_for_each_entry(sgp, &block_subsys.list, kobj.entry) { | 227 | list_for_each_entry(dev, &block_class.devices, node) { |
225 | char buf[BDEVNAME_SIZE]; | 228 | if (dev->type != &disk_type) |
229 | continue; | ||
230 | sgp = dev_to_disk(dev); | ||
226 | /* | 231 | /* |
227 | * Don't show empty devices or things that have been surpressed | 232 | * Don't show empty devices or things that have been surpressed |
228 | */ | 233 | */ |
@@ -255,38 +260,46 @@ void __init printk_all_partitions(void) | |||
255 | sgp->major, n + 1 + sgp->first_minor, | 260 | sgp->major, n + 1 + sgp->first_minor, |
256 | (unsigned long long)sgp->part[n]->nr_sects >> 1, | 261 | (unsigned long long)sgp->part[n]->nr_sects >> 1, |
257 | disk_name(sgp, n + 1, buf)); | 262 | disk_name(sgp, n + 1, buf)); |
258 | } /* partition subloop */ | 263 | } |
259 | } /* Block device loop */ | 264 | } |
260 | 265 | ||
261 | mutex_unlock(&block_subsys_lock); | 266 | mutex_unlock(&block_class_lock); |
262 | return; | ||
263 | } | 267 | } |
264 | 268 | ||
265 | #ifdef CONFIG_PROC_FS | 269 | #ifdef CONFIG_PROC_FS |
266 | /* iterator */ | 270 | /* iterator */ |
267 | static void *part_start(struct seq_file *part, loff_t *pos) | 271 | static void *part_start(struct seq_file *part, loff_t *pos) |
268 | { | 272 | { |
269 | struct list_head *p; | 273 | loff_t k = *pos; |
270 | loff_t l = *pos; | 274 | struct device *dev; |
271 | 275 | ||
272 | mutex_lock(&block_subsys_lock); | 276 | mutex_lock(&block_class_lock); |
273 | list_for_each(p, &block_subsys.list) | 277 | list_for_each_entry(dev, &block_class.devices, node) { |
274 | if (!l--) | 278 | if (dev->type != &disk_type) |
275 | return list_entry(p, struct gendisk, kobj.entry); | 279 | continue; |
280 | if (!k--) | ||
281 | return dev_to_disk(dev); | ||
282 | } | ||
276 | return NULL; | 283 | return NULL; |
277 | } | 284 | } |
278 | 285 | ||
279 | 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) |
280 | { | 287 | { |
281 | struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; | 288 | struct gendisk *gp = v; |
289 | struct device *dev; | ||
282 | ++*pos; | 290 | ++*pos; |
283 | return p==&block_subsys.list ? NULL : | 291 | list_for_each_entry(dev, &gp->dev.node, node) { |
284 | list_entry(p, struct gendisk, kobj.entry); | 292 | if (&dev->node == &block_class.devices) |
293 | return NULL; | ||
294 | if (dev->type == &disk_type) | ||
295 | return dev_to_disk(dev); | ||
296 | } | ||
297 | return NULL; | ||
285 | } | 298 | } |
286 | 299 | ||
287 | static void part_stop(struct seq_file *part, void *v) | 300 | static void part_stop(struct seq_file *part, void *v) |
288 | { | 301 | { |
289 | mutex_unlock(&block_subsys_lock); | 302 | mutex_unlock(&block_class_lock); |
290 | } | 303 | } |
291 | 304 | ||
292 | static int show_partition(struct seq_file *part, void *v) | 305 | static int show_partition(struct seq_file *part, void *v) |
@@ -295,7 +308,7 @@ static int show_partition(struct seq_file *part, void *v) | |||
295 | int n; | 308 | int n; |
296 | char buf[BDEVNAME_SIZE]; | 309 | char buf[BDEVNAME_SIZE]; |
297 | 310 | ||
298 | if (&sgp->kobj.entry == block_subsys.list.next) | 311 | if (&sgp->dev.node == block_class.devices.next) |
299 | seq_puts(part, "major minor #blocks name\n\n"); | 312 | seq_puts(part, "major minor #blocks name\n\n"); |
300 | 313 | ||
301 | /* Don't show non-partitionable removeable devices or empty devices */ | 314 | /* Don't show non-partitionable removeable devices or empty devices */ |
@@ -325,110 +338,81 @@ static int show_partition(struct seq_file *part, void *v) | |||
325 | } | 338 | } |
326 | 339 | ||
327 | struct seq_operations partitions_op = { | 340 | struct seq_operations partitions_op = { |
328 | .start =part_start, | 341 | .start = part_start, |
329 | .next = part_next, | 342 | .next = part_next, |
330 | .stop = part_stop, | 343 | .stop = part_stop, |
331 | .show = show_partition | 344 | .show = show_partition |
332 | }; | 345 | }; |
333 | #endif | 346 | #endif |
334 | 347 | ||
335 | 348 | ||
336 | extern int blk_dev_init(void); | 349 | extern int blk_dev_init(void); |
337 | 350 | ||
338 | 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) |
339 | { | 352 | { |
340 | if (request_module("block-major-%d-%d", MAJOR(dev), MINOR(dev)) > 0) | 353 | if (request_module("block-major-%d-%d", MAJOR(devt), MINOR(devt)) > 0) |
341 | /* Make old-style 2.4 aliases work */ | 354 | /* Make old-style 2.4 aliases work */ |
342 | request_module("block-major-%d", MAJOR(dev)); | 355 | request_module("block-major-%d", MAJOR(devt)); |
343 | return NULL; | 356 | return NULL; |
344 | } | 357 | } |
345 | 358 | ||
346 | static int __init genhd_device_init(void) | 359 | static int __init genhd_device_init(void) |
347 | { | 360 | { |
348 | int err; | 361 | class_register(&block_class); |
349 | 362 | bdev_map = kobj_map_init(base_probe, &block_class_lock); | |
350 | bdev_map = kobj_map_init(base_probe, &block_subsys_lock); | ||
351 | blk_dev_init(); | 363 | blk_dev_init(); |
352 | err = subsystem_register(&block_subsys); | 364 | |
353 | if (err < 0) | 365 | #ifndef CONFIG_SYSFS_DEPRECATED |
354 | printk(KERN_WARNING "%s: subsystem_register error: %d\n", | 366 | /* create top-level block dir */ |
355 | __FUNCTION__, err); | 367 | block_depr = kobject_create_and_add("block", NULL); |
356 | return err; | 368 | #endif |
369 | return 0; | ||
357 | } | 370 | } |
358 | 371 | ||
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 | { | ||
400 | kobject_uevent(&disk->kobj, KOBJ_ADD); | ||
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 | { | 393 | { |
410 | return sprintf(page, "%d\n", disk->minors); | 394 | struct gendisk *disk = dev_to_disk(dev); |
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,136 +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, | 466 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
511 | &disk_attr_stat.attr, | 467 | static struct device_attribute dev_attr_fail = |
512 | &disk_attr_capability.attr, | 468 | __ATTR(make-it-fail, S_IRUGO|S_IWUSR, disk_fail_show, disk_fail_store); |
469 | #endif | ||
470 | |||
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, | ||
513 | #ifdef CONFIG_FAIL_MAKE_REQUEST | 477 | #ifdef CONFIG_FAIL_MAKE_REQUEST |
514 | &disk_attr_fail.attr, | 478 | &dev_attr_fail.attr, |
515 | #endif | 479 | #endif |
516 | NULL, | 480 | NULL |
481 | }; | ||
482 | |||
483 | static struct attribute_group disk_attr_group = { | ||
484 | .attrs = disk_attrs, | ||
517 | }; | 485 | }; |
518 | 486 | ||
519 | static void disk_release(struct kobject * kobj) | 487 | static struct attribute_group *disk_attr_groups[] = { |
488 | &disk_attr_group, | ||
489 | NULL | ||
490 | }; | ||
491 | |||
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 | decl_subsys(block, &ktype_block, &block_uevent_ops); | ||
588 | |||
589 | /* | 511 | /* |
590 | * aggregate disk stat collector. Uses the same stats that the sysfs | 512 | * aggregate disk stat collector. Uses the same stats that the sysfs |
591 | * entries do, above, but makes them available through one seq_file. | 513 | * entries do, above, but makes them available through one seq_file. |
592 | * Watching a few disks may be efficient through sysfs, but watching | ||
593 | * all of them will be more efficient through this interface. | ||
594 | * | 514 | * |
595 | * The output looks suspiciously like /proc/partitions with a bunch of | 515 | * The output looks suspiciously like /proc/partitions with a bunch of |
596 | * extra fields. | 516 | * extra fields. |
597 | */ | 517 | */ |
598 | 518 | ||
599 | /* iterator */ | ||
600 | static void *diskstats_start(struct seq_file *part, loff_t *pos) | 519 | static void *diskstats_start(struct seq_file *part, loff_t *pos) |
601 | { | 520 | { |
602 | loff_t k = *pos; | 521 | loff_t k = *pos; |
603 | struct list_head *p; | 522 | struct device *dev; |
604 | 523 | ||
605 | mutex_lock(&block_subsys_lock); | 524 | mutex_lock(&block_class_lock); |
606 | list_for_each(p, &block_subsys.list) | 525 | list_for_each_entry(dev, &block_class.devices, node) { |
526 | if (dev->type != &disk_type) | ||
527 | continue; | ||
607 | if (!k--) | 528 | if (!k--) |
608 | return list_entry(p, struct gendisk, kobj.entry); | 529 | return dev_to_disk(dev); |
530 | } | ||
609 | return NULL; | 531 | return NULL; |
610 | } | 532 | } |
611 | 533 | ||
612 | 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) |
613 | { | 535 | { |
614 | struct list_head *p = ((struct gendisk *)v)->kobj.entry.next; | 536 | struct gendisk *gp = v; |
537 | struct device *dev; | ||
538 | |||
615 | ++*pos; | 539 | ++*pos; |
616 | return p==&block_subsys.list ? NULL : | 540 | list_for_each_entry(dev, &gp->dev.node, node) { |
617 | list_entry(p, struct gendisk, kobj.entry); | 541 | if (&dev->node == &block_class.devices) |
542 | return NULL; | ||
543 | if (dev->type == &disk_type) | ||
544 | return dev_to_disk(dev); | ||
545 | } | ||
546 | return NULL; | ||
618 | } | 547 | } |
619 | 548 | ||
620 | static void diskstats_stop(struct seq_file *part, void *v) | 549 | static void diskstats_stop(struct seq_file *part, void *v) |
621 | { | 550 | { |
622 | mutex_unlock(&block_subsys_lock); | 551 | mutex_unlock(&block_class_lock); |
623 | } | 552 | } |
624 | 553 | ||
625 | static int diskstats_show(struct seq_file *s, void *v) | 554 | static int diskstats_show(struct seq_file *s, void *v) |
@@ -629,7 +558,7 @@ static int diskstats_show(struct seq_file *s, void *v) | |||
629 | int n = 0; | 558 | int n = 0; |
630 | 559 | ||
631 | /* | 560 | /* |
632 | if (&sgp->kobj.entry == block_subsys.kset.list.next) | 561 | if (&gp->dev.kobj.entry == block_class.devices.next) |
633 | seq_puts(s, "major minor name" | 562 | seq_puts(s, "major minor name" |
634 | " rio rmerge rsect ruse wio wmerge " | 563 | " rio rmerge rsect ruse wio wmerge " |
635 | "wsect wuse running use aveq" | 564 | "wsect wuse running use aveq" |
@@ -683,7 +612,7 @@ static void media_change_notify_thread(struct work_struct *work) | |||
683 | * set enviroment vars to indicate which event this is for | 612 | * set enviroment vars to indicate which event this is for |
684 | * so that user space will know to go check the media status. | 613 | * so that user space will know to go check the media status. |
685 | */ | 614 | */ |
686 | kobject_uevent_env(&gd->kobj, KOBJ_CHANGE, envp); | 615 | kobject_uevent_env(&gd->dev.kobj, KOBJ_CHANGE, envp); |
687 | put_device(gd->driverfs_dev); | 616 | put_device(gd->driverfs_dev); |
688 | } | 617 | } |
689 | 618 | ||
@@ -694,6 +623,25 @@ void genhd_media_change_notify(struct gendisk *disk) | |||
694 | } | 623 | } |
695 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); | 624 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); |
696 | 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 | |||
697 | struct gendisk *alloc_disk(int minors) | 645 | struct gendisk *alloc_disk(int minors) |
698 | { | 646 | { |
699 | return alloc_disk_node(minors, -1); | 647 | return alloc_disk_node(minors, -1); |
@@ -721,9 +669,10 @@ struct gendisk *alloc_disk_node(int minors, int node_id) | |||
721 | } | 669 | } |
722 | } | 670 | } |
723 | disk->minors = minors; | 671 | disk->minors = minors; |
724 | kobj_set_kset_s(disk,block_subsys); | ||
725 | kobject_init(&disk->kobj); | ||
726 | rand_initialize_disk(disk); | 672 | rand_initialize_disk(disk); |
673 | disk->dev.class = &block_class; | ||
674 | disk->dev.type = &disk_type; | ||
675 | device_initialize(&disk->dev); | ||
727 | INIT_WORK(&disk->async_notify, | 676 | INIT_WORK(&disk->async_notify, |
728 | media_change_notify_thread); | 677 | media_change_notify_thread); |
729 | } | 678 | } |
@@ -743,7 +692,7 @@ struct kobject *get_disk(struct gendisk *disk) | |||
743 | owner = disk->fops->owner; | 692 | owner = disk->fops->owner; |
744 | if (owner && !try_module_get(owner)) | 693 | if (owner && !try_module_get(owner)) |
745 | return NULL; | 694 | return NULL; |
746 | kobj = kobject_get(&disk->kobj); | 695 | kobj = kobject_get(&disk->dev.kobj); |
747 | if (kobj == NULL) { | 696 | if (kobj == NULL) { |
748 | module_put(owner); | 697 | module_put(owner); |
749 | return NULL; | 698 | return NULL; |
@@ -757,7 +706,7 @@ EXPORT_SYMBOL(get_disk); | |||
757 | void put_disk(struct gendisk *disk) | 706 | void put_disk(struct gendisk *disk) |
758 | { | 707 | { |
759 | if (disk) | 708 | if (disk) |
760 | kobject_put(&disk->kobj); | 709 | kobject_put(&disk->dev.kobj); |
761 | } | 710 | } |
762 | 711 | ||
763 | EXPORT_SYMBOL(put_disk); | 712 | EXPORT_SYMBOL(put_disk); |
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c index 14af36c5cdb2..3d0422f48453 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -1886,9 +1886,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) | |||
1886 | 1886 | ||
1887 | init_timer(&q->unplug_timer); | 1887 | init_timer(&q->unplug_timer); |
1888 | 1888 | ||
1889 | kobject_set_name(&q->kobj, "%s", "queue"); | 1889 | kobject_init(&q->kobj, &queue_ktype); |
1890 | q->kobj.ktype = &queue_ktype; | ||
1891 | kobject_init(&q->kobj); | ||
1892 | 1890 | ||
1893 | mutex_init(&q->sysfs_lock); | 1891 | mutex_init(&q->sysfs_lock); |
1894 | 1892 | ||
@@ -4206,9 +4204,8 @@ int blk_register_queue(struct gendisk *disk) | |||
4206 | if (!q || !q->request_fn) | 4204 | if (!q || !q->request_fn) |
4207 | return -ENXIO; | 4205 | return -ENXIO; |
4208 | 4206 | ||
4209 | q->kobj.parent = kobject_get(&disk->kobj); | 4207 | ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj), |
4210 | 4208 | "%s", "queue"); | |
4211 | ret = kobject_add(&q->kobj); | ||
4212 | if (ret < 0) | 4209 | if (ret < 0) |
4213 | return ret; | 4210 | return ret; |
4214 | 4211 | ||
@@ -4233,6 +4230,6 @@ void blk_unregister_queue(struct gendisk *disk) | |||
4233 | 4230 | ||
4234 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 4231 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
4235 | kobject_del(&q->kobj); | 4232 | kobject_del(&q->kobj); |
4236 | kobject_put(&disk->kobj); | 4233 | kobject_put(&disk->dev.kobj); |
4237 | } | 4234 | } |
4238 | } | 4235 | } |