clk: sunxi: factors: Consolidate get_factors parameters into a struct
[deliverable/linux.git] / mm / util.c
index 2d28f79300431422397f0c3d82f637bc9f8d5a87..c108a6542d05d3e1c880c1f6ab540ced62156e54 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,
@@ -460,17 +476,25 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
        int res = 0;
        unsigned int len;
        struct mm_struct *mm = get_task_mm(task);
+       unsigned long arg_start, arg_end, env_start, env_end;
        if (!mm)
                goto out;
        if (!mm->arg_end)
                goto out_mm;    /* Shh! No looking before we're done */
 
-       len = mm->arg_end - mm->arg_start;
+       down_read(&mm->mmap_sem);
+       arg_start = mm->arg_start;
+       arg_end = mm->arg_end;
+       env_start = mm->env_start;
+       env_end = mm->env_end;
+       up_read(&mm->mmap_sem);
+
+       len = arg_end - arg_start;
 
        if (len > buflen)
                len = buflen;
 
-       res = access_process_vm(task, mm->arg_start, buffer, len, 0);
+       res = access_process_vm(task, arg_start, buffer, len, 0);
 
        /*
         * If the nul at the end of args has been overwritten, then
@@ -481,10 +505,10 @@ int get_cmdline(struct task_struct *task, char *buffer, int buflen)
                if (len < res) {
                        res = len;
                } else {
-                       len = mm->env_end - mm->env_start;
+                       len = env_end - env_start;
                        if (len > buflen - res)
                                len = buflen - res;
-                       res += access_process_vm(task, mm->env_start,
+                       res += access_process_vm(task, env_start,
                                                 buffer+res, len, 0);
                        res = strnlen(buffer, res);
                }
This page took 0.025148 seconds and 5 git commands to generate.