Take a look at __lock_page:
static void __lock_page(struct page *page)
{
struct task_struct *tsk = current;
DECLARE_WAITQUEUE(wait, tsk);
add_wait_queue_exclusive(&page->wait, &wait);
for (;;) {
sync_page(page);
set_task_state(tsk, TASK_UNINTERRUPTIBLE);
if (PageLocked(page)) {
run_task_queue(&tq_disk);
schedule();
continue;
}
if (!TryLockPage(page))
break;
}
tsk->state = TASK_RUNNING;
remove_wait_queue(&page->wait, &wait);
}
Af a process sleeps in __lock_page, sync_page() will be called even if the
page is already unlocked. (block_sync_page(), the sync_page routine for
generic block based filesystem calls run_task_queue(&tq_disk)).
I don't see any problem if we remove the run_task_queue(&tq_disk) and put
sync_page(page) there instead, removing the other sync_page(page) at the
beginning of the loop.
Comments?
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/