diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:34:42 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-01-25 11:35:13 -0500 |
commit | df8dc74e8a383eaf2d9b44b80a71ec6f0e52b42e (patch) | |
tree | bc3799a43e8b94fa84b32e37b1c124d5e4868f50 /block | |
parent | 556a169dab38b5100df6f4a45b655dddd3db94c1 (diff) | |
parent | 4a3ad20ccd8f4d2a0535cf98fa83f7b561ba59a9 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6
This can be broken down into these major areas:
- Documentation updates (language translations and fixes, as
well as kobject and kset documenatation updates.)
- major kset/kobject/ktype rework and fixes. This cleans up the
kset and kobject and ktype relationship and architecture,
making sense of things now, and good documenation and samples
are provided for others to use. Also the attributes for
kobjects are much easier to handle now. This cleaned up a LOT
of code all through the kernel, making kobjects easier to use
if you want to.
- struct bus_type has been reworked to now handle the lifetime
rules properly, as the kobject is properly dynamic.
- struct driver has also been reworked, and now the lifetime
issues are resolved.
- the block subsystem has been converted to use struct device
now, and not "raw" kobjects. This patch has been in the -mm
tree for over a year now, and finally all the issues are
worked out with it. Older distros now properly work with new
kernels, and no userspace updates are needed at all.
- nozomi driver is added. This has also been in -mm for a long
time, and many people have asked for it to go in. It is now
in good enough shape to do so.
- lots of class_device conversions to use struct device instead.
The tree is almost all cleaned up now, only SCSI and IB is the
remaining code to fix up...
* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-2.6: (196 commits)
Driver core: coding style fixes
Kobject: fix coding style issues in kobject c files
Kobject: fix coding style issues in kobject.h
Driver core: fix coding style issues in device.h
spi: use class iteration api
scsi: use class iteration api
rtc: use class iteration api
power supply : use class iteration api
ieee1394: use class iteration api
Driver Core: add class iteration api
Driver core: Cleanup get_device_parent() in device_add() and device_move()
UIO: constify function pointer tables
Driver Core: constify the name passed to platform_device_register_simple
driver core: fix build with SYSFS=n
sysfs: make SYSFS_DEPRECATED depend on SYSFS
Driver core: use LIST_HEAD instead of call to INIT_LIST_HEAD in __init
kobject: add sample code for how to use ksets/ktypes/kobjects
kobject: add sample code for how to use kobjects in a simple manner.
kobject: update the kobject/kset documentation
kobject: remove old, outdated documentation.
...
Diffstat (limited to 'block')
-rw-r--r-- | block/elevator.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 8b919940b2ab..5ccec8aa964b 100644 --- a/block/ll_rw_blk.c +++ b/block/ll_rw_blk.c | |||
@@ -1862,9 +1862,7 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id) | |||
1862 | 1862 | ||
1863 | init_timer(&q->unplug_timer); | 1863 | init_timer(&q->unplug_timer); |
1864 | 1864 | ||
1865 | kobject_set_name(&q->kobj, "%s", "queue"); | 1865 | kobject_init(&q->kobj, &queue_ktype); |
1866 | q->kobj.ktype = &queue_ktype; | ||
1867 | kobject_init(&q->kobj); | ||
1868 | 1866 | ||
1869 | mutex_init(&q->sysfs_lock); | 1867 | mutex_init(&q->sysfs_lock); |
1870 | 1868 | ||
@@ -4182,9 +4180,8 @@ int blk_register_queue(struct gendisk *disk) | |||
4182 | if (!q || !q->request_fn) | 4180 | if (!q || !q->request_fn) |
4183 | return -ENXIO; | 4181 | return -ENXIO; |
4184 | 4182 | ||
4185 | q->kobj.parent = kobject_get(&disk->kobj); | 4183 | ret = kobject_add(&q->kobj, kobject_get(&disk->dev.kobj), |
4186 | 4184 | "%s", "queue"); | |
4187 | ret = kobject_add(&q->kobj); | ||
4188 | if (ret < 0) | 4185 | if (ret < 0) |
4189 | return ret; | 4186 | return ret; |
4190 | 4187 | ||
@@ -4209,6 +4206,6 @@ void blk_unregister_queue(struct gendisk *disk) | |||
4209 | 4206 | ||
4210 | kobject_uevent(&q->kobj, KOBJ_REMOVE); | 4207 | kobject_uevent(&q->kobj, KOBJ_REMOVE); |
4211 | kobject_del(&q->kobj); | 4208 | kobject_del(&q->kobj); |
4212 | kobject_put(&disk->kobj); | 4209 | kobject_put(&disk->dev.kobj); |
4213 | } | 4210 | } |
4214 | } | 4211 | } |