|
@@ -288,40 +288,31 @@ static int shmem_add_to_page_cache(struct page *page,
|
|
struct address_space *mapping,
|
|
struct address_space *mapping,
|
|
pgoff_t index, gfp_t gfp, void *expected)
|
|
pgoff_t index, gfp_t gfp, void *expected)
|
|
{
|
|
{
|
|
- int error = 0;
|
|
|
|
|
|
+ int error;
|
|
|
|
|
|
VM_BUG_ON(!PageLocked(page));
|
|
VM_BUG_ON(!PageLocked(page));
|
|
VM_BUG_ON(!PageSwapBacked(page));
|
|
VM_BUG_ON(!PageSwapBacked(page));
|
|
|
|
|
|
|
|
+ page_cache_get(page);
|
|
|
|
+ page->mapping = mapping;
|
|
|
|
+ page->index = index;
|
|
|
|
+
|
|
|
|
+ spin_lock_irq(&mapping->tree_lock);
|
|
if (!expected)
|
|
if (!expected)
|
|
- error = radix_tree_preload(gfp & GFP_RECLAIM_MASK);
|
|
|
|
|
|
+ error = radix_tree_insert(&mapping->page_tree, index, page);
|
|
|
|
+ else
|
|
|
|
+ error = shmem_radix_tree_replace(mapping, index, expected,
|
|
|
|
+ page);
|
|
if (!error) {
|
|
if (!error) {
|
|
- page_cache_get(page);
|
|
|
|
- page->mapping = mapping;
|
|
|
|
- page->index = index;
|
|
|
|
-
|
|
|
|
- spin_lock_irq(&mapping->tree_lock);
|
|
|
|
- if (!expected)
|
|
|
|
- error = radix_tree_insert(&mapping->page_tree,
|
|
|
|
- index, page);
|
|
|
|
- else
|
|
|
|
- error = shmem_radix_tree_replace(mapping, index,
|
|
|
|
- expected, page);
|
|
|
|
- if (!error) {
|
|
|
|
- mapping->nrpages++;
|
|
|
|
- __inc_zone_page_state(page, NR_FILE_PAGES);
|
|
|
|
- __inc_zone_page_state(page, NR_SHMEM);
|
|
|
|
- spin_unlock_irq(&mapping->tree_lock);
|
|
|
|
- } else {
|
|
|
|
- page->mapping = NULL;
|
|
|
|
- spin_unlock_irq(&mapping->tree_lock);
|
|
|
|
- page_cache_release(page);
|
|
|
|
- }
|
|
|
|
- if (!expected)
|
|
|
|
- radix_tree_preload_end();
|
|
|
|
|
|
+ mapping->nrpages++;
|
|
|
|
+ __inc_zone_page_state(page, NR_FILE_PAGES);
|
|
|
|
+ __inc_zone_page_state(page, NR_SHMEM);
|
|
|
|
+ spin_unlock_irq(&mapping->tree_lock);
|
|
|
|
+ } else {
|
|
|
|
+ page->mapping = NULL;
|
|
|
|
+ spin_unlock_irq(&mapping->tree_lock);
|
|
|
|
+ page_cache_release(page);
|
|
}
|
|
}
|
|
- if (error)
|
|
|
|
- mem_cgroup_uncharge_cache_page(page);
|
|
|
|
return error;
|
|
return error;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1202,11 +1193,18 @@ repeat:
|
|
__set_page_locked(page);
|
|
__set_page_locked(page);
|
|
error = mem_cgroup_cache_charge(page, current->mm,
|
|
error = mem_cgroup_cache_charge(page, current->mm,
|
|
gfp & GFP_RECLAIM_MASK);
|
|
gfp & GFP_RECLAIM_MASK);
|
|
- if (!error)
|
|
|
|
- error = shmem_add_to_page_cache(page, mapping, index,
|
|
|
|
- gfp, NULL);
|
|
|
|
if (error)
|
|
if (error)
|
|
goto decused;
|
|
goto decused;
|
|
|
|
+ error = radix_tree_preload(gfp & GFP_RECLAIM_MASK);
|
|
|
|
+ if (!error) {
|
|
|
|
+ error = shmem_add_to_page_cache(page, mapping, index,
|
|
|
|
+ gfp, NULL);
|
|
|
|
+ radix_tree_preload_end();
|
|
|
|
+ }
|
|
|
|
+ if (error) {
|
|
|
|
+ mem_cgroup_uncharge_cache_page(page);
|
|
|
|
+ goto decused;
|
|
|
|
+ }
|
|
lru_cache_add_anon(page);
|
|
lru_cache_add_anon(page);
|
|
|
|
|
|
spin_lock(&info->lock);
|
|
spin_lock(&info->lock);
|