Commit ea66b69c authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] fix invalidate_inode_pages2() race

Fix a buglet in invalidate_list_pages2(): there is a small window in
which writeback could start against the page before this function locks
it.

The patch closes the race by performing the PageWriteback test inside
PageLocked.

Testing PageWriteback inside PageLocked is "definitive" - when a page
is locked, writeback cannot start against it.
parent 8b00e4fa
...@@ -367,15 +367,17 @@ static int invalidate_list_pages2(struct address_space * mapping, ...@@ -367,15 +367,17 @@ static int invalidate_list_pages2(struct address_space * mapping,
while (curr != head) { while (curr != head) {
page = list_entry(curr, struct page, list); page = list_entry(curr, struct page, list);
if (!TestSetPageLocked(page)) {
int __unlocked;
if (PageWriteback(page)) { if (PageWriteback(page)) {
write_unlock(&mapping->page_lock); write_unlock(&mapping->page_lock);
wait_on_page_writeback(page); wait_on_page_writeback(page);
unlocked = 1; unlocked = 1;
write_lock(&mapping->page_lock); write_lock(&mapping->page_lock);
unlock_page(page);
goto restart; goto restart;
} }
if (!TestSetPageLocked(page)) {
int __unlocked;
__unlocked = invalidate_this_page2(mapping, page, curr, head); __unlocked = invalidate_this_page2(mapping, page, curr, head);
unlock_page(page); unlock_page(page);
......
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