splice.c (f4e6b498d6e06742d72706ef50593a9c4dd72214) | splice.c (afddba49d18f346e5cc2938b6ed7c512db18ca68) |
---|---|
1/* 2 * "splice": joining two ropes together by interweaving their strands. 3 * 4 * This is the "extended pipe" functionality, where a pipe is used as 5 * an arbitrary in-memory buffer. Think of a pipe as a small kernel 6 * buffer that you can use to transfer data from one end to the other. 7 * 8 * The traditional unix read/write is extended with a "splice()" operation --- 549 unchanged lines hidden (view full) --- 558 */ 559static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, 560 struct splice_desc *sd) 561{ 562 struct file *file = sd->u.file; 563 struct address_space *mapping = file->f_mapping; 564 unsigned int offset, this_len; 565 struct page *page; | 1/* 2 * "splice": joining two ropes together by interweaving their strands. 3 * 4 * This is the "extended pipe" functionality, where a pipe is used as 5 * an arbitrary in-memory buffer. Think of a pipe as a small kernel 6 * buffer that you can use to transfer data from one end to the other. 7 * 8 * The traditional unix read/write is extended with a "splice()" operation --- 549 unchanged lines hidden (view full) --- 558 */ 559static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf, 560 struct splice_desc *sd) 561{ 562 struct file *file = sd->u.file; 563 struct address_space *mapping = file->f_mapping; 564 unsigned int offset, this_len; 565 struct page *page; |
566 pgoff_t index; | 566 void *fsdata; |
567 int ret; 568 569 /* 570 * make sure the data in this buffer is uptodate 571 */ 572 ret = buf->ops->confirm(pipe, buf); 573 if (unlikely(ret)) 574 return ret; 575 | 567 int ret; 568 569 /* 570 * make sure the data in this buffer is uptodate 571 */ 572 ret = buf->ops->confirm(pipe, buf); 573 if (unlikely(ret)) 574 return ret; 575 |
576 index = sd->pos >> PAGE_CACHE_SHIFT; | |
577 offset = sd->pos & ~PAGE_CACHE_MASK; 578 579 this_len = sd->len; 580 if (this_len + offset > PAGE_CACHE_SIZE) 581 this_len = PAGE_CACHE_SIZE - offset; 582 | 576 offset = sd->pos & ~PAGE_CACHE_MASK; 577 578 this_len = sd->len; 579 if (this_len + offset > PAGE_CACHE_SIZE) 580 this_len = PAGE_CACHE_SIZE - offset; 581 |
583find_page: 584 page = find_lock_page(mapping, index); 585 if (!page) { 586 ret = -ENOMEM; 587 page = page_cache_alloc_cold(mapping); 588 if (unlikely(!page)) 589 goto out_ret; | 582 ret = pagecache_write_begin(file, mapping, sd->pos, this_len, 583 AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata); 584 if (unlikely(ret)) 585 goto out; |
590 | 586 |
591 /* 592 * This will also lock the page 593 */ 594 ret = add_to_page_cache_lru(page, mapping, index, 595 GFP_KERNEL); 596 if (unlikely(ret)) 597 goto out_release; 598 } 599 600 ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len); 601 if (unlikely(ret)) { 602 loff_t isize = i_size_read(mapping->host); 603 604 if (ret != AOP_TRUNCATED_PAGE) 605 unlock_page(page); 606 page_cache_release(page); 607 if (ret == AOP_TRUNCATED_PAGE) 608 goto find_page; 609 610 /* 611 * prepare_write() may have instantiated a few blocks 612 * outside i_size. Trim these off again. 613 */ 614 if (sd->pos + this_len > isize) 615 vmtruncate(mapping->host, isize); 616 617 goto out_ret; 618 } 619 | |
620 if (buf->page != page) { 621 /* 622 * Careful, ->map() uses KM_USER0! 623 */ 624 char *src = buf->ops->map(pipe, buf, 1); 625 char *dst = kmap_atomic(page, KM_USER1); 626 627 memcpy(dst + offset, src + buf->offset, this_len); 628 flush_dcache_page(page); 629 kunmap_atomic(dst, KM_USER1); 630 buf->ops->unmap(pipe, buf, src); 631 } | 587 if (buf->page != page) { 588 /* 589 * Careful, ->map() uses KM_USER0! 590 */ 591 char *src = buf->ops->map(pipe, buf, 1); 592 char *dst = kmap_atomic(page, KM_USER1); 593 594 memcpy(dst + offset, src + buf->offset, this_len); 595 flush_dcache_page(page); 596 kunmap_atomic(dst, KM_USER1); 597 buf->ops->unmap(pipe, buf, src); 598 } |
632 633 ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); 634 if (ret) { 635 if (ret == AOP_TRUNCATED_PAGE) { 636 page_cache_release(page); 637 goto find_page; 638 } 639 if (ret < 0) 640 goto out; 641 /* 642 * Partial write has happened, so 'ret' already initialized by 643 * number of bytes written, Where is nothing we have to do here. 644 */ 645 } else 646 ret = this_len; 647 /* 648 * Return the number of bytes written and mark page as 649 * accessed, we are now done! 650 */ 651 mark_page_accessed(page); | 599 ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len, 600 page, fsdata); |
652out: | 601out: |
653 unlock_page(page); 654out_release: 655 page_cache_release(page); 656out_ret: | |
657 return ret; 658} 659 660/** 661 * __splice_from_pipe - splice data from a pipe to given actor 662 * @pipe: pipe to splice from 663 * @sd: information to @actor 664 * @actor: handler that splices the data --- 1130 unchanged lines hidden --- | 602 return ret; 603} 604 605/** 606 * __splice_from_pipe - splice data from a pipe to given actor 607 * @pipe: pipe to splice from 608 * @sd: information to @actor 609 * @actor: handler that splices the data --- 1130 unchanged lines hidden --- |