aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hughd@google.com>2011-06-27 19:18:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2011-06-27 21:00:12 -0400
commitd9d90e5eb70e09903dadff42099b6c948f814050 (patch)
treec3ab73df6dee61f9403bfd819a6b0cb9f3ca6085
parent94c1e62df4494b79782cb9c7279f827212d1de70 (diff)
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>
-rw-r--r--include/linux/shmem_fs.h17
-rw-r--r--mm/shmem.c23
2 files changed, 33 insertions, 7 deletions
diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h
index 22a20af4d785..aa08fa8fd79b 100644
--- a/include/linux/shmem_fs.h
+++ b/include/linux/shmem_fs.h
@@ -3,15 +3,9 @@
3 3
4#include <linux/swap.h> 4#include <linux/swap.h>
5#include <linux/mempolicy.h> 5#include <linux/mempolicy.h>
6#include <linux/pagemap.h>
6#include <linux/percpu_counter.h> 7#include <linux/percpu_counter.h>
7 8
8struct page;
9struct file;
10struct inode;
11struct super_block;
12struct user_struct;
13struct vm_area_struct;
14
15/* inode in-kernel data */ 9/* inode in-kernel data */
16 10
17#define SHMEM_NR_DIRECT 16 11#define SHMEM_NR_DIRECT 16
@@ -61,9 +55,18 @@ extern struct file *shmem_file_setup(const char *name,
61 loff_t size, unsigned long flags); 55 loff_t size, unsigned long flags);
62extern int shmem_zero_setup(struct vm_area_struct *); 56extern int shmem_zero_setup(struct vm_area_struct *);
63extern int shmem_lock(struct file *file, int lock, struct user_struct *user); 57extern int shmem_lock(struct file *file, int lock, struct user_struct *user);
58extern struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
59 pgoff_t index, gfp_t gfp_mask);
64extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end); 60extern void shmem_truncate_range(struct inode *inode, loff_t start, loff_t end);
65extern int shmem_unuse(swp_entry_t entry, struct page *page); 61extern int shmem_unuse(swp_entry_t entry, struct page *page);
66extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff, 62extern void mem_cgroup_get_shmem_target(struct inode *inode, pgoff_t pgoff,
67 struct page **pagep, swp_entry_t *ent); 63 struct page **pagep, swp_entry_t *ent);
68 64
65static 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}
71
69#endif 72#endif
diff --git a/mm/shmem.c b/mm/shmem.c
index f1714758ea96..fcedf5464eb7 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -3035,3 +3035,26 @@ int shmem_zero_setup(struct vm_area_struct *vma)
3035 vma->vm_flags |= VM_CAN_NONLINEAR; 3035 vma->vm_flags |= VM_CAN_NONLINEAR;
3036 return 0; 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 */
3055struct 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}
3060EXPORT_SYMBOL_GPL(shmem_read_mapping_page_gfp);