Commit 9276aad6 authored by Hugh Dickins's avatar Hugh Dickins Committed by Linus Torvalds

tmpfs: remove_shmem_readpage

Remove that pernicious shmem_readpage() at last: the things we needed it
for (splice, loop, sendfile, i915 GEM) are now fully taken care of by
shmem_file_splice_read() and shmem_read_mapping_page_gfp().

This removal clears the way for a simpler shmem_getpage_gfp(), since page
is never passed in; but leave most of that cleanup until after.

sys_readahead() and sys_fadvise(POSIX_FADV_WILLNEED) will now EINVAL,
instead of unexpectedly trying to read ahead on tmpfs: if that proves to
be an issue for someone, then we can either arrange for them to return
success instead, or try to implement async readahead on tmpfs.
Signed-off-by: default avatarHugh Dickins <hughd@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 68da9f05
...@@ -1246,7 +1246,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx, ...@@ -1246,7 +1246,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx,
struct address_space *mapping = inode->i_mapping; struct address_space *mapping = inode->i_mapping;
struct shmem_inode_info *info = SHMEM_I(inode); struct shmem_inode_info *info = SHMEM_I(inode);
struct shmem_sb_info *sbinfo; struct shmem_sb_info *sbinfo;
struct page *filepage = *pagep; struct page *filepage;
struct page *swappage; struct page *swappage;
struct page *prealloc_page = NULL; struct page *prealloc_page = NULL;
swp_entry_t *entry; swp_entry_t *entry;
...@@ -1255,17 +1255,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx, ...@@ -1255,17 +1255,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx,
if (idx >= SHMEM_MAX_INDEX) if (idx >= SHMEM_MAX_INDEX)
return -EFBIG; return -EFBIG;
/*
* Normally, filepage is NULL on entry, and either found
* uptodate immediately, or allocated and zeroed, or read
* in under swappage, which is then assigned to filepage.
* But shmem_readpage (required for splice) passes in a locked
* filepage, which may be found not uptodate by other callers
* too, and may need to be copied from the swappage read in.
*/
repeat: repeat:
if (!filepage)
filepage = find_lock_page(mapping, idx); filepage = find_lock_page(mapping, idx);
if (filepage && PageUptodate(filepage)) if (filepage && PageUptodate(filepage))
goto done; goto done;
...@@ -1513,8 +1503,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx, ...@@ -1513,8 +1503,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx,
* Perhaps the page was brought in from swap between find_lock_page * Perhaps the page was brought in from swap between find_lock_page
* and taking info->lock? We allow for that at add_to_page_cache_lru, * and taking info->lock? We allow for that at add_to_page_cache_lru,
* but must also avoid reporting a spurious ENOSPC while working on a * but must also avoid reporting a spurious ENOSPC while working on a
* full tmpfs. (When filepage has been passed in to shmem_getpage, it * full tmpfs.
* is already in page cache, which prevents this race from occurring.)
*/ */
if (!filepage) { if (!filepage) {
struct page *page = find_get_page(mapping, idx); struct page *page = find_get_page(mapping, idx);
...@@ -1527,7 +1516,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx, ...@@ -1527,7 +1516,7 @@ static int shmem_getpage_gfp(struct inode *inode, pgoff_t idx,
spin_unlock(&info->lock); spin_unlock(&info->lock);
error = -ENOSPC; error = -ENOSPC;
failed: failed:
if (*pagep != filepage) { if (filepage) {
unlock_page(filepage); unlock_page(filepage);
page_cache_release(filepage); page_cache_release(filepage);
} }
...@@ -1673,19 +1662,6 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode ...@@ -1673,19 +1662,6 @@ static struct inode *shmem_get_inode(struct super_block *sb, const struct inode
static const struct inode_operations shmem_symlink_inode_operations; static const struct inode_operations shmem_symlink_inode_operations;
static const struct inode_operations shmem_symlink_inline_operations; static const struct inode_operations shmem_symlink_inline_operations;
/*
* Normally tmpfs avoids the use of shmem_readpage and shmem_write_begin;
* but providing them allows a tmpfs file to be used for splice, sendfile, and
* below the loop driver, in the generic fashion that many filesystems support.
*/
static int shmem_readpage(struct file *file, struct page *page)
{
struct inode *inode = page->mapping->host;
int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL);
unlock_page(page);
return error;
}
static int static int
shmem_write_begin(struct file *file, struct address_space *mapping, shmem_write_begin(struct file *file, struct address_space *mapping,
loff_t pos, unsigned len, unsigned flags, loff_t pos, unsigned len, unsigned flags,
...@@ -1693,7 +1669,6 @@ shmem_write_begin(struct file *file, struct address_space *mapping, ...@@ -1693,7 +1669,6 @@ shmem_write_begin(struct file *file, struct address_space *mapping,
{ {
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
pgoff_t index = pos >> PAGE_CACHE_SHIFT; pgoff_t index = pos >> PAGE_CACHE_SHIFT;
*pagep = NULL;
return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL); return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL);
} }
...@@ -1893,7 +1868,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, ...@@ -1893,7 +1868,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
error = 0; error = 0;
while (spd.nr_pages < nr_pages) { while (spd.nr_pages < nr_pages) {
page = NULL;
error = shmem_getpage(inode, index, &page, SGP_CACHE, NULL); error = shmem_getpage(inode, index, &page, SGP_CACHE, NULL);
if (error) if (error)
break; break;
...@@ -1916,7 +1890,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos, ...@@ -1916,7 +1890,6 @@ static ssize_t shmem_file_splice_read(struct file *in, loff_t *ppos,
page = spd.pages[page_nr]; page = spd.pages[page_nr];
if (!PageUptodate(page) || page->mapping != mapping) { if (!PageUptodate(page) || page->mapping != mapping) {
page = NULL;
error = shmem_getpage(inode, index, &page, error = shmem_getpage(inode, index, &page,
SGP_CACHE, NULL); SGP_CACHE, NULL);
if (error) if (error)
...@@ -2125,7 +2098,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s ...@@ -2125,7 +2098,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
int error; int error;
int len; int len;
struct inode *inode; struct inode *inode;
struct page *page = NULL; struct page *page;
char *kaddr; char *kaddr;
struct shmem_inode_info *info; struct shmem_inode_info *info;
...@@ -2803,7 +2776,6 @@ static const struct address_space_operations shmem_aops = { ...@@ -2803,7 +2776,6 @@ static const struct address_space_operations shmem_aops = {
.writepage = shmem_writepage, .writepage = shmem_writepage,
.set_page_dirty = __set_page_dirty_no_writeback, .set_page_dirty = __set_page_dirty_no_writeback,
#ifdef CONFIG_TMPFS #ifdef CONFIG_TMPFS
.readpage = shmem_readpage,
.write_begin = shmem_write_begin, .write_begin = shmem_write_begin,
.write_end = shmem_write_end, .write_end = shmem_write_end,
#endif #endif
...@@ -3175,7 +3147,7 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping, ...@@ -3175,7 +3147,7 @@ struct page *shmem_read_mapping_page_gfp(struct address_space *mapping,
{ {
#ifdef CONFIG_SHMEM #ifdef CONFIG_SHMEM
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
struct page *page = NULL; struct page *page;
int error; int error;
BUG_ON(mapping->a_ops != &shmem_aops); BUG_ON(mapping->a_ops != &shmem_aops);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment