]> git.hungrycats.org Git - linux/commitdiff
[PATCH] fix a page dirtying race in vmscan.c
authorAndrew Morton <akpm@digeo.com>
Sat, 21 Dec 2002 09:07:00 +0000 (01:07 -0800)
committerLinus Torvalds <torvalds@home.transmeta.com>
Sat, 21 Dec 2002 09:07:00 +0000 (01:07 -0800)
There's a small window in which another CPU could dirty the page after
we've cleaned it, and before we've moved it to mapping->dirty_pages().
The end result is a dirty page on mapping->locked_pages, which is
wrong.

So take mapping->page_lock before clearing the dirty bit.

mm/vmscan.c

index 7eabbdffa1ab9a6d5decdd88b99fa98d42d807c0..aeab1e3b48f0e5bd3d66228e721c1e44f454bf5e 100644 (file)
@@ -317,6 +317,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                        if (bdi != current->backing_dev_info &&
                                        bdi_write_congested(bdi))
                                goto keep_locked;
+                       write_lock(&mapping->page_lock);
                        if (test_clear_page_dirty(page)) {
                                int res;
                                struct writeback_control wbc = {
@@ -326,7 +327,6 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                                        .for_reclaim = 1,
                                };
 
-                               write_lock(&mapping->page_lock);
                                list_move(&page->list, &mapping->locked_pages);
                                write_unlock(&mapping->page_lock);
 
@@ -343,6 +343,7 @@ shrink_list(struct list_head *page_list, unsigned int gfp_mask,
                                }
                                goto keep;
                        }
+                       write_unlock(&mapping->page_lock);
                }
 
                /*