Commit 2ab9665b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fix a writeback race

Fixes a bug in generic_writepages() and its cut-n-paste-cousin,
mpage_writepages().

The code was clearing PageDirty and then baling out if it discovered
the page was nder writeback.  Which would cause the dirty bit to be
lost.

It's a very small window, but reversing the order so PageDirty is only
cleared when we know for-sure that IO will be started fixes it up.
parent 193ae036
...@@ -515,8 +515,8 @@ mpage_writepages(struct address_space *mapping, ...@@ -515,8 +515,8 @@ mpage_writepages(struct address_space *mapping,
lock_page(page); lock_page(page);
if (page->mapping && TestClearPageDirty(page) && if (page->mapping && !PageWriteback(page) &&
!PageWriteback(page)) { TestClearPageDirty(page)) {
/* FIXME: batch this up */ /* FIXME: batch this up */
if (!PageActive(page) && PageLRU(page)) { if (!PageActive(page) && PageLRU(page)) {
spin_lock(&pagemap_lru_lock); spin_lock(&pagemap_lru_lock);
......
...@@ -383,8 +383,8 @@ int generic_writepages(struct address_space *mapping, int *nr_to_write) ...@@ -383,8 +383,8 @@ int generic_writepages(struct address_space *mapping, int *nr_to_write)
lock_page(page); lock_page(page);
/* It may have been removed from swapcache: check ->mapping */ /* It may have been removed from swapcache: check ->mapping */
if (page->mapping && TestClearPageDirty(page) && if (page->mapping && !PageWriteback(page) &&
!PageWriteback(page)) { TestClearPageDirty(page)) {
/* FIXME: batch this up */ /* FIXME: batch this up */
if (!PageActive(page) && PageLRU(page)) { if (!PageActive(page) && PageLRU(page)) {
spin_lock(&pagemap_lru_lock); spin_lock(&pagemap_lru_lock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment