aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/file.c
diff options
context:
space:
mode:
authorMark Fasheh <mark.fasheh@oracle.com>2007-03-06 20:24:46 -0500
committerMark Fasheh <mark.fasheh@oracle.com>2007-04-26 18:02:34 -0400
commit6af67d8205cf65fbaaa743edc7ebb46e486e34ff (patch)
tree1aadef5c71e4f8905477a813b1bd0a35e62ccbee /fs/ocfs2/file.c
parentfa41045fcbf78269991d5aebb1820fc51534f05d (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.c80
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
1606static 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;
1653out:
1654
1655 return total ? total : ret;
1656}
1657
1658static 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
1606static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, 1684static 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
1638out_unlock: 1716out_unlock:
1639 ocfs2_rw_unlock(inode, 1); 1717 ocfs2_rw_unlock(inode, 1);