diff options
Diffstat (limited to 'mm/util.c')
-rw-r--r-- | mm/util.c | 24 |
1 files changed, 20 insertions, 4 deletions
@@ -386,7 +386,9 @@ struct anon_vma *page_anon_vma(struct page *page) | |||
386 | 386 | ||
387 | struct address_space *page_mapping(struct page *page) | 387 | struct address_space *page_mapping(struct page *page) |
388 | { | 388 | { |
389 | unsigned long mapping; | 389 | struct address_space *mapping; |
390 | |||
391 | page = compound_head(page); | ||
390 | 392 | ||
391 | /* This happens if someone calls flush_dcache_page on slab page */ | 393 | /* This happens if someone calls flush_dcache_page on slab page */ |
392 | if (unlikely(PageSlab(page))) | 394 | if (unlikely(PageSlab(page))) |
@@ -399,11 +401,25 @@ struct address_space *page_mapping(struct page *page) | |||
399 | return swap_address_space(entry); | 401 | return swap_address_space(entry); |
400 | } | 402 | } |
401 | 403 | ||
402 | mapping = (unsigned long)page->mapping; | 404 | mapping = page->mapping; |
403 | if (mapping & PAGE_MAPPING_FLAGS) | 405 | if ((unsigned long)mapping & PAGE_MAPPING_FLAGS) |
404 | return NULL; | 406 | return NULL; |
405 | return page->mapping; | 407 | return mapping; |
408 | } | ||
409 | |||
410 | /* Slow path of page_mapcount() for compound pages */ | ||
411 | int __page_mapcount(struct page *page) | ||
412 | { | ||
413 | int ret; | ||
414 | |||
415 | ret = atomic_read(&page->_mapcount) + 1; | ||
416 | page = compound_head(page); | ||
417 | ret += atomic_read(compound_mapcount_ptr(page)) + 1; | ||
418 | if (PageDoubleMap(page)) | ||
419 | ret--; | ||
420 | return ret; | ||
406 | } | 421 | } |
422 | EXPORT_SYMBOL_GPL(__page_mapcount); | ||
407 | 423 | ||
408 | int overcommit_ratio_handler(struct ctl_table *table, int write, | 424 | int overcommit_ratio_handler(struct ctl_table *table, int write, |
409 | void __user *buffer, size_t *lenp, | 425 | void __user *buffer, size_t *lenp, |