From e67156cef9f25ee73bb5f50b416990ea09aa3963 Mon Sep 17 00:00:00 2001 From: William Lee Irwin III Date: Sun, 1 May 2005 08:58:38 -0700 Subject: [PATCH] --- yaml --- r: 632 b: refs/heads/master c: dd1d5afca8d3bda7ff9db773fc08e648d2503dc6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/mm/filemap.c | 20 +++++++++++++++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/[refs] b/[refs] index a09e9e762500..fccccffcef43 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 93ea1d0a12623dc1a693642b5758261f35f9bf96 +refs/heads/master: dd1d5afca8d3bda7ff9db773fc08e648d2503dc6 diff --git a/trunk/mm/filemap.c b/trunk/mm/filemap.c index 9b74674e36ad..ee79b5d3439f 100644 --- a/trunk/mm/filemap.c +++ b/trunk/mm/filemap.c @@ -139,7 +139,25 @@ static int sync_page(void *word) page = container_of((page_flags_t *)word, struct page, flags); /* - * FIXME, fercrissake. What is this barrier here for? + * page_mapping() is being called without PG_locked held. + * Some knowledge of the state and use of the page is used to + * reduce the requirements down to a memory barrier. + * The danger here is of a stale page_mapping() return value + * indicating a struct address_space different from the one it's + * associated with when it is associated with one. + * After smp_mb(), it's either the correct page_mapping() for + * the page, or an old page_mapping() and the page's own + * page_mapping() has gone NULL. + * The ->sync_page() address_space operation must tolerate + * page_mapping() going NULL. By an amazing coincidence, + * this comes about because none of the users of the page + * in the ->sync_page() methods make essential use of the + * page_mapping(), merely passing the page down to the backing + * device's unplug functions when it's non-NULL, which in turn + * ignore it for all cases but swap, where only page->private is + * of interest. When page_mapping() does go NULL, the entire + * call stack gracefully ignores the page and returns. + * -- wli */ smp_mb(); mapping = page_mapping(page);