#endif
unsigned long num_physpages;
+/*
+ * A number of key systems in x86 including ioremap() rely on the assumption
+ * that high_memory defines the upper bound on direct map memory, then end
+ * of ZONE_NORMAL. Under CONFIG_DISCONTIG this means that max_low_pfn and
+ * highstart_pfn must be the same; there must be no gap between ZONE_NORMAL
+ * and ZONE_HIGHMEM.
+ */
void * high_memory;
struct page *highmem_start_page;
+unsigned long vmalloc_earlyreserve;
EXPORT_SYMBOL(num_physpages);
EXPORT_SYMBOL(highmem_start_page);
EXPORT_SYMBOL(high_memory);
+EXPORT_SYMBOL(vmalloc_earlyreserve);
/*
* We special-case the C-O-W ZERO_PAGE, because it's such
set_pte(ptep, pgoff_to_pte(page->index));
if (pte_dirty(pte))
set_page_dirty(page);
- if (pte_young(pte) && page_mapping(page))
+ if (pte_young(pte) && !PageAnon(page))
mark_page_accessed(page);
tlb->freed++;
page_remove_rmap(page);
static inline struct page *get_page_map(struct page *page)
{
if (!pfn_valid(page_to_pfn(page)))
- return 0;
+ return NULL;
return page;
}
pte_t *pte;
if (write) /* user gate pages are read-only */
return i ? : -EFAULT;
- pgd = pgd_offset_k(pg);
+ pgd = pgd_offset_gate(mm, pg);
if (!pgd)
return i ? : -EFAULT;
pmd = pmd_offset(pgd, pg);
if (!pmd)
return i ? : -EFAULT;
- pte = pte_offset_kernel(pmd, pg);
- if (!pte || !pte_present(*pte))
+ pte = pte_offset_map(pmd, pg);
+ if (!pte)
+ return i ? : -EFAULT;
+ if (!pte_present(*pte)) {
+ pte_unmap(pte);
return i ? : -EFAULT;
+ }
if (pages) {
pages[i] = pte_page(*pte);
get_page(pages[i]);
}
+ pte_unmap(pte);
if (vmas)
vmas[i] = gate_vma;
i++;
/*
* Ok, we need to copy. Oh, well..
*/
- page_cache_get(old_page);
+ if (!PageReserved(old_page))
+ page_cache_get(old_page);
spin_unlock(&mm->page_table_lock);
if (unlikely(anon_vma_prepare(vma)))
if (inode->i_size < offset)
goto do_expand;
+ /*
+ * truncation of in-use swapfiles is disallowed - it would cause
+ * subsequent swapout to scribble on the now-freed blocks.
+ */
+ if (IS_SWAPFILE(inode))
+ goto out_busy;
i_size_write(inode, offset);
unmap_mapping_range(mapping, offset + PAGE_SIZE - 1, 0, 1);
truncate_inode_pages(mapping, offset);
if (limit != RLIM_INFINITY && offset > limit)
goto out_sig;
if (offset > inode->i_sb->s_maxbytes)
- goto out;
+ goto out_big;
i_size_write(inode, offset);
out_truncate:
return 0;
out_sig:
send_sig(SIGXFSZ, current, 0);
-out:
+out_big:
return -EFBIG;
+out_busy:
+ return -ETXTBSY;
}
EXPORT_SYMBOL(vmtruncate);
#ifdef AT_SYSINFO_EHDR
return &gate_vma;
#else
- return 0;
+ return NULL;
#endif
}