aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHugh Dickins <hugh@veritas.com>2007-06-04 04:00:39 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-07-10 02:04:15 -0400
commitae976416464b741913a13eea62eb6953ee065733 (patch)
tree48ac14023b494c9f6522ad390f60e4decac41ac3
parent1db60cf2056511c7c8cebcbaee308ef6c79b4728 (diff)
shmem: convert to using splice instead of sendfile()
Remove shmem_file_sendfile and resurrect shmem_readpage, as used by tmpfs to support loop and sendfile in 2.4 and 2.5. Now tmpfs can support splice, loop and sendfile in the simplest way, using generic_file_splice_read and generic_file_splice_write (with the aid of shmem_prepare_write). We could make some efficiency tweaks later, if there's a real need; but this is stable and works well as is. Signed-off-by: Hugh Dickins <hugh@veritas.com> Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
-rw-r--r--mm/shmem.c42
1 files changed, 17 insertions, 25 deletions
diff --git a/mm/shmem.c b/mm/shmem.c
index b6aae2b33393..0493e4d0bcaa 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -1100,9 +1100,9 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
1100 * Normally, filepage is NULL on entry, and either found 1100 * Normally, filepage is NULL on entry, and either found
1101 * uptodate immediately, or allocated and zeroed, or read 1101 * uptodate immediately, or allocated and zeroed, or read
1102 * in under swappage, which is then assigned to filepage. 1102 * in under swappage, which is then assigned to filepage.
1103 * But shmem_prepare_write passes in a locked filepage, 1103 * But shmem_readpage and shmem_prepare_write pass in a locked
1104 * which may be found not uptodate by other callers too, 1104 * filepage, which may be found not uptodate by other callers
1105 * and may need to be copied from the swappage read in. 1105 * too, and may need to be copied from the swappage read in.
1106 */ 1106 */
1107repeat: 1107repeat:
1108 if (!filepage) 1108 if (!filepage)
@@ -1485,9 +1485,18 @@ static const struct inode_operations shmem_symlink_inode_operations;
1485static const struct inode_operations shmem_symlink_inline_operations; 1485static const struct inode_operations shmem_symlink_inline_operations;
1486 1486
1487/* 1487/*
1488 * Normally tmpfs makes no use of shmem_prepare_write, but it 1488 * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write;
1489 * lets a tmpfs file be used read-write below the loop driver. 1489 * but providing them allows a tmpfs file to be used for splice, sendfile, and
1490 * below the loop driver, in the generic fashion that many filesystems support.
1490 */ 1491 */
1492static int shmem_readpage(struct file *file, struct page *page)
1493{
1494 struct inode *inode = page->mapping->host;
1495 int error = shmem_getpage(inode, page->index, &page, SGP_CACHE, NULL);
1496 unlock_page(page);
1497 return error;
1498}
1499
1491static int 1500static int
1492shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 1501shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to)
1493{ 1502{
@@ -1711,25 +1720,6 @@ static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count
1711 return desc.error; 1720 return desc.error;
1712} 1721}
1713 1722
1714static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
1715 size_t count, read_actor_t actor, void *target)
1716{
1717 read_descriptor_t desc;
1718
1719 if (!count)
1720 return 0;
1721
1722 desc.written = 0;
1723 desc.count = count;
1724 desc.arg.data = target;
1725 desc.error = 0;
1726
1727 do_shmem_file_read(in_file, ppos, &desc, actor);
1728 if (desc.written)
1729 return desc.written;
1730 return desc.error;
1731}
1732
1733static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf) 1723static int shmem_statfs(struct dentry *dentry, struct kstatfs *buf)
1734{ 1724{
1735 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb); 1725 struct shmem_sb_info *sbinfo = SHMEM_SB(dentry->d_sb);
@@ -2386,6 +2376,7 @@ static const struct address_space_operations shmem_aops = {
2386 .writepage = shmem_writepage, 2376 .writepage = shmem_writepage,
2387 .set_page_dirty = __set_page_dirty_no_writeback, 2377 .set_page_dirty = __set_page_dirty_no_writeback,
2388#ifdef CONFIG_TMPFS 2378#ifdef CONFIG_TMPFS
2379 .readpage = shmem_readpage,
2389 .prepare_write = shmem_prepare_write, 2380 .prepare_write = shmem_prepare_write,
2390 .commit_write = simple_commit_write, 2381 .commit_write = simple_commit_write,
2391#endif 2382#endif
@@ -2399,7 +2390,8 @@ static const struct file_operations shmem_file_operations = {
2399 .read = shmem_file_read, 2390 .read = shmem_file_read,
2400 .write = shmem_file_write, 2391 .write = shmem_file_write,
2401 .fsync = simple_sync_file, 2392 .fsync = simple_sync_file,
2402 .sendfile = shmem_file_sendfile, 2393 .splice_read = generic_file_splice_read,
2394 .splice_write = generic_file_splice_write,
2403#endif 2395#endif
2404}; 2396};
2405 2397