And here's a patch which triggers clearing check on close. It's on top of the following branch + the previous patch. git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git for-linus With the patch applied, eject triggers MEDIA_CHANGE if the drive had a media in it. Thanks. --- block/genhd.c | 22 ++++++++++++---------- fs/block_dev.c | 17 ++++++++--------- include/linux/genhd.h | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) Index: work/block/genhd.c =================================================================== --- work.orig/block/genhd.c +++ work/block/genhd.c @@ -1500,30 +1500,32 @@ void disk_unblock_events(struct gendisk } /** - * disk_check_events - schedule immediate event checking - * @disk: disk to check events for + * disk_flush_events - schedule immediate event checking and flushing + * @disk: disk to check and flush events for + * @mask: events to flush * - * Schedule immediate event checking on @disk if not blocked. + * Schedule immediate event checking on @disk if not blocked. Events in + * @mask are scheduled to be cleared from the driver. Note that this + * doesn't clear the events from @disk->ev. * * CONTEXT: - * Don't care. Safe to call from irq context. + * If @mask is non-zero must be called with bdev->bd_mutex held. */ -void disk_check_events(struct gendisk *disk) +void disk_flush_events(struct gendisk *disk, unsigned int mask) { struct disk_events *ev = disk->ev; - unsigned long flags; if (!ev) return; - spin_lock_irqsave(&ev->lock, flags); + spin_lock_irq(&ev->lock); + ev->clearing |= mask; if (!ev->block) { cancel_delayed_work(&ev->dwork); queue_delayed_work(system_nrt_wq, &ev->dwork, 0); } - spin_unlock_irqrestore(&ev->lock, flags); + spin_unlock_irq(&ev->lock); } -EXPORT_SYMBOL_GPL(disk_check_events); /** * disk_clear_events - synchronously check, clear and return pending events @@ -1713,7 +1715,7 @@ static int disk_events_set_dfl_poll_msec mutex_lock(&disk_events_mutex); list_for_each_entry(ev, &disk_events, node) - disk_check_events(ev->disk); + disk_flush_events(ev->disk, 0); mutex_unlock(&disk_events_mutex); Index: work/fs/block_dev.c =================================================================== --- work.orig/fs/block_dev.c +++ work/fs/block_dev.c @@ -1447,6 +1447,8 @@ static int __blkdev_put(struct block_dev int blkdev_put(struct block_device *bdev, fmode_t mode) { + mutex_lock(&bdev->bd_mutex); + if (mode & FMODE_EXCL) { bool bdev_free; @@ -1455,7 +1457,6 @@ int blkdev_put(struct block_device *bdev * are protected with bdev_lock. bd_mutex is to * synchronize disk_holder unlinking. */ - mutex_lock(&bdev->bd_mutex); spin_lock(&bdev_lock); WARN_ON_ONCE(--bdev->bd_holders < 0); @@ -1473,17 +1474,15 @@ int blkdev_put(struct block_device *bdev * If this was the last claim, remove holder link and * unblock evpoll if it was a write holder. */ - if (bdev_free) { - if (bdev->bd_write_holder) { - disk_unblock_events(bdev->bd_disk); - disk_check_events(bdev->bd_disk); - bdev->bd_write_holder = false; - } + if (bdev_free && bdev->bd_write_holder) { + disk_unblock_events(bdev->bd_disk); + bdev->bd_write_holder = false; } - - mutex_unlock(&bdev->bd_mutex); } + disk_flush_events(bdev->bd_disk, DISK_EVENT_MEDIA_CHANGE); + mutex_unlock(&bdev->bd_mutex); + return __blkdev_put(bdev, mode, 0); } EXPORT_SYMBOL(blkdev_put); Index: work/include/linux/genhd.h =================================================================== --- work.orig/include/linux/genhd.h +++ work/include/linux/genhd.h @@ -420,7 +420,7 @@ static inline int get_disk_ro(struct gen extern void disk_block_events(struct gendisk *disk); extern void disk_unblock_events(struct gendisk *disk); -extern void disk_check_events(struct gendisk *disk); +extern void disk_flush_events(struct gendisk *disk, unsigned int mask); extern unsigned int disk_clear_events(struct gendisk *disk, unsigned int mask); /* drivers/char/random.c */ -- To unsubscribe from this list: send the line "unsubscribe linux-hotplug" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html