diff options
| -rw-r--r-- | kernel/futex.c | 28 |
1 files changed, 20 insertions, 8 deletions
diff --git a/kernel/futex.c b/kernel/futex.c index ea87f4d2f455..1614be20173d 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
| @@ -314,17 +314,29 @@ again: | |||
| 314 | #endif | 314 | #endif |
| 315 | 315 | ||
| 316 | lock_page(page_head); | 316 | lock_page(page_head); |
| 317 | |||
| 318 | /* | ||
| 319 | * If page_head->mapping is NULL, then it cannot be a PageAnon | ||
| 320 | * page; but it might be the ZERO_PAGE or in the gate area or | ||
| 321 | * in a special mapping (all cases which we are happy to fail); | ||
| 322 | * or it may have been a good file page when get_user_pages_fast | ||
| 323 | * found it, but truncated or holepunched or subjected to | ||
| 324 | * invalidate_complete_page2 before we got the page lock (also | ||
| 325 | * cases which we are happy to fail). And we hold a reference, | ||
| 326 | * so refcount care in invalidate_complete_page's remove_mapping | ||
| 327 | * prevents drop_caches from setting mapping to NULL beneath us. | ||
| 328 | * | ||
| 329 | * The case we do have to guard against is when memory pressure made | ||
| 330 | * shmem_writepage move it from filecache to swapcache beneath us: | ||
| 331 | * an unlikely race, but we do need to retry for page_head->mapping. | ||
| 332 | */ | ||
| 317 | if (!page_head->mapping) { | 333 | if (!page_head->mapping) { |
| 334 | int shmem_swizzled = PageSwapCache(page_head); | ||
| 318 | unlock_page(page_head); | 335 | unlock_page(page_head); |
| 319 | put_page(page_head); | 336 | put_page(page_head); |
| 320 | /* | 337 | if (shmem_swizzled) |
| 321 | * ZERO_PAGE pages don't have a mapping. Avoid a busy loop | 338 | goto again; |
| 322 | * trying to find one. RW mapping would have COW'd (and thus | 339 | return -EFAULT; |
| 323 | * have a mapping) so this page is RO and won't ever change. | ||
| 324 | */ | ||
| 325 | if ((page_head == ZERO_PAGE(address))) | ||
| 326 | return -EFAULT; | ||
| 327 | goto again; | ||
| 328 | } | 340 | } |
| 329 | 341 | ||
| 330 | /* | 342 | /* |
