Commit d9d90e5eb70e09903dadff42099b6c948f814050
Committed by
Linus Torvalds
1 parent
94c1e62df4
Exists in
master
and in
39 other branches
tmpfs: add shmem_read_mapping_page_gfp
Although it is used (by i915) on nothing but tmpfs, read_cache_page_gfp() is unsuited to tmpfs, because it inserts a page into pagecache before calling the filesystem's ->readpage: tmpfs may have pages in swapcache which only it knows how to locate and switch to filecache. At present tmpfs provides a ->readpage method, and copes with this by copying pages; but soon we can simplify it by removing its ->readpage. Provide shmem_read_mapping_page_gfp() now, ready for that transition, Export shmem_read_mapping_page_gfp() and add it to list in shmem_fs.h, with shmem_read_mapping_page() inline for the common mapping_gfp case. (shmem_read_mapping_page_gfp or shmem_read_cache_page_gfp? Generally the read_mapping_page functions use the mapping's ->readpage, and the read_cache_page functions use the supplied filler, so I think read_cache_page_gfp was slightly misnamed.) Signed-off-by: Hugh Dickins <hughd@google.com> Cc: Christoph Hellwig <hch@infradead.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Showing 2 changed files with 33 additions and 7 deletions Side-by-side Diff
include/linux/shmem_fs.h
... | ... | @@ -3,15 +3,9 @@ |
3 | 3 | |
4 | 4 | #include <linux/swap.h> |
5 | 5 | #include <linux/mempolicy.h> |
6 | +#include <linux/pagemap.h> | |
6 | 7 | #include <linux/percpu_counter.h> |
7 | 8 | |
8 | -struct page; | |
9 | -struct file; | |
10 | -struct inode; | |
11 | -struct super_block; | |
12 | -struct user_struct; | |
13 | -struct vm_area_struct; | |
14 | - | |
15 | 9 | /* inode in-kernel data */ |
16 | 10 | |
17 | 11 | #define SHMEM_NR_DIRECT 16 |
18 | 12 | |
... | ... | @@ -61,10 +55,19 @@ |
61 | 55 | loff_t size, unsigned long flags); |
62 | 56 | extern int shmem_zero_setup(struct vm_area_struct *); |
63 | 57 | extern int shmem_lock(struct file *file, int lock, struct user_struct *user); |
58 | +extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, | |
59 | + pgoff_t index, gfp_t gfp_mask); | |
64 | 60 | extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); |
65 | 61 | extern int shmem_unuse(swp_entry_t entry, struct page *page); |
66 | 62 | extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, |
67 | 63 | struct page **pagep, swp_entry_t *ent); |
64 | + | |
65 | +static inline struct page *shmem_read_mapping_page( | |
66 | + struct address_space *mapping, pgoff_t index) | |
67 | +{ | |
68 | + return shmem_read_mapping_page_gfp(mapping, index, | |
69 | + mapping_gfp_mask(mapping)); | |
70 | +} | |
68 | 71 | |
69 | 72 | #endif |
mm/shmem.c
... | ... | @@ -3035,4 +3035,27 @@ |
3035 | 3035 | vma->vm_flags |= VM_CAN_NONLINEAR; |
3036 | 3036 | return 0; |
3037 | 3037 | } |
3038 | + | |
3039 | +/** | |
3040 | + * shmem_read_mapping_page_gfp - read into page cache, using specified page allocation flags. | |
3041 | + * @mapping: the page's address_space | |
3042 | + * @index: the page index | |
3043 | + * @gfp: the page allocator flags to use if allocating | |
3044 | + * | |
3045 | + * This behaves as a tmpfs "read_cache_page_gfp(mapping, index, gfp)", | |
3046 | + * with any new page allocations done using the specified allocation flags. | |
3047 | + * But read_cache_page_gfp() uses the ->readpage() method: which does not | |
3048 | + * suit tmpfs, since it may have pages in swapcache, and needs to find those | |
3049 | + * for itself; although drivers/gpu/drm i915 and ttm rely upon this support. | |
3050 | + * | |
3051 | + * Provide a stub for those callers to start using now, then later | |
3052 | + * flesh it out to call shmem_getpage() with additional gfp mask, when | |
3053 | + * shmem_file_splice_read() is added and shmem_readpage() is removed. | |
3054 | + */ | |
3055 | +struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, | |
3056 | + pgoff_t index, gfp_t gfp) | |
3057 | +{ | |
3058 | + return read_cache_page_gfp(mapping, index, gfp); | |
3059 | +} | |
3060 | +EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp); |