diff options
| author | Andrew Morton <akpm@zip.com.au> | 2002-05-05 01:10:05 -0700 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-05-05 01:10:05 -0700 |
| commit | d028eab535bd8c1597391fd850f93501ff06f044 (patch) | |
| tree | 81b28667207a23421f81881948d71cfc85c96fef | |
| parent | 49c7cfe7dcd6c6a31b8ed3a82f6d947013b8cdf6 (diff) | |
[PATCH] Fix SMP race in truncate
Closes a small race window: testing PageWriteback() outside the page
lock introduces the possibility that page could be redirtied and have
writeback started after we've inspected PageWriteback.
| -rw-r--r-- | mm/filemap.c | 12 |
1 files changed, 6 insertions, 6 deletions
diff --git a/mm/filemap.c b/mm/filemap.c index c61488b41864..9c5002f1e2d5 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -201,18 +201,18 @@ static int truncate_list_pages(struct address_space *mapping, int failed; page_cache_get(page); - if (PageWriteback(page)) { - /* - * urgggh. This function is utterly foul, - * and this addition doesn't help. Kill. - */ + failed = TestSetPageLocked(page); + if (!failed && PageWriteback(page)) { + unlock_page(page); + list_del(head); + list_add_tail(head, curr); write_unlock(&mapping->page_lock); wait_on_page_writeback(page); + page_cache_release(page); unlocked = 1; write_lock(&mapping->page_lock); goto restart; } - failed = TestSetPageLocked(page); list_del(head); if (!failed) |
