Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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>

authored by

Hugh Dickins and committed by
Linus Torvalds
d9d90e5e 94c1e62d

+33 -7
+10 -7
include/linux/shmem_fs.h
··· 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 - struct page; 9 - struct file; 10 - struct inode; 11 - struct super_block; 12 - struct user_struct; 13 - struct vm_area_struct; 14 8 15 9 /* inode in-kernel data */ 16 10 ··· 55 61 loff_t size, unsigned long flags); 56 62 extern int shmem_zero_setup(struct vm_area_struct *); 57 63 extern int shmem_lock(struct file *file, int lock, struct user_struct *user); 64 + extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, 65 + pgoff_t index, gfp_t gfp_mask); 58 66 extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); 59 67 extern int shmem_unuse(swp_entry_t entry, struct page *page); 60 68 extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, 61 69 struct page **pagep, swp_entry_t *ent); 70 + 71 + static inline struct page *shmem_read_mapping_page( 72 + struct address_space *mapping, pgoff_t index) 73 + { 74 + return shmem_read_mapping_page_gfp(mapping, index, 75 + mapping_gfp_mask(mapping)); 76 + } 62 77 63 78 #endif
+23
mm/shmem.c
··· 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);