diff options
author | Jens Axboe <jaxboe@fusionio.com> | 2011-01-13 08:47:54 -0500 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2011-01-13 08:47:54 -0500 |
commit | 81c5e2ae33c4b19e53966b427e33646bf6811830 (patch) | |
tree | a602a6dd100165c8948bfa713e6f0b422dcba5d8 /fs | |
parent | 797a455d2c682476c3797dbfecf5bf84c1e3b9d3 (diff) | |
parent | fcc57045d53edc35bcce456e60ac4aa802712934 (diff) |
Merge branch 'for-2.6.38/event-handling' into for-2.6.38/core
Diffstat (limited to 'fs')
-rw-r--r-- | fs/block_dev.c | 41 | ||||
-rw-r--r-- | fs/partitions/check.c | 89 |
2 files changed, 34 insertions, 96 deletions
diff --git a/fs/block_dev.c b/fs/block_dev.c index c1c1b8c3fb99..6017389711ee 100644 --- a/fs/block_dev.c +++ b/fs/block_dev.c | |||
@@ -948,10 +948,11 @@ int check_disk_change(struct block_device *bdev) | |||
948 | { | 948 | { |
949 | struct gendisk *disk = bdev->bd_disk; | 949 | struct gendisk *disk = bdev->bd_disk; |
950 | const struct block_device_operations *bdops = disk->fops; | 950 | const struct block_device_operations *bdops = disk->fops; |
951 | unsigned int events; | ||
951 | 952 | ||
952 | if (!bdops->media_changed) | 953 | events = disk_clear_events(disk, DISK_EVENT_MEDIA_CHANGE | |
953 | return 0; | 954 | DISK_EVENT_EJECT_REQUEST); |
954 | if (!bdops->media_changed(bdev->bd_disk)) | 955 | if (!(events & DISK_EVENT_MEDIA_CHANGE)) |
955 | return 0; | 956 | return 0; |
956 | 957 | ||
957 | flush_disk(bdev); | 958 | flush_disk(bdev); |
@@ -1158,9 +1159,10 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | |||
1158 | 1159 | ||
1159 | if (whole) { | 1160 | if (whole) { |
1160 | /* finish claiming */ | 1161 | /* finish claiming */ |
1162 | mutex_lock(&bdev->bd_mutex); | ||
1161 | spin_lock(&bdev_lock); | 1163 | spin_lock(&bdev_lock); |
1162 | 1164 | ||
1163 | if (res == 0) { | 1165 | if (!res) { |
1164 | BUG_ON(!bd_may_claim(bdev, whole, holder)); | 1166 | BUG_ON(!bd_may_claim(bdev, whole, holder)); |
1165 | /* | 1167 | /* |
1166 | * Note that for a whole device bd_holders | 1168 | * Note that for a whole device bd_holders |
@@ -1180,6 +1182,20 @@ int blkdev_get(struct block_device *bdev, fmode_t mode, void *holder) | |||
1180 | wake_up_bit(&whole->bd_claiming, 0); | 1182 | wake_up_bit(&whole->bd_claiming, 0); |
1181 | 1183 | ||
1182 | spin_unlock(&bdev_lock); | 1184 | spin_unlock(&bdev_lock); |
1185 | |||
1186 | /* | ||
1187 | * Block event polling for write claims. Any write | ||
1188 | * holder makes the write_holder state stick until all | ||
1189 | * are released. This is good enough and tracking | ||
1190 | * individual writeable reference is too fragile given | ||
1191 | * the way @mode is used in blkdev_get/put(). | ||
1192 | */ | ||
1193 | if (!res && (mode & FMODE_WRITE) && !bdev->bd_write_holder) { | ||
1194 | bdev->bd_write_holder = true; | ||
1195 | disk_block_events(bdev->bd_disk); | ||
1196 | } | ||
1197 | |||
1198 | mutex_unlock(&bdev->bd_mutex); | ||
1183 | bdput(whole); | 1199 | bdput(whole); |
1184 | } | 1200 | } |
1185 | 1201 | ||
@@ -1353,12 +1369,23 @@ int blkdev_put(struct block_device *bdev, fmode_t mode) | |||
1353 | 1369 | ||
1354 | spin_unlock(&bdev_lock); | 1370 | spin_unlock(&bdev_lock); |
1355 | 1371 | ||
1356 | /* if this was the last claim, holder link should go too */ | 1372 | /* |
1357 | if (bdev_free) | 1373 | * If this was the last claim, remove holder link and |
1374 | * unblock evpoll if it was a write holder. | ||
1375 | */ | ||
1376 | if (bdev_free) { | ||
1358 | bd_unlink_disk_holder(bdev); | 1377 | bd_unlink_disk_holder(bdev); |
1378 | if (bdev->bd_write_holder) { | ||
1379 | disk_unblock_events(bdev->bd_disk); | ||
1380 | bdev->bd_write_holder = false; | ||
1381 | } else | ||
1382 | disk_check_events(bdev->bd_disk); | ||
1383 | } | ||
1359 | 1384 | ||
1360 | mutex_unlock(&bdev->bd_mutex); | 1385 | mutex_unlock(&bdev->bd_mutex); |
1361 | } | 1386 | } else |
1387 | disk_check_events(bdev->bd_disk); | ||
1388 | |||
1362 | return __blkdev_put(bdev, mode, 0); | 1389 | return __blkdev_put(bdev, mode, 0); |
1363 | } | 1390 | } |
1364 | EXPORT_SYMBOL(blkdev_put); | 1391 | EXPORT_SYMBOL(blkdev_put); |
diff --git a/fs/partitions/check.c b/fs/partitions/check.c index 011520df71ae..9c21119512b9 100644 --- a/fs/partitions/check.c +++ b/fs/partitions/check.c | |||
@@ -522,65 +522,6 @@ out_put: | |||
522 | return ERR_PTR(err); | 522 | return ERR_PTR(err); |
523 | } | 523 | } |
524 | 524 | ||
525 | /* Not exported, helper to add_disk(). */ | ||
526 | void register_disk(struct gendisk *disk) | ||
527 | { | ||
528 | struct device *ddev = disk_to_dev(disk); | ||
529 | struct block_device *bdev; | ||
530 | struct disk_part_iter piter; | ||
531 | struct hd_struct *part; | ||
532 | int err; | ||
533 | |||
534 | ddev->parent = disk->driverfs_dev; | ||
535 | |||
536 | dev_set_name(ddev, disk->disk_name); | ||
537 | |||
538 | /* delay uevents, until we scanned partition table */ | ||
539 | dev_set_uevent_suppress(ddev, 1); | ||
540 | |||
541 | if (device_add(ddev)) | ||
542 | return; | ||
543 | if (!sysfs_deprecated) { | ||
544 | err = sysfs_create_link(block_depr, &ddev->kobj, | ||
545 | kobject_name(&ddev->kobj)); | ||
546 | if (err) { | ||
547 | device_del(ddev); | ||
548 | return; | ||
549 | } | ||
550 | } | ||
551 | disk->part0.holder_dir = kobject_create_and_add("holders", &ddev->kobj); | ||
552 | disk->slave_dir = kobject_create_and_add("slaves", &ddev->kobj); | ||
553 | |||
554 | /* No minors to use for partitions */ | ||
555 | if (!disk_partitionable(disk)) | ||
556 | goto exit; | ||
557 | |||
558 | /* No such device (e.g., media were just removed) */ | ||
559 | if (!get_capacity(disk)) | ||
560 | goto exit; | ||
561 | |||
562 | bdev = bdget_disk(disk, 0); | ||
563 | if (!bdev) | ||
564 | goto exit; | ||
565 | |||
566 | bdev->bd_invalidated = 1; | ||
567 | err = blkdev_get(bdev, FMODE_READ, NULL); | ||
568 | if (err < 0) | ||
569 | goto exit; | ||
570 | blkdev_put(bdev, FMODE_READ); | ||
571 | |||
572 | exit: | ||
573 | /* announce disk after possible partitions are created */ | ||
574 | dev_set_uevent_suppress(ddev, 0); | ||
575 | kobject_uevent(&ddev->kobj, KOBJ_ADD); | ||
576 | |||
577 | /* announce possible partitions */ | ||
578 | disk_part_iter_init(&piter, disk, 0); | ||
579 | while ((part = disk_part_iter_next(&piter))) | ||
580 | kobject_uevent(&part_to_dev(part)->kobj, KOBJ_ADD); | ||
581 | disk_part_iter_exit(&piter); | ||
582 | } | ||
583 | |||
584 | static bool disk_unlock_native_capacity(struct gendisk *disk) | 525 | static bool disk_unlock_native_capacity(struct gendisk *disk) |
585 | { | 526 | { |
586 | const struct block_device_operations *bdops = disk->fops; | 527 | const struct block_device_operations *bdops = disk->fops; |
@@ -743,33 +684,3 @@ fail: | |||
743 | } | 684 | } |
744 | 685 | ||
745 | EXPORT_SYMBOL(read_dev_sector); | 686 | EXPORT_SYMBOL(read_dev_sector); |
746 | |||
747 | void del_gendisk(struct gendisk *disk) | ||
748 | { | ||
749 | struct disk_part_iter piter; | ||
750 | struct hd_struct *part; | ||
751 | |||
752 | /* invalidate stuff */ | ||
753 | disk_part_iter_init(&piter, disk, | ||
754 | DISK_PITER_INCL_EMPTY | DISK_PITER_REVERSE); | ||
755 | while ((part = disk_part_iter_next(&piter))) { | ||
756 | invalidate_partition(disk, part->partno); | ||
757 | delete_partition(disk, part->partno); | ||
758 | } | ||
759 | disk_part_iter_exit(&piter); | ||
760 | |||
761 | invalidate_partition(disk, 0); | ||
762 | blk_free_devt(disk_to_dev(disk)->devt); | ||
763 | set_capacity(disk, 0); | ||
764 | disk->flags &= ~GENHD_FL_UP; | ||
765 | unlink_gendisk(disk); | ||
766 | part_stat_set_all(&disk->part0, 0); | ||
767 | disk->part0.stamp = 0; | ||
768 | |||
769 | kobject_put(disk->part0.holder_dir); | ||
770 | kobject_put(disk->slave_dir); | ||
771 | disk->driverfs_dev = NULL; | ||
772 | if (!sysfs_deprecated) | ||
773 | sysfs_remove_link(block_depr, dev_name(disk_to_dev(disk))); | ||
774 | device_del(disk_to_dev(disk)); | ||
775 | } | ||