-
Andrew Morton authored
In two cases (AIO-for-direct-IO and some CDROM DMA stuff which Jens did), we need to run set_page_dirty() in interrupt context. After DMA hardware has altered userspace pages for direct-IO reads. But mapping->page_lock, mapping->private_lock and inode_lock are not irq-safe. And really, we don't want to convert those locks just for this problem. So what we do is to dirty the pages *before* starting I/O. Then, in interrupt completion context, check to see that they are still dirty. If so then there is nothing to do. But if the pages were cleaned while the direct-IO is in progress we need to redirty them. The code uses schedule_work() for that. Of course, we could use schedule_work() for all BIOs and pages. The speculative dirty-before-starting-IO is just an optimisation. It's quite unlikely that any of the pages will be cleaned during the direct IO. This code is basically untestable under normal circumstances, because the relevant pages are pinned via get_user_pages(). This makes is_page_cache_freeable() evaluate false and the VM doesn't try to write them out anyway. But if the pages happen to be MAP_SHARED file pages, pdflush could clean them. The way I tested this code was to disable the call to bio_set_pages_dirty() in fs/direct-io.c.
511d2652