xref: /openbmc/linux/fs/splice.c (revision 29e35094)
15274f052SJens Axboe /*
25274f052SJens Axboe  * "splice": joining two ropes together by interweaving their strands.
35274f052SJens Axboe  *
45274f052SJens Axboe  * This is the "extended pipe" functionality, where a pipe is used as
55274f052SJens Axboe  * an arbitrary in-memory buffer. Think of a pipe as a small kernel
65274f052SJens Axboe  * buffer that you can use to transfer data from one end to the other.
75274f052SJens Axboe  *
85274f052SJens Axboe  * The traditional unix read/write is extended with a "splice()" operation
95274f052SJens Axboe  * that transfers data buffers to or from a pipe buffer.
105274f052SJens Axboe  *
115274f052SJens Axboe  * Named by Larry McVoy, original implementation from Linus, extended by
125274f052SJens Axboe  * Jens to support splicing to files and fixing the initial implementation
135274f052SJens Axboe  * bugs.
145274f052SJens Axboe  *
155274f052SJens Axboe  * Copyright (C) 2005 Jens Axboe <axboe@suse.de>
165274f052SJens Axboe  * Copyright (C) 2005 Linus Torvalds <torvalds@osdl.org>
175274f052SJens Axboe  *
185274f052SJens Axboe  */
195274f052SJens Axboe #include <linux/fs.h>
205274f052SJens Axboe #include <linux/file.h>
215274f052SJens Axboe #include <linux/pagemap.h>
225274f052SJens Axboe #include <linux/pipe_fs_i.h>
235274f052SJens Axboe #include <linux/mm_inline.h>
245abc97aaSJens Axboe #include <linux/swap.h>
25a0f06780SJeff Garzik #include <linux/module.h>
265274f052SJens Axboe 
275274f052SJens Axboe /*
285274f052SJens Axboe  * Passed to the actors
295274f052SJens Axboe  */
305274f052SJens Axboe struct splice_desc {
315274f052SJens Axboe 	unsigned int len, total_len;	/* current and remaining length */
325274f052SJens Axboe 	unsigned int flags;		/* splice flags */
335274f052SJens Axboe 	struct file *file;		/* file to read/write */
345274f052SJens Axboe 	loff_t pos;			/* file position */
355274f052SJens Axboe };
365274f052SJens Axboe 
375abc97aaSJens Axboe static int page_cache_pipe_buf_steal(struct pipe_inode_info *info,
385abc97aaSJens Axboe 				     struct pipe_buffer *buf)
395abc97aaSJens Axboe {
405abc97aaSJens Axboe 	struct page *page = buf->page;
415abc97aaSJens Axboe 
425abc97aaSJens Axboe 	WARN_ON(!PageLocked(page));
435abc97aaSJens Axboe 	WARN_ON(!PageUptodate(page));
445abc97aaSJens Axboe 
455abc97aaSJens Axboe 	if (!remove_mapping(page_mapping(page), page))
465abc97aaSJens Axboe 		return 1;
475abc97aaSJens Axboe 
485abc97aaSJens Axboe 	if (PageLRU(page)) {
495abc97aaSJens Axboe 		struct zone *zone = page_zone(page);
505abc97aaSJens Axboe 
515abc97aaSJens Axboe 		spin_lock_irq(&zone->lru_lock);
525abc97aaSJens Axboe 		BUG_ON(!PageLRU(page));
535abc97aaSJens Axboe 		__ClearPageLRU(page);
545abc97aaSJens Axboe 		del_page_from_lru(zone, page);
555abc97aaSJens Axboe 		spin_unlock_irq(&zone->lru_lock);
565abc97aaSJens Axboe 	}
575abc97aaSJens Axboe 
585abc97aaSJens Axboe 	buf->stolen = 1;
595abc97aaSJens Axboe 	return 0;
605abc97aaSJens Axboe }
615abc97aaSJens Axboe 
625274f052SJens Axboe static void page_cache_pipe_buf_release(struct pipe_inode_info *info,
635274f052SJens Axboe 					struct pipe_buffer *buf)
645274f052SJens Axboe {
655274f052SJens Axboe 	page_cache_release(buf->page);
665274f052SJens Axboe 	buf->page = NULL;
675abc97aaSJens Axboe 	buf->stolen = 0;
685274f052SJens Axboe }
695274f052SJens Axboe 
705274f052SJens Axboe static void *page_cache_pipe_buf_map(struct file *file,
715274f052SJens Axboe 				     struct pipe_inode_info *info,
725274f052SJens Axboe 				     struct pipe_buffer *buf)
735274f052SJens Axboe {
745274f052SJens Axboe 	struct page *page = buf->page;
755274f052SJens Axboe 
765274f052SJens Axboe 	lock_page(page);
775274f052SJens Axboe 
785274f052SJens Axboe 	if (!PageUptodate(page)) {
795274f052SJens Axboe 		unlock_page(page);
805274f052SJens Axboe 		return ERR_PTR(-EIO);
815274f052SJens Axboe 	}
825274f052SJens Axboe 
835274f052SJens Axboe 	if (!page->mapping) {
845274f052SJens Axboe 		unlock_page(page);
855274f052SJens Axboe 		return ERR_PTR(-ENODATA);
865274f052SJens Axboe 	}
875274f052SJens Axboe 
885274f052SJens Axboe 	return kmap(buf->page);
895274f052SJens Axboe }
905274f052SJens Axboe 
915274f052SJens Axboe static void page_cache_pipe_buf_unmap(struct pipe_inode_info *info,
925274f052SJens Axboe 				      struct pipe_buffer *buf)
935274f052SJens Axboe {
945abc97aaSJens Axboe 	if (!buf->stolen)
955274f052SJens Axboe 		unlock_page(buf->page);
965274f052SJens Axboe 	kunmap(buf->page);
975274f052SJens Axboe }
985274f052SJens Axboe 
995274f052SJens Axboe static struct pipe_buf_operations page_cache_pipe_buf_ops = {
1005274f052SJens Axboe 	.can_merge = 0,
1015274f052SJens Axboe 	.map = page_cache_pipe_buf_map,
1025274f052SJens Axboe 	.unmap = page_cache_pipe_buf_unmap,
1035274f052SJens Axboe 	.release = page_cache_pipe_buf_release,
1045abc97aaSJens Axboe 	.steal = page_cache_pipe_buf_steal,
1055274f052SJens Axboe };
1065274f052SJens Axboe 
1075274f052SJens Axboe static ssize_t move_to_pipe(struct inode *inode, struct page **pages,
1085274f052SJens Axboe 			    int nr_pages, unsigned long offset,
10929e35094SLinus Torvalds 			    unsigned long len, unsigned int flags)
1105274f052SJens Axboe {
1115274f052SJens Axboe 	struct pipe_inode_info *info;
1125274f052SJens Axboe 	int ret, do_wakeup, i;
1135274f052SJens Axboe 
1145274f052SJens Axboe 	ret = 0;
1155274f052SJens Axboe 	do_wakeup = 0;
1165274f052SJens Axboe 	i = 0;
1175274f052SJens Axboe 
1185274f052SJens Axboe 	mutex_lock(PIPE_MUTEX(*inode));
1195274f052SJens Axboe 
1205274f052SJens Axboe 	info = inode->i_pipe;
1215274f052SJens Axboe 	for (;;) {
1225274f052SJens Axboe 		int bufs;
1235274f052SJens Axboe 
1245274f052SJens Axboe 		if (!PIPE_READERS(*inode)) {
1255274f052SJens Axboe 			send_sig(SIGPIPE, current, 0);
1265274f052SJens Axboe 			if (!ret)
1275274f052SJens Axboe 				ret = -EPIPE;
1285274f052SJens Axboe 			break;
1295274f052SJens Axboe 		}
1305274f052SJens Axboe 
1315274f052SJens Axboe 		bufs = info->nrbufs;
1325274f052SJens Axboe 		if (bufs < PIPE_BUFFERS) {
1335274f052SJens Axboe 			int newbuf = (info->curbuf + bufs) & (PIPE_BUFFERS - 1);
1345274f052SJens Axboe 			struct pipe_buffer *buf = info->bufs + newbuf;
1355274f052SJens Axboe 			struct page *page = pages[i++];
1365274f052SJens Axboe 			unsigned long this_len;
1375274f052SJens Axboe 
1385274f052SJens Axboe 			this_len = PAGE_CACHE_SIZE - offset;
1395274f052SJens Axboe 			if (this_len > len)
1405274f052SJens Axboe 				this_len = len;
1415274f052SJens Axboe 
1425274f052SJens Axboe 			buf->page = page;
1435274f052SJens Axboe 			buf->offset = offset;
1445274f052SJens Axboe 			buf->len = this_len;
1455274f052SJens Axboe 			buf->ops = &page_cache_pipe_buf_ops;
1465274f052SJens Axboe 			info->nrbufs = ++bufs;
1475274f052SJens Axboe 			do_wakeup = 1;
1485274f052SJens Axboe 
1495274f052SJens Axboe 			ret += this_len;
1505274f052SJens Axboe 			len -= this_len;
1515274f052SJens Axboe 			offset = 0;
1525274f052SJens Axboe 			if (!--nr_pages)
1535274f052SJens Axboe 				break;
1545274f052SJens Axboe 			if (!len)
1555274f052SJens Axboe 				break;
1565274f052SJens Axboe 			if (bufs < PIPE_BUFFERS)
1575274f052SJens Axboe 				continue;
1585274f052SJens Axboe 
1595274f052SJens Axboe 			break;
1605274f052SJens Axboe 		}
1615274f052SJens Axboe 
16229e35094SLinus Torvalds 		if (flags & SPLICE_F_NONBLOCK) {
16329e35094SLinus Torvalds 			if (!ret)
16429e35094SLinus Torvalds 				ret = -EAGAIN;
16529e35094SLinus Torvalds 			break;
16629e35094SLinus Torvalds 		}
16729e35094SLinus Torvalds 
1685274f052SJens Axboe 		if (signal_pending(current)) {
1695274f052SJens Axboe 			if (!ret)
1705274f052SJens Axboe 				ret = -ERESTARTSYS;
1715274f052SJens Axboe 			break;
1725274f052SJens Axboe 		}
1735274f052SJens Axboe 
1745274f052SJens Axboe 		if (do_wakeup) {
1755274f052SJens Axboe 			wake_up_interruptible_sync(PIPE_WAIT(*inode));
1765274f052SJens Axboe 			kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO,
1775274f052SJens Axboe 				    POLL_IN);
1785274f052SJens Axboe 			do_wakeup = 0;
1795274f052SJens Axboe 		}
1805274f052SJens Axboe 
1815274f052SJens Axboe 		PIPE_WAITING_WRITERS(*inode)++;
1825274f052SJens Axboe 		pipe_wait(inode);
1835274f052SJens Axboe 		PIPE_WAITING_WRITERS(*inode)--;
1845274f052SJens Axboe 	}
1855274f052SJens Axboe 
1865274f052SJens Axboe 	mutex_unlock(PIPE_MUTEX(*inode));
1875274f052SJens Axboe 
1885274f052SJens Axboe 	if (do_wakeup) {
1895274f052SJens Axboe 		wake_up_interruptible(PIPE_WAIT(*inode));
1905274f052SJens Axboe 		kill_fasync(PIPE_FASYNC_READERS(*inode), SIGIO, POLL_IN);
1915274f052SJens Axboe 	}
1925274f052SJens Axboe 
1935274f052SJens Axboe 	while (i < nr_pages)
1945274f052SJens Axboe 		page_cache_release(pages[i++]);
1955274f052SJens Axboe 
1965274f052SJens Axboe 	return ret;
1975274f052SJens Axboe }
1985274f052SJens Axboe 
1995274f052SJens Axboe static int __generic_file_splice_read(struct file *in, struct inode *pipe,
20029e35094SLinus Torvalds 				      size_t len, unsigned int flags)
2015274f052SJens Axboe {
2025274f052SJens Axboe 	struct address_space *mapping = in->f_mapping;
2035274f052SJens Axboe 	unsigned int offset, nr_pages;
2045274f052SJens Axboe 	struct page *pages[PIPE_BUFFERS], *shadow[PIPE_BUFFERS];
2055274f052SJens Axboe 	struct page *page;
2065274f052SJens Axboe 	pgoff_t index, pidx;
2075274f052SJens Axboe 	int i, j;
2085274f052SJens Axboe 
2095274f052SJens Axboe 	index = in->f_pos >> PAGE_CACHE_SHIFT;
2105274f052SJens Axboe 	offset = in->f_pos & ~PAGE_CACHE_MASK;
2115274f052SJens Axboe 	nr_pages = (len + offset + PAGE_CACHE_SIZE - 1) >> PAGE_CACHE_SHIFT;
2125274f052SJens Axboe 
2135274f052SJens Axboe 	if (nr_pages > PIPE_BUFFERS)
2145274f052SJens Axboe 		nr_pages = PIPE_BUFFERS;
2155274f052SJens Axboe 
2165274f052SJens Axboe 	/*
2175274f052SJens Axboe 	 * initiate read-ahead on this page range
2185274f052SJens Axboe 	 */
2195274f052SJens Axboe 	do_page_cache_readahead(mapping, in, index, nr_pages);
2205274f052SJens Axboe 
2215274f052SJens Axboe 	/*
2225274f052SJens Axboe 	 * Get as many pages from the page cache as possible..
2235274f052SJens Axboe 	 * Start IO on the page cache entries we create (we
2245274f052SJens Axboe 	 * can assume that any pre-existing ones we find have
2255274f052SJens Axboe 	 * already had IO started on them).
2265274f052SJens Axboe 	 */
2275274f052SJens Axboe 	i = find_get_pages(mapping, index, nr_pages, pages);
2285274f052SJens Axboe 
2295274f052SJens Axboe 	/*
2305274f052SJens Axboe 	 * common case - we found all pages and they are contiguous,
2315274f052SJens Axboe 	 * kick them off
2325274f052SJens Axboe 	 */
2335274f052SJens Axboe 	if (i && (pages[i - 1]->index == index + i - 1))
2345274f052SJens Axboe 		goto splice_them;
2355274f052SJens Axboe 
2365274f052SJens Axboe 	/*
2375274f052SJens Axboe 	 * fill shadow[] with pages at the right locations, so we only
2385274f052SJens Axboe 	 * have to fill holes
2395274f052SJens Axboe 	 */
2405274f052SJens Axboe 	memset(shadow, 0, i * sizeof(struct page *));
2415274f052SJens Axboe 	for (j = 0, pidx = index; j < i; pidx++, j++)
2425274f052SJens Axboe 		shadow[pages[j]->index - pidx] = pages[j];
2435274f052SJens Axboe 
2445274f052SJens Axboe 	/*
2455274f052SJens Axboe 	 * now fill in the holes
2465274f052SJens Axboe 	 */
2475274f052SJens Axboe 	for (i = 0, pidx = index; i < nr_pages; pidx++, i++) {
2485274f052SJens Axboe 		int error;
2495274f052SJens Axboe 
2505274f052SJens Axboe 		if (shadow[i])
2515274f052SJens Axboe 			continue;
2525274f052SJens Axboe 
2535274f052SJens Axboe 		/*
2545274f052SJens Axboe 		 * no page there, look one up / create it
2555274f052SJens Axboe 		 */
2565274f052SJens Axboe 		page = find_or_create_page(mapping, pidx,
2575274f052SJens Axboe 						   mapping_gfp_mask(mapping));
2585274f052SJens Axboe 		if (!page)
2595274f052SJens Axboe 			break;
2605274f052SJens Axboe 
2615274f052SJens Axboe 		if (PageUptodate(page))
2625274f052SJens Axboe 			unlock_page(page);
2635274f052SJens Axboe 		else {
2645274f052SJens Axboe 			error = mapping->a_ops->readpage(in, page);
2655274f052SJens Axboe 
2665274f052SJens Axboe 			if (unlikely(error)) {
2675274f052SJens Axboe 				page_cache_release(page);
2685274f052SJens Axboe 				break;
2695274f052SJens Axboe 			}
2705274f052SJens Axboe 		}
2715274f052SJens Axboe 		shadow[i] = page;
2725274f052SJens Axboe 	}
2735274f052SJens Axboe 
2745274f052SJens Axboe 	if (!i) {
2755274f052SJens Axboe 		for (i = 0; i < nr_pages; i++) {
2765274f052SJens Axboe 			 if (shadow[i])
2775274f052SJens Axboe 				page_cache_release(shadow[i]);
2785274f052SJens Axboe 		}
2795274f052SJens Axboe 		return 0;
2805274f052SJens Axboe 	}
2815274f052SJens Axboe 
2825274f052SJens Axboe 	memcpy(pages, shadow, i * sizeof(struct page *));
2835274f052SJens Axboe 
2845274f052SJens Axboe 	/*
2855274f052SJens Axboe 	 * Now we splice them into the pipe..
2865274f052SJens Axboe 	 */
2875274f052SJens Axboe splice_them:
28829e35094SLinus Torvalds 	return move_to_pipe(pipe, pages, i, offset, len, flags);
2895274f052SJens Axboe }
2905274f052SJens Axboe 
2915274f052SJens Axboe ssize_t generic_file_splice_read(struct file *in, struct inode *pipe,
2925274f052SJens Axboe 				 size_t len, unsigned int flags)
2935274f052SJens Axboe {
2945274f052SJens Axboe 	ssize_t spliced;
2955274f052SJens Axboe 	int ret;
2965274f052SJens Axboe 
2975274f052SJens Axboe 	ret = 0;
2985274f052SJens Axboe 	spliced = 0;
2995274f052SJens Axboe 	while (len) {
30029e35094SLinus Torvalds 		ret = __generic_file_splice_read(in, pipe, len, flags);
3015274f052SJens Axboe 
3025274f052SJens Axboe 		if (ret <= 0)
3035274f052SJens Axboe 			break;
3045274f052SJens Axboe 
3055274f052SJens Axboe 		in->f_pos += ret;
3065274f052SJens Axboe 		len -= ret;
3075274f052SJens Axboe 		spliced += ret;
30829e35094SLinus Torvalds 
30929e35094SLinus Torvalds 		if (!(flags & SPLICE_F_NONBLOCK))
31029e35094SLinus Torvalds 			continue;
31129e35094SLinus Torvalds 		ret = -EAGAIN;
31229e35094SLinus Torvalds 		break;
3135274f052SJens Axboe 	}
3145274f052SJens Axboe 
3155274f052SJens Axboe 	if (spliced)
3165274f052SJens Axboe 		return spliced;
3175274f052SJens Axboe 
3185274f052SJens Axboe 	return ret;
3195274f052SJens Axboe }
3205274f052SJens Axboe 
3215274f052SJens Axboe /*
3225274f052SJens Axboe  * Send 'len' bytes to socket from 'file' at position 'pos' using sendpage().
3235274f052SJens Axboe  */
3245274f052SJens Axboe static int pipe_to_sendpage(struct pipe_inode_info *info,
3255274f052SJens Axboe 			    struct pipe_buffer *buf, struct splice_desc *sd)
3265274f052SJens Axboe {
3275274f052SJens Axboe 	struct file *file = sd->file;
3285274f052SJens Axboe 	loff_t pos = sd->pos;
3295274f052SJens Axboe 	unsigned int offset;
3305274f052SJens Axboe 	ssize_t ret;
3315274f052SJens Axboe 	void *ptr;
3325274f052SJens Axboe 
3335274f052SJens Axboe 	/*
3345274f052SJens Axboe 	 * sub-optimal, but we are limited by the pipe ->map. we don't
3355274f052SJens Axboe 	 * need a kmap'ed buffer here, we just want to make sure we
3365274f052SJens Axboe 	 * have the page pinned if the pipe page originates from the
3375274f052SJens Axboe 	 * page cache
3385274f052SJens Axboe 	 */
3395274f052SJens Axboe 	ptr = buf->ops->map(file, info, buf);
3405274f052SJens Axboe 	if (IS_ERR(ptr))
3415274f052SJens Axboe 		return PTR_ERR(ptr);
3425274f052SJens Axboe 
3435274f052SJens Axboe 	offset = pos & ~PAGE_CACHE_MASK;
3445274f052SJens Axboe 
3455274f052SJens Axboe 	ret = file->f_op->sendpage(file, buf->page, offset, sd->len, &pos,
3465274f052SJens Axboe 					sd->len < sd->total_len);
3475274f052SJens Axboe 
3485274f052SJens Axboe 	buf->ops->unmap(info, buf);
3495274f052SJens Axboe 	if (ret == sd->len)
3505274f052SJens Axboe 		return 0;
3515274f052SJens Axboe 
3525274f052SJens Axboe 	return -EIO;
3535274f052SJens Axboe }
3545274f052SJens Axboe 
3555274f052SJens Axboe /*
3565274f052SJens Axboe  * This is a little more tricky than the file -> pipe splicing. There are
3575274f052SJens Axboe  * basically three cases:
3585274f052SJens Axboe  *
3595274f052SJens Axboe  *	- Destination page already exists in the address space and there
3605274f052SJens Axboe  *	  are users of it. For that case we have no other option that
3615274f052SJens Axboe  *	  copying the data. Tough luck.
3625274f052SJens Axboe  *	- Destination page already exists in the address space, but there
3635274f052SJens Axboe  *	  are no users of it. Make sure it's uptodate, then drop it. Fall
3645274f052SJens Axboe  *	  through to last case.
3655274f052SJens Axboe  *	- Destination page does not exist, we can add the pipe page to
3665274f052SJens Axboe  *	  the page cache and avoid the copy.
3675274f052SJens Axboe  *
3685274f052SJens Axboe  * For now we just do the slower thing and always copy pages over, it's
3695274f052SJens Axboe  * easier than migrating pages from the pipe to the target file. For the
3705274f052SJens Axboe  * case of doing file | file splicing, the migrate approach had some LRU
3715274f052SJens Axboe  * nastiness...
3725274f052SJens Axboe  */
3735274f052SJens Axboe static int pipe_to_file(struct pipe_inode_info *info, struct pipe_buffer *buf,
3745274f052SJens Axboe 			struct splice_desc *sd)
3755274f052SJens Axboe {
3765274f052SJens Axboe 	struct file *file = sd->file;
3775274f052SJens Axboe 	struct address_space *mapping = file->f_mapping;
3785274f052SJens Axboe 	unsigned int offset;
3795274f052SJens Axboe 	struct page *page;
3805274f052SJens Axboe 	pgoff_t index;
3815abc97aaSJens Axboe 	char *src;
3825274f052SJens Axboe 	int ret;
3835274f052SJens Axboe 
3845274f052SJens Axboe 	/*
3855274f052SJens Axboe 	 * after this, page will be locked and unmapped
3865274f052SJens Axboe 	 */
3875274f052SJens Axboe 	src = buf->ops->map(file, info, buf);
3885274f052SJens Axboe 	if (IS_ERR(src))
3895274f052SJens Axboe 		return PTR_ERR(src);
3905274f052SJens Axboe 
3915274f052SJens Axboe 	index = sd->pos >> PAGE_CACHE_SHIFT;
3925274f052SJens Axboe 	offset = sd->pos & ~PAGE_CACHE_MASK;
3935274f052SJens Axboe 
3945abc97aaSJens Axboe 	/*
3955abc97aaSJens Axboe 	 * reuse buf page, if SPLICE_F_MOVE is set
3965abc97aaSJens Axboe 	 */
3975abc97aaSJens Axboe 	if (sd->flags & SPLICE_F_MOVE) {
3985abc97aaSJens Axboe 		if (buf->ops->steal(info, buf))
3995abc97aaSJens Axboe 			goto find_page;
4005abc97aaSJens Axboe 
4015abc97aaSJens Axboe 		page = buf->page;
4025abc97aaSJens Axboe 		if (add_to_page_cache_lru(page, mapping, index,
4035abc97aaSJens Axboe 						mapping_gfp_mask(mapping)))
4045abc97aaSJens Axboe 			goto find_page;
4055abc97aaSJens Axboe 	} else {
4065274f052SJens Axboe find_page:
4075274f052SJens Axboe 		ret = -ENOMEM;
4085abc97aaSJens Axboe 		page = find_or_create_page(mapping, index,
4095abc97aaSJens Axboe 						mapping_gfp_mask(mapping));
4105274f052SJens Axboe 		if (!page)
4115274f052SJens Axboe 			goto out;
4125274f052SJens Axboe 
4135274f052SJens Axboe 		/*
4145274f052SJens Axboe 		 * If the page is uptodate, it is also locked. If it isn't
4155274f052SJens Axboe 		 * uptodate, we can mark it uptodate if we are filling the
4165274f052SJens Axboe 		 * full page. Otherwise we need to read it in first...
4175274f052SJens Axboe 		 */
4185274f052SJens Axboe 		if (!PageUptodate(page)) {
4195274f052SJens Axboe 			if (sd->len < PAGE_CACHE_SIZE) {
4205274f052SJens Axboe 				ret = mapping->a_ops->readpage(file, page);
4215274f052SJens Axboe 				if (unlikely(ret))
4225274f052SJens Axboe 					goto out;
4235274f052SJens Axboe 
4245274f052SJens Axboe 				lock_page(page);
4255274f052SJens Axboe 
4265274f052SJens Axboe 				if (!PageUptodate(page)) {
4275274f052SJens Axboe 					/*
4285274f052SJens Axboe 					 * page got invalidated, repeat
4295274f052SJens Axboe 					 */
4305274f052SJens Axboe 					if (!page->mapping) {
4315274f052SJens Axboe 						unlock_page(page);
4325274f052SJens Axboe 						page_cache_release(page);
4335274f052SJens Axboe 						goto find_page;
4345274f052SJens Axboe 					}
4355274f052SJens Axboe 					ret = -EIO;
4365274f052SJens Axboe 					goto out;
4375274f052SJens Axboe 				}
4385274f052SJens Axboe 			} else {
4395274f052SJens Axboe 				WARN_ON(!PageLocked(page));
4405274f052SJens Axboe 				SetPageUptodate(page);
4415274f052SJens Axboe 			}
4425274f052SJens Axboe 		}
4435abc97aaSJens Axboe 	}
4445274f052SJens Axboe 
4455274f052SJens Axboe 	ret = mapping->a_ops->prepare_write(file, page, 0, sd->len);
4465274f052SJens Axboe 	if (ret)
4475274f052SJens Axboe 		goto out;
4485274f052SJens Axboe 
4495abc97aaSJens Axboe 	if (!buf->stolen) {
4505abc97aaSJens Axboe 		char *dst = kmap_atomic(page, KM_USER0);
4515abc97aaSJens Axboe 
4525274f052SJens Axboe 		memcpy(dst + offset, src + buf->offset, sd->len);
4535274f052SJens Axboe 		flush_dcache_page(page);
4545274f052SJens Axboe 		kunmap_atomic(dst, KM_USER0);
4555abc97aaSJens Axboe 	}
4565274f052SJens Axboe 
4575274f052SJens Axboe 	ret = mapping->a_ops->commit_write(file, page, 0, sd->len);
4585274f052SJens Axboe 	if (ret < 0)
4595274f052SJens Axboe 		goto out;
4605274f052SJens Axboe 
4615274f052SJens Axboe 	set_page_dirty(page);
4625274f052SJens Axboe 	ret = write_one_page(page, 0);
4635274f052SJens Axboe out:
4645274f052SJens Axboe 	if (ret < 0)
4655274f052SJens Axboe 		unlock_page(page);
4665abc97aaSJens Axboe 	if (!buf->stolen)
4675274f052SJens Axboe 		page_cache_release(page);
4685274f052SJens Axboe 	buf->ops->unmap(info, buf);
4695274f052SJens Axboe 	return ret;
4705274f052SJens Axboe }
4715274f052SJens Axboe 
4725274f052SJens Axboe typedef int (splice_actor)(struct pipe_inode_info *, struct pipe_buffer *,
4735274f052SJens Axboe 			   struct splice_desc *);
4745274f052SJens Axboe 
4755274f052SJens Axboe static ssize_t move_from_pipe(struct inode *inode, struct file *out,
4765274f052SJens Axboe 			      size_t len, unsigned int flags,
4775274f052SJens Axboe 			      splice_actor *actor)
4785274f052SJens Axboe {
4795274f052SJens Axboe 	struct pipe_inode_info *info;
4805274f052SJens Axboe 	int ret, do_wakeup, err;
4815274f052SJens Axboe 	struct splice_desc sd;
4825274f052SJens Axboe 
4835274f052SJens Axboe 	ret = 0;
4845274f052SJens Axboe 	do_wakeup = 0;
4855274f052SJens Axboe 
4865274f052SJens Axboe 	sd.total_len = len;
4875274f052SJens Axboe 	sd.flags = flags;
4885274f052SJens Axboe 	sd.file = out;
4895274f052SJens Axboe 	sd.pos = out->f_pos;
4905274f052SJens Axboe 
4915274f052SJens Axboe 	mutex_lock(PIPE_MUTEX(*inode));
4925274f052SJens Axboe 
4935274f052SJens Axboe 	info = inode->i_pipe;
4945274f052SJens Axboe 	for (;;) {
4955274f052SJens Axboe 		int bufs = info->nrbufs;
4965274f052SJens Axboe 
4975274f052SJens Axboe 		if (bufs) {
4985274f052SJens Axboe 			int curbuf = info->curbuf;
4995274f052SJens Axboe 			struct pipe_buffer *buf = info->bufs + curbuf;
5005274f052SJens Axboe 			struct pipe_buf_operations *ops = buf->ops;
5015274f052SJens Axboe 
5025274f052SJens Axboe 			sd.len = buf->len;
5035274f052SJens Axboe 			if (sd.len > sd.total_len)
5045274f052SJens Axboe 				sd.len = sd.total_len;
5055274f052SJens Axboe 
5065274f052SJens Axboe 			err = actor(info, buf, &sd);
5075274f052SJens Axboe 			if (err) {
5085274f052SJens Axboe 				if (!ret && err != -ENODATA)
5095274f052SJens Axboe 					ret = err;
5105274f052SJens Axboe 
5115274f052SJens Axboe 				break;
5125274f052SJens Axboe 			}
5135274f052SJens Axboe 
5145274f052SJens Axboe 			ret += sd.len;
5155274f052SJens Axboe 			buf->offset += sd.len;
5165274f052SJens Axboe 			buf->len -= sd.len;
5175274f052SJens Axboe 			if (!buf->len) {
5185274f052SJens Axboe 				buf->ops = NULL;
5195274f052SJens Axboe 				ops->release(info, buf);
5205274f052SJens Axboe 				curbuf = (curbuf + 1) & (PIPE_BUFFERS - 1);
5215274f052SJens Axboe 				info->curbuf = curbuf;
5225274f052SJens Axboe 				info->nrbufs = --bufs;
5235274f052SJens Axboe 				do_wakeup = 1;
5245274f052SJens Axboe 			}
5255274f052SJens Axboe 
5265274f052SJens Axboe 			sd.pos += sd.len;
5275274f052SJens Axboe 			sd.total_len -= sd.len;
5285274f052SJens Axboe 			if (!sd.total_len)
5295274f052SJens Axboe 				break;
5305274f052SJens Axboe 		}
5315274f052SJens Axboe 
5325274f052SJens Axboe 		if (bufs)
5335274f052SJens Axboe 			continue;
5345274f052SJens Axboe 		if (!PIPE_WRITERS(*inode))
5355274f052SJens Axboe 			break;
5365274f052SJens Axboe 		if (!PIPE_WAITING_WRITERS(*inode)) {
5375274f052SJens Axboe 			if (ret)
5385274f052SJens Axboe 				break;
5395274f052SJens Axboe 		}
5405274f052SJens Axboe 
54129e35094SLinus Torvalds 		if (flags & SPLICE_F_NONBLOCK) {
54229e35094SLinus Torvalds 			if (!ret)
54329e35094SLinus Torvalds 				ret = -EAGAIN;
54429e35094SLinus Torvalds 			break;
54529e35094SLinus Torvalds 		}
54629e35094SLinus Torvalds 
5475274f052SJens Axboe 		if (signal_pending(current)) {
5485274f052SJens Axboe 			if (!ret)
5495274f052SJens Axboe 				ret = -ERESTARTSYS;
5505274f052SJens Axboe 			break;
5515274f052SJens Axboe 		}
5525274f052SJens Axboe 
5535274f052SJens Axboe 		if (do_wakeup) {
5545274f052SJens Axboe 			wake_up_interruptible_sync(PIPE_WAIT(*inode));
5555274f052SJens Axboe 			kill_fasync(PIPE_FASYNC_WRITERS(*inode),SIGIO,POLL_OUT);
5565274f052SJens Axboe 			do_wakeup = 0;
5575274f052SJens Axboe 		}
5585274f052SJens Axboe 
5595274f052SJens Axboe 		pipe_wait(inode);
5605274f052SJens Axboe 	}
5615274f052SJens Axboe 
5625274f052SJens Axboe 	mutex_unlock(PIPE_MUTEX(*inode));
5635274f052SJens Axboe 
5645274f052SJens Axboe 	if (do_wakeup) {
5655274f052SJens Axboe 		wake_up_interruptible(PIPE_WAIT(*inode));
5665274f052SJens Axboe 		kill_fasync(PIPE_FASYNC_WRITERS(*inode), SIGIO, POLL_OUT);
5675274f052SJens Axboe 	}
5685274f052SJens Axboe 
5695274f052SJens Axboe 	mutex_lock(&out->f_mapping->host->i_mutex);
5705274f052SJens Axboe 	out->f_pos = sd.pos;
5715274f052SJens Axboe 	mutex_unlock(&out->f_mapping->host->i_mutex);
5725274f052SJens Axboe 	return ret;
5735274f052SJens Axboe 
5745274f052SJens Axboe }
5755274f052SJens Axboe 
5765274f052SJens Axboe ssize_t generic_file_splice_write(struct inode *inode, struct file *out,
5775274f052SJens Axboe 				  size_t len, unsigned int flags)
5785274f052SJens Axboe {
5795274f052SJens Axboe 	return move_from_pipe(inode, out, len, flags, pipe_to_file);
5805274f052SJens Axboe }
5815274f052SJens Axboe 
5825274f052SJens Axboe ssize_t generic_splice_sendpage(struct inode *inode, struct file *out,
5835274f052SJens Axboe 				size_t len, unsigned int flags)
5845274f052SJens Axboe {
5855274f052SJens Axboe 	return move_from_pipe(inode, out, len, flags, pipe_to_sendpage);
5865274f052SJens Axboe }
5875274f052SJens Axboe 
588a0f06780SJeff Garzik EXPORT_SYMBOL(generic_file_splice_write);
589a0f06780SJeff Garzik EXPORT_SYMBOL(generic_file_splice_read);
590a0f06780SJeff Garzik 
5915274f052SJens Axboe static long do_splice_from(struct inode *pipe, struct file *out, size_t len,
5925274f052SJens Axboe 			   unsigned int flags)
5935274f052SJens Axboe {
5945274f052SJens Axboe 	loff_t pos;
5955274f052SJens Axboe 	int ret;
5965274f052SJens Axboe 
5975274f052SJens Axboe 	if (!out->f_op || !out->f_op->splice_write)
5985274f052SJens Axboe 		return -EINVAL;
5995274f052SJens Axboe 
6005274f052SJens Axboe 	if (!(out->f_mode & FMODE_WRITE))
6015274f052SJens Axboe 		return -EBADF;
6025274f052SJens Axboe 
6035274f052SJens Axboe 	pos = out->f_pos;
6045274f052SJens Axboe 	ret = rw_verify_area(WRITE, out, &pos, len);
6055274f052SJens Axboe 	if (unlikely(ret < 0))
6065274f052SJens Axboe 		return ret;
6075274f052SJens Axboe 
6085274f052SJens Axboe 	return out->f_op->splice_write(pipe, out, len, flags);
6095274f052SJens Axboe }
6105274f052SJens Axboe 
6115274f052SJens Axboe static long do_splice_to(struct file *in, struct inode *pipe, size_t len,
6125274f052SJens Axboe 			 unsigned int flags)
6135274f052SJens Axboe {
6145274f052SJens Axboe 	loff_t pos, isize, left;
6155274f052SJens Axboe 	int ret;
6165274f052SJens Axboe 
6175274f052SJens Axboe 	if (!in->f_op || !in->f_op->splice_read)
6185274f052SJens Axboe 		return -EINVAL;
6195274f052SJens Axboe 
6205274f052SJens Axboe 	if (!(in->f_mode & FMODE_READ))
6215274f052SJens Axboe 		return -EBADF;
6225274f052SJens Axboe 
6235274f052SJens Axboe 	pos = in->f_pos;
6245274f052SJens Axboe 	ret = rw_verify_area(READ, in, &pos, len);
6255274f052SJens Axboe 	if (unlikely(ret < 0))
6265274f052SJens Axboe 		return ret;
6275274f052SJens Axboe 
6285274f052SJens Axboe 	isize = i_size_read(in->f_mapping->host);
6295274f052SJens Axboe 	if (unlikely(in->f_pos >= isize))
6305274f052SJens Axboe 		return 0;
6315274f052SJens Axboe 
6325274f052SJens Axboe 	left = isize - in->f_pos;
6335274f052SJens Axboe 	if (left < len)
6345274f052SJens Axboe 		len = left;
6355274f052SJens Axboe 
6365274f052SJens Axboe 	return in->f_op->splice_read(in, pipe, len, flags);
6375274f052SJens Axboe }
6385274f052SJens Axboe 
6395274f052SJens Axboe static long do_splice(struct file *in, struct file *out, size_t len,
6405274f052SJens Axboe 		      unsigned int flags)
6415274f052SJens Axboe {
6425274f052SJens Axboe 	struct inode *pipe;
6435274f052SJens Axboe 
6445274f052SJens Axboe 	pipe = in->f_dentry->d_inode;
6455274f052SJens Axboe 	if (pipe->i_pipe)
6465274f052SJens Axboe 		return do_splice_from(pipe, out, len, flags);
6475274f052SJens Axboe 
6485274f052SJens Axboe 	pipe = out->f_dentry->d_inode;
6495274f052SJens Axboe 	if (pipe->i_pipe)
6505274f052SJens Axboe 		return do_splice_to(in, pipe, len, flags);
6515274f052SJens Axboe 
6525274f052SJens Axboe 	return -EINVAL;
6535274f052SJens Axboe }
6545274f052SJens Axboe 
6555274f052SJens Axboe asmlinkage long sys_splice(int fdin, int fdout, size_t len, unsigned int flags)
6565274f052SJens Axboe {
6575274f052SJens Axboe 	long error;
6585274f052SJens Axboe 	struct file *in, *out;
6595274f052SJens Axboe 	int fput_in, fput_out;
6605274f052SJens Axboe 
6615274f052SJens Axboe 	if (unlikely(!len))
6625274f052SJens Axboe 		return 0;
6635274f052SJens Axboe 
6645274f052SJens Axboe 	error = -EBADF;
6655274f052SJens Axboe 	in = fget_light(fdin, &fput_in);
6665274f052SJens Axboe 	if (in) {
6675274f052SJens Axboe 		if (in->f_mode & FMODE_READ) {
6685274f052SJens Axboe 			out = fget_light(fdout, &fput_out);
6695274f052SJens Axboe 			if (out) {
6705274f052SJens Axboe 				if (out->f_mode & FMODE_WRITE)
6715274f052SJens Axboe 					error = do_splice(in, out, len, flags);
6725274f052SJens Axboe 				fput_light(out, fput_out);
6735274f052SJens Axboe 			}
6745274f052SJens Axboe 		}
6755274f052SJens Axboe 
6765274f052SJens Axboe 		fput_light(in, fput_in);
6775274f052SJens Axboe 	}
6785274f052SJens Axboe 
6795274f052SJens Axboe 	return error;
6805274f052SJens Axboe }
681