]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - mm/util.c
Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf
[karo-tx-linux.git] / mm / util.c
index 2d28f79300431422397f0c3d82f637bc9f8d5a87..6d1f9200f74e794c403ec687bae513e4f6e40700 100644 (file)
--- a/mm/util.c
+++ b/mm/util.c
@@ -386,7 +386,9 @@ struct anon_vma *page_anon_vma(struct page *page)
 
 struct address_space *page_mapping(struct page *page)
 {
-       unsigned long mapping;
+       struct address_space *mapping;
+
+       page = compound_head(page);
 
        /* This happens if someone calls flush_dcache_page on slab page */
        if (unlikely(PageSlab(page)))
@@ -399,11 +401,25 @@ struct address_space *page_mapping(struct page *page)
                return swap_address_space(entry);
        }
 
-       mapping = (unsigned long)page->mapping;
-       if (mapping & PAGE_MAPPING_FLAGS)
+       mapping = page->mapping;
+       if ((unsigned long)mapping & PAGE_MAPPING_FLAGS)
                return NULL;
-       return page->mapping;
+       return mapping;
+}
+
+/* Slow path of page_mapcount() for compound pages */
+int __page_mapcount(struct page *page)
+{
+       int ret;
+
+       ret = atomic_read(&page->_mapcount) + 1;
+       page = compound_head(page);
+       ret += atomic_read(compound_mapcount_ptr(page)) + 1;
+       if (PageDoubleMap(page))
+               ret--;
+       return ret;
 }
+EXPORT_SYMBOL_GPL(__page_mapcount);
 
 int overcommit_ratio_handler(struct ctl_table *table, int write,
                             void __user *buffer, size_t *lenp,