aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJens Axboe <jaxboe@fusionio.com>2011-01-13 08:47:54 -0500
committerJens Axboe <jaxboe@fusionio.com>2011-01-13 08:47:54 -0500
commit81c5e2ae33c4b19e53966b427e33646bf6811830 (patch)
treea602a6dd100165c8948bfa713e6f0b422dcba5d8 /fs
parent797a455d2c682476c3797dbfecf5bf84c1e3b9d3 (diff)
parentfcc57045d53edc35bcce456e60ac4aa802712934 (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.c41
-rw-r--r--fs/partitions/check.c89
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}
1364EXPORT_SYMBOL(blkdev_put); 1391EXPORT_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(). */
526void 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
572exit:
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
584static bool disk_unlock_native_capacity(struct gendisk *disk) 525static 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
745EXPORT_SYMBOL(read_dev_sector); 686EXPORT_SYMBOL(read_dev_sector);
746
747void 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}