--- linux-2.6.1-rc1-mm1/mm/filemap.c 2003-12-31 10:52:47.039988554 -0800 +++ linux-2.6.1-rc1-mm1.fdatawait/mm/filemap.c 2003-12-31 14:10:43.114197926 -0800 @@ -188,6 +188,32 @@ restart: struct page *page; page = list_entry(mapping->locked_pages.next,struct page,list); + /* + * If the page is locked, it might be in process of being + * setup for writeback but without PG_writeback set + * and with PG_dirty cleared. + * (PG_dirty is cleared BEFORE PG_writeback is set) + * So, wait for the PG_locked to clear, then start over. + */ + if (PageLocked(page)) { + page_cache_get(page); + spin_unlock(&mapping->page_lock); + wait_on_page_locked(page); + page_cache_release(page); + goto restart; + } + /* + * Wait for page writeback with it still on the locked list. + */ + if (PageWriteback(page)) { + page_cache_get(page); + spin_unlock(&mapping->page_lock); + wait_on_page_writeback(page); + if (PageError(page)) + ret = -EIO; + page_cache_release(page); + goto restart; + } list_del(&page->list); if (PageDirty(page)) list_add(&page->list, &mapping->dirty_pages);