aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.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/aops.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/aops.c')
-rw-r--r--fs/ocfs2/aops.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 605c82a93f01..014f4f52809c 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -25,6 +25,7 @@
25#include <linux/pagemap.h> 25#include <linux/pagemap.h>
26#include <asm/byteorder.h> 26#include <asm/byteorder.h>
27#include <linux/swap.h> 27#include <linux/swap.h>
28#include <linux/pipe_fs_i.h>
28 29
29#define MLOG_MASK_PREFIX ML_FILE_IO 30#define MLOG_MASK_PREFIX ML_FILE_IO
30#include <cluster/masklog.h> 31#include <cluster/masklog.h>
@@ -749,6 +750,74 @@ next_bh:
749} 750}
750 751
751/* 752/*
753 * This will copy user data from the buffer page in the splice
754 * context.
755 *
756 * For now, we ignore SPLICE_F_MOVE as that would require some extra
757 * communication out all the way to ocfs2_write().
758 */
759int ocfs2_map_and_write_splice_data(struct inode *inode,
760 struct ocfs2_write_ctxt *wc, u64 *p_blkno,
761 unsigned int *ret_from, unsigned int *ret_to)
762{
763 int ret;
764 unsigned int to, from, cluster_start, cluster_end;
765 char *src, *dst;
766 struct ocfs2_splice_write_priv *sp = wc->w_private;
767 struct pipe_buffer *buf = sp->s_buf;
768 unsigned long bytes, src_from;
769 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
770
771 ocfs2_figure_cluster_boundaries(osb, wc->w_cpos, &cluster_start,
772 &cluster_end);
773
774 from = sp->s_offset;
775 src_from = sp->s_buf_offset;
776 bytes = wc->w_count;
777
778 if (wc->w_large_pages) {
779 /*
780 * For cluster size < page size, we have to
781 * calculate pos within the cluster and obey
782 * the rightmost boundary.
783 */
784 bytes = min(bytes, (unsigned long)(osb->s_clustersize
785 - (wc->w_pos & (osb->s_clustersize - 1))));
786 }
787 to = from + bytes;
788
789 if (wc->w_this_page_new)
790 ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode,
791 cluster_start, cluster_end, 1);
792 else
793 ret = ocfs2_map_page_blocks(wc->w_this_page, p_blkno, inode,
794 from, to, 0);
795 if (ret) {
796 mlog_errno(ret);
797 goto out;
798 }
799
800 BUG_ON(from > PAGE_CACHE_SIZE);
801 BUG_ON(to > PAGE_CACHE_SIZE);
802 BUG_ON(from > osb->s_clustersize);
803 BUG_ON(to > osb->s_clustersize);
804
805 src = buf->ops->map(sp->s_pipe, buf, 1);
806 dst = kmap_atomic(wc->w_this_page, KM_USER1);
807 memcpy(dst + from, src + src_from, bytes);
808 kunmap_atomic(wc->w_this_page, KM_USER1);
809 buf->ops->unmap(sp->s_pipe, buf, src);
810
811 wc->w_finished_copy = 1;
812
813 *ret_from = from;
814 *ret_to = to;
815out:
816
817 return bytes ? (unsigned int)bytes : ret;
818}
819
820/*
752 * This will copy user data from the iovec in the buffered write 821 * This will copy user data from the iovec in the buffered write
753 * context. 822 * context.
754 */ 823 */