diff options
author | Mark Fasheh <mark.fasheh@oracle.com> | 2007-03-06 20:24:46 -0500 |
---|---|---|
committer | Mark Fasheh <mark.fasheh@oracle.com> | 2007-04-26 18:02:34 -0400 |
commit | 6af67d8205cf65fbaaa743edc7ebb46e486e34ff (patch) | |
tree | 1aadef5c71e4f8905477a813b1bd0a35e62ccbee /fs/ocfs2/file.c | |
parent | fa41045fcbf78269991d5aebb1820fc51534f05d (diff) |
ocfs2: Use own splice write actor
We need to fill holes during a splice write. Provide our own splice write
actor which can call ocfs2_file_buffered_write() with a splice-specific
callback.
Signed-off-by: Mark Fasheh <mark.fasheh@oracle.com>
Diffstat (limited to 'fs/ocfs2/file.c')
-rw-r--r-- | fs/ocfs2/file.c | 80 |
1 files changed, 79 insertions, 1 deletions
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c index 5fd49ec169dc..f516619a3744 100644 --- a/fs/ocfs2/file.c +++ b/fs/ocfs2/file.c | |||
@@ -1603,6 +1603,84 @@ out_sems: | |||
1603 | return written ? written : ret; | 1603 | return written ? written : ret; |
1604 | } | 1604 | } |
1605 | 1605 | ||
1606 | static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe, | ||
1607 | struct pipe_buffer *buf, | ||
1608 | struct splice_desc *sd) | ||
1609 | { | ||
1610 | int ret, count, total = 0; | ||
1611 | ssize_t copied = 0; | ||
1612 | struct ocfs2_splice_write_priv sp; | ||
1613 | |||
1614 | ret = buf->ops->pin(pipe, buf); | ||
1615 | if (ret) | ||
1616 | goto out; | ||
1617 | |||
1618 | sp.s_sd = sd; | ||
1619 | sp.s_buf = buf; | ||
1620 | sp.s_pipe = pipe; | ||
1621 | sp.s_offset = sd->pos & ~PAGE_CACHE_MASK; | ||
1622 | sp.s_buf_offset = buf->offset; | ||
1623 | |||
1624 | count = sd->len; | ||
1625 | if (count + sp.s_offset > PAGE_CACHE_SIZE) | ||
1626 | count = PAGE_CACHE_SIZE - sp.s_offset; | ||
1627 | |||
1628 | do { | ||
1629 | /* | ||
1630 | * splice wants us to copy up to one page at a | ||
1631 | * time. For pagesize > cluster size, this means we | ||
1632 | * might enter ocfs2_buffered_write_cluster() more | ||
1633 | * than once, so keep track of our progress here. | ||
1634 | */ | ||
1635 | copied = ocfs2_buffered_write_cluster(sd->file, | ||
1636 | (loff_t)sd->pos + total, | ||
1637 | count, | ||
1638 | ocfs2_map_and_write_splice_data, | ||
1639 | &sp); | ||
1640 | if (copied < 0) { | ||
1641 | mlog_errno(copied); | ||
1642 | ret = copied; | ||
1643 | goto out; | ||
1644 | } | ||
1645 | |||
1646 | count -= copied; | ||
1647 | sp.s_offset += copied; | ||
1648 | sp.s_buf_offset += copied; | ||
1649 | total += copied; | ||
1650 | } while (count); | ||
1651 | |||
1652 | ret = 0; | ||
1653 | out: | ||
1654 | |||
1655 | return total ? total : ret; | ||
1656 | } | ||
1657 | |||
1658 | static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe, | ||
1659 | struct file *out, | ||
1660 | loff_t *ppos, | ||
1661 | size_t len, | ||
1662 | unsigned int flags) | ||
1663 | { | ||
1664 | int ret, err; | ||
1665 | struct address_space *mapping = out->f_mapping; | ||
1666 | struct inode *inode = mapping->host; | ||
1667 | |||
1668 | ret = __splice_from_pipe(pipe, out, ppos, len, flags, | ||
1669 | ocfs2_splice_write_actor); | ||
1670 | if (ret > 0) { | ||
1671 | *ppos += ret; | ||
1672 | |||
1673 | if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) { | ||
1674 | err = generic_osync_inode(inode, mapping, | ||
1675 | OSYNC_METADATA|OSYNC_DATA); | ||
1676 | if (err) | ||
1677 | ret = err; | ||
1678 | } | ||
1679 | } | ||
1680 | |||
1681 | return ret; | ||
1682 | } | ||
1683 | |||
1606 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | 1684 | static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, |
1607 | struct file *out, | 1685 | struct file *out, |
1608 | loff_t *ppos, | 1686 | loff_t *ppos, |
@@ -1633,7 +1711,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, | |||
1633 | } | 1711 | } |
1634 | 1712 | ||
1635 | /* ok, we're done with i_size and alloc work */ | 1713 | /* ok, we're done with i_size and alloc work */ |
1636 | ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags); | 1714 | ret = __ocfs2_file_splice_write(pipe, out, ppos, len, flags); |
1637 | 1715 | ||
1638 | out_unlock: | 1716 | out_unlock: |
1639 | ocfs2_rw_unlock(inode, 1); | 1717 | ocfs2_rw_unlock(inode, 1); |