diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-07-28 18:07:55 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-07-28 18:07:55 -0400 |
commit | cb28a1bbdb4790378e7366d6c9ee1d2340b84f92 (patch) | |
tree | 316436f77dac75335fd2c3ef5f109e71606c50d3 /block | |
parent | b6d4f7e3ef25beb8c658c97867d98883e69dc544 (diff) | |
parent | f934fb19ef34730263e6afc01e8ec27a8a71470f (diff) |
Merge branch 'linus' into core/generic-dma-coherent
Conflicts:
arch/x86/Kconfig
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'block')
-rw-r--r-- | block/as-iosched.c | 3 | ||||
-rw-r--r-- | block/blk-map.c | 8 | ||||
-rw-r--r-- | block/bsg.c | 3 | ||||
-rw-r--r-- | block/genhd.c | 205 | ||||
-rw-r--r-- | block/ioctl.c | 5 |
5 files changed, 127 insertions, 97 deletions
diff --git a/block/as-iosched.c b/block/as-iosched.c index 9735acb5b4f5..cf4eb0eefbbf 100644 --- a/block/as-iosched.c +++ b/block/as-iosched.c | |||
@@ -837,8 +837,7 @@ static void as_completed_request(struct request_queue *q, struct request *rq) | |||
837 | WARN_ON(!list_empty(&rq->queuelist)); | 837 | WARN_ON(!list_empty(&rq->queuelist)); |
838 | 838 | ||
839 | if (RQ_STATE(rq) != AS_RQ_REMOVED) { | 839 | if (RQ_STATE(rq) != AS_RQ_REMOVED) { |
840 | printk("rq->state %d\n", RQ_STATE(rq)); | 840 | WARN(1, "rq->state %d\n", RQ_STATE(rq)); |
841 | WARN_ON(1); | ||
842 | goto out; | 841 | goto out; |
843 | } | 842 | } |
844 | 843 | ||
diff --git a/block/blk-map.c b/block/blk-map.c index ddd96fb11a7d..af37e4ae62f5 100644 --- a/block/blk-map.c +++ b/block/blk-map.c | |||
@@ -269,7 +269,6 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
269 | int reading = rq_data_dir(rq) == READ; | 269 | int reading = rq_data_dir(rq) == READ; |
270 | int do_copy = 0; | 270 | int do_copy = 0; |
271 | struct bio *bio; | 271 | struct bio *bio; |
272 | unsigned long stack_mask = ~(THREAD_SIZE - 1); | ||
273 | 272 | ||
274 | if (len > (q->max_hw_sectors << 9)) | 273 | if (len > (q->max_hw_sectors << 9)) |
275 | return -EINVAL; | 274 | return -EINVAL; |
@@ -278,11 +277,8 @@ int blk_rq_map_kern(struct request_queue *q, struct request *rq, void *kbuf, | |||
278 | 277 | ||
279 | kaddr = (unsigned long)kbuf; | 278 | kaddr = (unsigned long)kbuf; |
280 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; | 279 | alignment = queue_dma_alignment(q) | q->dma_pad_mask; |
281 | do_copy = ((kaddr & alignment) || (len & alignment)); | 280 | do_copy = ((kaddr & alignment) || (len & alignment) || |
282 | 281 | object_is_on_stack(kbuf)); | |
283 | if (!((kaddr & stack_mask) ^ | ||
284 | ((unsigned long)current->stack & stack_mask))) | ||
285 | do_copy = 1; | ||
286 | 282 | ||
287 | if (do_copy) | 283 | if (do_copy) |
288 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); | 284 | bio = bio_copy_kern(q, kbuf, len, gfp_mask, reading); |
diff --git a/block/bsg.c b/block/bsg.c index 5fb9b0bdbe85..5a68b09a69ba 100644 --- a/block/bsg.c +++ b/block/bsg.c | |||
@@ -1044,7 +1044,8 @@ int bsg_register_queue(struct request_queue *q, struct device *parent, | |||
1044 | bcd->release = release; | 1044 | bcd->release = release; |
1045 | kref_init(&bcd->ref); | 1045 | kref_init(&bcd->ref); |
1046 | dev = MKDEV(bsg_major, bcd->minor); | 1046 | dev = MKDEV(bsg_major, bcd->minor); |
1047 | class_dev = device_create(bsg_class, parent, dev, "%s", devname); | 1047 | class_dev = device_create_drvdata(bsg_class, parent, dev, NULL, |
1048 | "%s", devname); | ||
1048 | if (IS_ERR(class_dev)) { | 1049 | if (IS_ERR(class_dev)) { |
1049 | ret = PTR_ERR(class_dev); | 1050 | ret = PTR_ERR(class_dev); |
1050 | goto put_dev; | 1051 | goto put_dev; |
diff --git a/block/genhd.c b/block/genhd.c index 9074f384b097..c13cc77291af 100644 --- a/block/genhd.c +++ b/block/genhd.c | |||
@@ -183,6 +183,7 @@ static int exact_lock(dev_t devt, void *data) | |||
183 | void add_disk(struct gendisk *disk) | 183 | void add_disk(struct gendisk *disk) |
184 | { | 184 | { |
185 | struct backing_dev_info *bdi; | 185 | struct backing_dev_info *bdi; |
186 | int retval; | ||
186 | 187 | ||
187 | disk->flags |= GENHD_FL_UP; | 188 | disk->flags |= GENHD_FL_UP; |
188 | blk_register_region(MKDEV(disk->major, disk->first_minor), | 189 | blk_register_region(MKDEV(disk->major, disk->first_minor), |
@@ -193,7 +194,8 @@ void add_disk(struct gendisk *disk) | |||
193 | 194 | ||
194 | bdi = &disk->queue->backing_dev_info; | 195 | bdi = &disk->queue->backing_dev_info; |
195 | bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); | 196 | bdi_register_dev(bdi, MKDEV(disk->major, disk->first_minor)); |
196 | sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi"); | 197 | retval = sysfs_create_link(&disk->dev.kobj, &bdi->dev->kobj, "bdi"); |
198 | WARN_ON(retval); | ||
197 | } | 199 | } |
198 | 200 | ||
199 | EXPORT_SYMBOL(add_disk); | 201 | EXPORT_SYMBOL(add_disk); |
@@ -225,89 +227,111 @@ struct gendisk *get_gendisk(dev_t devt, int *part) | |||
225 | } | 227 | } |
226 | 228 | ||
227 | /* | 229 | /* |
228 | * print a full list of all partitions - intended for places where the root | 230 | * print a partitions - intended for places where the root filesystem can't be |
229 | * filesystem can't be mounted and thus to give the victim some idea of what | 231 | * mounted and thus to give the victim some idea of what went wrong |
230 | * went wrong | ||
231 | */ | 232 | */ |
232 | void __init printk_all_partitions(void) | 233 | static int printk_partition(struct device *dev, void *data) |
233 | { | 234 | { |
234 | struct device *dev; | ||
235 | struct gendisk *sgp; | 235 | struct gendisk *sgp; |
236 | char buf[BDEVNAME_SIZE]; | 236 | char buf[BDEVNAME_SIZE]; |
237 | int n; | 237 | int n; |
238 | 238 | ||
239 | mutex_lock(&block_class_lock); | 239 | if (dev->type != &disk_type) |
240 | /* For each block device... */ | 240 | goto exit; |
241 | list_for_each_entry(dev, &block_class.devices, node) { | ||
242 | if (dev->type != &disk_type) | ||
243 | continue; | ||
244 | sgp = dev_to_disk(dev); | ||
245 | /* | ||
246 | * Don't show empty devices or things that have been surpressed | ||
247 | */ | ||
248 | if (get_capacity(sgp) == 0 || | ||
249 | (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) | ||
250 | continue; | ||
251 | 241 | ||
252 | /* | 242 | sgp = dev_to_disk(dev); |
253 | * Note, unlike /proc/partitions, I am showing the numbers in | 243 | /* |
254 | * hex - the same format as the root= option takes. | 244 | * Don't show empty devices or things that have been surpressed |
255 | */ | 245 | */ |
256 | printk("%02x%02x %10llu %s", | 246 | if (get_capacity(sgp) == 0 || |
257 | sgp->major, sgp->first_minor, | 247 | (sgp->flags & GENHD_FL_SUPPRESS_PARTITION_INFO)) |
258 | (unsigned long long)get_capacity(sgp) >> 1, | 248 | goto exit; |
259 | disk_name(sgp, 0, buf)); | 249 | |
260 | if (sgp->driverfs_dev != NULL && | 250 | /* |
261 | sgp->driverfs_dev->driver != NULL) | 251 | * Note, unlike /proc/partitions, I am showing the numbers in |
262 | printk(" driver: %s\n", | 252 | * hex - the same format as the root= option takes. |
263 | sgp->driverfs_dev->driver->name); | 253 | */ |
264 | else | 254 | printk("%02x%02x %10llu %s", |
265 | printk(" (driver?)\n"); | 255 | sgp->major, sgp->first_minor, |
266 | 256 | (unsigned long long)get_capacity(sgp) >> 1, | |
267 | /* now show the partitions */ | 257 | disk_name(sgp, 0, buf)); |
268 | for (n = 0; n < sgp->minors - 1; ++n) { | 258 | if (sgp->driverfs_dev != NULL && |
269 | if (sgp->part[n] == NULL) | 259 | sgp->driverfs_dev->driver != NULL) |
270 | continue; | 260 | printk(" driver: %s\n", |
271 | if (sgp->part[n]->nr_sects == 0) | 261 | sgp->driverfs_dev->driver->name); |
272 | continue; | 262 | else |
273 | printk(" %02x%02x %10llu %s\n", | 263 | printk(" (driver?)\n"); |
274 | sgp->major, n + 1 + sgp->first_minor, | 264 | |
275 | (unsigned long long)sgp->part[n]->nr_sects >> 1, | 265 | /* now show the partitions */ |
276 | disk_name(sgp, n + 1, buf)); | 266 | for (n = 0; n < sgp->minors - 1; ++n) { |
277 | } | 267 | if (sgp->part[n] == NULL) |
268 | goto exit; | ||
269 | if (sgp->part[n]->nr_sects == 0) | ||
270 | goto exit; | ||
271 | printk(" %02x%02x %10llu %s\n", | ||
272 | sgp->major, n + 1 + sgp->first_minor, | ||
273 | (unsigned long long)sgp->part[n]->nr_sects >> 1, | ||
274 | disk_name(sgp, n + 1, buf)); | ||
278 | } | 275 | } |
276 | exit: | ||
277 | return 0; | ||
278 | } | ||
279 | 279 | ||
280 | /* | ||
281 | * print a full list of all partitions - intended for places where the root | ||
282 | * filesystem can't be mounted and thus to give the victim some idea of what | ||
283 | * went wrong | ||
284 | */ | ||
285 | void __init printk_all_partitions(void) | ||
286 | { | ||
287 | mutex_lock(&block_class_lock); | ||
288 | class_for_each_device(&block_class, NULL, NULL, printk_partition); | ||
280 | mutex_unlock(&block_class_lock); | 289 | mutex_unlock(&block_class_lock); |
281 | } | 290 | } |
282 | 291 | ||
283 | #ifdef CONFIG_PROC_FS | 292 | #ifdef CONFIG_PROC_FS |
284 | /* iterator */ | 293 | /* iterator */ |
294 | static int find_start(struct device *dev, void *data) | ||
295 | { | ||
296 | loff_t k = *(loff_t *)data; | ||
297 | |||
298 | if (dev->type != &disk_type) | ||
299 | return 0; | ||
300 | if (!k--) | ||
301 | return 1; | ||
302 | return 0; | ||
303 | } | ||
304 | |||
285 | static void *part_start(struct seq_file *part, loff_t *pos) | 305 | static void *part_start(struct seq_file *part, loff_t *pos) |
286 | { | 306 | { |
287 | loff_t k = *pos; | ||
288 | struct device *dev; | 307 | struct device *dev; |
308 | loff_t n = *pos; | ||
309 | |||
310 | if (!n) | ||
311 | seq_puts(part, "major minor #blocks name\n\n"); | ||
289 | 312 | ||
290 | mutex_lock(&block_class_lock); | 313 | mutex_lock(&block_class_lock); |
291 | list_for_each_entry(dev, &block_class.devices, node) { | 314 | dev = class_find_device(&block_class, NULL, (void *)pos, find_start); |
292 | if (dev->type != &disk_type) | 315 | if (dev) |
293 | continue; | 316 | return dev_to_disk(dev); |
294 | if (!k--) | ||
295 | return dev_to_disk(dev); | ||
296 | } | ||
297 | return NULL; | 317 | return NULL; |
298 | } | 318 | } |
299 | 319 | ||
320 | static int find_next(struct device *dev, void *data) | ||
321 | { | ||
322 | if (dev->type == &disk_type) | ||
323 | return 1; | ||
324 | return 0; | ||
325 | } | ||
326 | |||
300 | static void *part_next(struct seq_file *part, void *v, loff_t *pos) | 327 | static void *part_next(struct seq_file *part, void *v, loff_t *pos) |
301 | { | 328 | { |
302 | struct gendisk *gp = v; | 329 | struct gendisk *gp = v; |
303 | struct device *dev; | 330 | struct device *dev; |
304 | ++*pos; | 331 | ++*pos; |
305 | list_for_each_entry(dev, &gp->dev.node, node) { | 332 | dev = class_find_device(&block_class, &gp->dev, NULL, find_next); |
306 | if (&dev->node == &block_class.devices) | 333 | if (dev) |
307 | return NULL; | 334 | return dev_to_disk(dev); |
308 | if (dev->type == &disk_type) | ||
309 | return dev_to_disk(dev); | ||
310 | } | ||
311 | return NULL; | 335 | return NULL; |
312 | } | 336 | } |
313 | 337 | ||
@@ -322,9 +346,6 @@ static int show_partition(struct seq_file *part, void *v) | |||
322 | int n; | 346 | int n; |
323 | char buf[BDEVNAME_SIZE]; | 347 | char buf[BDEVNAME_SIZE]; |
324 | 348 | ||
325 | if (&sgp->dev.node == block_class.devices.next) | ||
326 | seq_puts(part, "major minor #blocks name\n\n"); | ||
327 | |||
328 | /* Don't show non-partitionable removeable devices or empty devices */ | 349 | /* Don't show non-partitionable removeable devices or empty devices */ |
329 | if (!get_capacity(sgp) || | 350 | if (!get_capacity(sgp) || |
330 | (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE))) | 351 | (sgp->minors == 1 && (sgp->flags & GENHD_FL_REMOVABLE))) |
@@ -370,7 +391,10 @@ static struct kobject *base_probe(dev_t devt, int *part, void *data) | |||
370 | 391 | ||
371 | static int __init genhd_device_init(void) | 392 | static int __init genhd_device_init(void) |
372 | { | 393 | { |
373 | int error = class_register(&block_class); | 394 | int error; |
395 | |||
396 | block_class.dev_kobj = sysfs_dev_block_kobj; | ||
397 | error = class_register(&block_class); | ||
374 | if (unlikely(error)) | 398 | if (unlikely(error)) |
375 | return error; | 399 | return error; |
376 | bdev_map = kobj_map_init(base_probe, &block_class_lock); | 400 | bdev_map = kobj_map_init(base_probe, &block_class_lock); |
@@ -532,6 +556,7 @@ static struct device_type disk_type = { | |||
532 | .release = disk_release, | 556 | .release = disk_release, |
533 | }; | 557 | }; |
534 | 558 | ||
559 | #ifdef CONFIG_PROC_FS | ||
535 | /* | 560 | /* |
536 | * aggregate disk stat collector. Uses the same stats that the sysfs | 561 | * aggregate disk stat collector. Uses the same stats that the sysfs |
537 | * entries do, above, but makes them available through one seq_file. | 562 | * entries do, above, but makes them available through one seq_file. |
@@ -542,16 +567,12 @@ static struct device_type disk_type = { | |||
542 | 567 | ||
543 | static void *diskstats_start(struct seq_file *part, loff_t *pos) | 568 | static void *diskstats_start(struct seq_file *part, loff_t *pos) |
544 | { | 569 | { |
545 | loff_t k = *pos; | ||
546 | struct device *dev; | 570 | struct device *dev; |
547 | 571 | ||
548 | mutex_lock(&block_class_lock); | 572 | mutex_lock(&block_class_lock); |
549 | list_for_each_entry(dev, &block_class.devices, node) { | 573 | dev = class_find_device(&block_class, NULL, (void *)pos, find_start); |
550 | if (dev->type != &disk_type) | 574 | if (dev) |
551 | continue; | 575 | return dev_to_disk(dev); |
552 | if (!k--) | ||
553 | return dev_to_disk(dev); | ||
554 | } | ||
555 | return NULL; | 576 | return NULL; |
556 | } | 577 | } |
557 | 578 | ||
@@ -561,12 +582,9 @@ static void *diskstats_next(struct seq_file *part, void *v, loff_t *pos) | |||
561 | struct device *dev; | 582 | struct device *dev; |
562 | 583 | ||
563 | ++*pos; | 584 | ++*pos; |
564 | list_for_each_entry(dev, &gp->dev.node, node) { | 585 | dev = class_find_device(&block_class, &gp->dev, NULL, find_next); |
565 | if (&dev->node == &block_class.devices) | 586 | if (dev) |
566 | return NULL; | 587 | return dev_to_disk(dev); |
567 | if (dev->type == &disk_type) | ||
568 | return dev_to_disk(dev); | ||
569 | } | ||
570 | return NULL; | 588 | return NULL; |
571 | } | 589 | } |
572 | 590 | ||
@@ -641,6 +659,7 @@ const struct seq_operations diskstats_op = { | |||
641 | .stop = diskstats_stop, | 659 | .stop = diskstats_stop, |
642 | .show = diskstats_show | 660 | .show = diskstats_show |
643 | }; | 661 | }; |
662 | #endif /* CONFIG_PROC_FS */ | ||
644 | 663 | ||
645 | static void media_change_notify_thread(struct work_struct *work) | 664 | static void media_change_notify_thread(struct work_struct *work) |
646 | { | 665 | { |
@@ -665,24 +684,38 @@ void genhd_media_change_notify(struct gendisk *disk) | |||
665 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); | 684 | EXPORT_SYMBOL_GPL(genhd_media_change_notify); |
666 | #endif /* 0 */ | 685 | #endif /* 0 */ |
667 | 686 | ||
687 | struct find_block { | ||
688 | const char *name; | ||
689 | int part; | ||
690 | }; | ||
691 | |||
692 | static int match_id(struct device *dev, void *data) | ||
693 | { | ||
694 | struct find_block *find = data; | ||
695 | |||
696 | if (dev->type != &disk_type) | ||
697 | return 0; | ||
698 | if (strcmp(dev->bus_id, find->name) == 0) { | ||
699 | struct gendisk *disk = dev_to_disk(dev); | ||
700 | if (find->part < disk->minors) | ||
701 | return 1; | ||
702 | } | ||
703 | return 0; | ||
704 | } | ||
705 | |||
668 | dev_t blk_lookup_devt(const char *name, int part) | 706 | dev_t blk_lookup_devt(const char *name, int part) |
669 | { | 707 | { |
670 | struct device *dev; | 708 | struct device *dev; |
671 | dev_t devt = MKDEV(0, 0); | 709 | dev_t devt = MKDEV(0, 0); |
710 | struct find_block find; | ||
672 | 711 | ||
673 | mutex_lock(&block_class_lock); | 712 | mutex_lock(&block_class_lock); |
674 | list_for_each_entry(dev, &block_class.devices, node) { | 713 | find.name = name; |
675 | if (dev->type != &disk_type) | 714 | find.part = part; |
676 | continue; | 715 | dev = class_find_device(&block_class, NULL, (void *)&find, match_id); |
677 | if (strcmp(dev->bus_id, name) == 0) { | 716 | if (dev) |
678 | struct gendisk *disk = dev_to_disk(dev); | 717 | devt = MKDEV(MAJOR(dev->devt), |
679 | 718 | MINOR(dev->devt) + part); | |
680 | if (part < disk->minors) | ||
681 | devt = MKDEV(MAJOR(dev->devt), | ||
682 | MINOR(dev->devt) + part); | ||
683 | break; | ||
684 | } | ||
685 | } | ||
686 | mutex_unlock(&block_class_lock); | 719 | mutex_unlock(&block_class_lock); |
687 | 720 | ||
688 | return devt; | 721 | return devt; |
diff --git a/block/ioctl.c b/block/ioctl.c index 52d6385216ad..77185e5c026a 100644 --- a/block/ioctl.c +++ b/block/ioctl.c | |||
@@ -17,6 +17,7 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user | |||
17 | long long start, length; | 17 | long long start, length; |
18 | int part; | 18 | int part; |
19 | int i; | 19 | int i; |
20 | int err; | ||
20 | 21 | ||
21 | if (!capable(CAP_SYS_ADMIN)) | 22 | if (!capable(CAP_SYS_ADMIN)) |
22 | return -EACCES; | 23 | return -EACCES; |
@@ -61,9 +62,9 @@ static int blkpg_ioctl(struct block_device *bdev, struct blkpg_ioctl_arg __user | |||
61 | } | 62 | } |
62 | } | 63 | } |
63 | /* all seems OK */ | 64 | /* all seems OK */ |
64 | add_partition(disk, part, start, length, ADDPART_FLAG_NONE); | 65 | err = add_partition(disk, part, start, length, ADDPART_FLAG_NONE); |
65 | mutex_unlock(&bdev->bd_mutex); | 66 | mutex_unlock(&bdev->bd_mutex); |
66 | return 0; | 67 | return err; |
67 | case BLKPG_DEL_PARTITION: | 68 | case BLKPG_DEL_PARTITION: |
68 | if (!disk->part[part-1]) | 69 | if (!disk->part[part-1]) |
69 | return -ENXIO; | 70 | return -ENXIO; |