diff options
Diffstat (limited to 'mm/shmem.c')
-rw-r--r-- | mm/shmem.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/mm/shmem.c b/mm/shmem.c index 4ef9797bd430..855eaf5b8d5b 100644 --- a/mm/shmem.c +++ b/mm/shmem.c | |||
@@ -2559,6 +2559,45 @@ out4: | |||
2559 | return error; | 2559 | return error; |
2560 | } | 2560 | } |
2561 | 2561 | ||
2562 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
2563 | /** | ||
2564 | * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file | ||
2565 | * @inode: the inode to be searched | ||
2566 | * @pgoff: the offset to be searched | ||
2567 | * @pagep: the pointer for the found page to be stored | ||
2568 | * @ent: the pointer for the found swap entry to be stored | ||
2569 | * | ||
2570 | * If a page is found, refcount of it is incremented. Callers should handle | ||
2571 | * these refcount. | ||
2572 | */ | ||
2573 | void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, | ||
2574 | struct page **pagep, swp_entry_t *ent) | ||
2575 | { | ||
2576 | swp_entry_t entry = { .val = 0 }, *ptr; | ||
2577 | struct page *page = NULL; | ||
2578 | struct shmem_inode_info *info = SHMEM_I(inode); | ||
2579 | |||
2580 | if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) | ||
2581 | goto out; | ||
2582 | |||
2583 | spin_lock(&info->lock); | ||
2584 | ptr = shmem_swp_entry(info, pgoff, NULL); | ||
2585 | #ifdef CONFIG_SWAP | ||
2586 | if (ptr && ptr->val) { | ||
2587 | entry.val = ptr->val; | ||
2588 | page = find_get_page(&swapper_space, entry.val); | ||
2589 | } else | ||
2590 | #endif | ||
2591 | page = find_get_page(inode->i_mapping, pgoff); | ||
2592 | if (ptr) | ||
2593 | shmem_swp_unmap(ptr); | ||
2594 | spin_unlock(&info->lock); | ||
2595 | out: | ||
2596 | *pagep = page; | ||
2597 | *ent = entry; | ||
2598 | } | ||
2599 | #endif | ||
2600 | |||
2562 | #else /* !CONFIG_SHMEM */ | 2601 | #else /* !CONFIG_SHMEM */ |
2563 | 2602 | ||
2564 | /* | 2603 | /* |
@@ -2598,6 +2637,31 @@ int shmem_lock(struct file *file, int lock, struct user_struct *user) | |||
2598 | return 0; | 2637 | return 0; |
2599 | } | 2638 | } |
2600 | 2639 | ||
2640 | #ifdef CONFIG_CGROUP_MEM_RES_CTLR | ||
2641 | /** | ||
2642 | * mem_cgroup_get_shmem_target - find a page or entry assigned to the shmem file | ||
2643 | * @inode: the inode to be searched | ||
2644 | * @pgoff: the offset to be searched | ||
2645 | * @pagep: the pointer for the found page to be stored | ||
2646 | * @ent: the pointer for the found swap entry to be stored | ||
2647 | * | ||
2648 | * If a page is found, refcount of it is incremented. Callers should handle | ||
2649 | * these refcount. | ||
2650 | */ | ||
2651 | void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, | ||
2652 | struct page **pagep, swp_entry_t *ent) | ||
2653 | { | ||
2654 | struct page *page = NULL; | ||
2655 | |||
2656 | if ((pgoff << PAGE_CACHE_SHIFT) >= i_size_read(inode)) | ||
2657 | goto out; | ||
2658 | page = find_get_page(inode->i_mapping, pgoff); | ||
2659 | out: | ||
2660 | *pagep = page; | ||
2661 | *ent = (swp_entry_t){ .val = 0 }; | ||
2662 | } | ||
2663 | #endif | ||
2664 | |||
2601 | #define shmem_vm_ops generic_file_vm_ops | 2665 | #define shmem_vm_ops generic_file_vm_ops |
2602 | #define shmem_file_operations ramfs_file_operations | 2666 | #define shmem_file_operations ramfs_file_operations |
2603 | #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) | 2667 | #define shmem_get_inode(sb, dir, mode, dev, flags) ramfs_get_inode(sb, dir, mode, dev) |