aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2
diff options
context:
space:
mode:
authorJoseph Qi <joseph.qi@huawei.com>2015-04-14 18:43:13 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-04-14 19:48:57 -0400
commit14a5275d8c31ba24832f45eeb2469e835ded660d (patch)
tree91f7ea53e0fcfa73088ca9b71af6aac4610b5321 /fs/ocfs2
parent37a8d89aee2a5b58812e19520d96632efe987f54 (diff)
ocfs2: do not use ocfs2_zero_extend during direct IO
In ocfs2_direct_IO_write, we use ocfs2_zero_extend to zero allocated clusters in case of cluster not aligned. But ocfs2_zero_extend uses page cache, this may happen that it clears the data which blockdev_direct_IO has already written. We should use blkdev_issue_zeroout instead of ocfs2_zero_extend during direct IO. So fix this issue by introducing ocfs2_direct_IO_zero_extend and ocfs2_direct_IO_extend_no_holes. Reported-by: Yiwen Jiang <jiangyiwen@huawei.com> Signed-off-by: Joseph Qi <joseph.qi@huawei.com> Tested-by: Yiwen Jiang <jiangyiwen@huawei.com> Cc: Mark Fasheh <mfasheh@suse.com> Cc: Joel Becker <jlbec@evilplan.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r--fs/ocfs2/aops.c138
1 files changed, 130 insertions, 8 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 973a636285d1..1b0463a92b17 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -663,6 +663,117 @@ static int ocfs2_is_overwrite(struct ocfs2_super *osb,
663 return 0; 663 return 0;
664} 664}
665 665
666static int ocfs2_direct_IO_zero_extend(struct ocfs2_super *osb,
667 struct inode *inode, loff_t offset,
668 u64 zero_len, int cluster_align)
669{
670 u32 p_cpos = 0;
671 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, i_size_read(inode));
672 unsigned int num_clusters = 0;
673 unsigned int ext_flags = 0;
674 int ret = 0;
675
676 if (offset <= i_size_read(inode) || cluster_align)
677 return 0;
678
679 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos, &num_clusters,
680 &ext_flags);
681 if (ret < 0) {
682 mlog_errno(ret);
683 return ret;
684 }
685
686 if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
687 u64 s = i_size_read(inode);
688 sector_t sector = (p_cpos << (osb->s_clustersize_bits - 9)) +
689 (do_div(s, osb->s_clustersize) >> 9);
690
691 ret = blkdev_issue_zeroout(osb->sb->s_bdev, sector,
692 zero_len >> 9, GFP_NOFS, false);
693 if (ret < 0)
694 mlog_errno(ret);
695 }
696
697 return ret;
698}
699
700static int ocfs2_direct_IO_extend_no_holes(struct ocfs2_super *osb,
701 struct inode *inode, loff_t offset)
702{
703 u64 zero_start, zero_len, total_zero_len;
704 u32 p_cpos = 0, clusters_to_add;
705 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, i_size_read(inode));
706 unsigned int num_clusters = 0;
707 unsigned int ext_flags = 0;
708 u32 size_div, offset_div;
709 int ret = 0;
710
711 {
712 u64 o = offset;
713 u64 s = i_size_read(inode);
714
715 offset_div = do_div(o, osb->s_clustersize);
716 size_div = do_div(s, osb->s_clustersize);
717 }
718
719 if (offset <= i_size_read(inode))
720 return 0;
721
722 clusters_to_add = ocfs2_bytes_to_clusters(inode->i_sb, offset) -
723 ocfs2_bytes_to_clusters(inode->i_sb, i_size_read(inode));
724 total_zero_len = offset - i_size_read(inode);
725 if (clusters_to_add)
726 total_zero_len -= offset_div;
727
728 /* Allocate clusters to fill out holes, and this is only needed
729 * when we add more than one clusters. Otherwise the cluster will
730 * be allocated during direct IO */
731 if (clusters_to_add > 1) {
732 ret = ocfs2_extend_allocation(inode,
733 OCFS2_I(inode)->ip_clusters,
734 clusters_to_add - 1, 0);
735 if (ret) {
736 mlog_errno(ret);
737 goto out;
738 }
739 }
740
741 while (total_zero_len) {
742 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos, &num_clusters,
743 &ext_flags);
744 if (ret < 0) {
745 mlog_errno(ret);
746 goto out;
747 }
748
749 zero_start = ocfs2_clusters_to_bytes(osb->sb, p_cpos) +
750 size_div;
751 zero_len = ocfs2_clusters_to_bytes(osb->sb, num_clusters) -
752 size_div;
753 zero_len = min(total_zero_len, zero_len);
754
755 if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
756 ret = blkdev_issue_zeroout(osb->sb->s_bdev,
757 zero_start >> 9, zero_len >> 9,
758 GFP_NOFS, false);
759 if (ret < 0) {
760 mlog_errno(ret);
761 goto out;
762 }
763 }
764
765 total_zero_len -= zero_len;
766 v_cpos += ocfs2_bytes_to_clusters(osb->sb, zero_len + size_div);
767
768 /* Only at first iteration can be cluster not aligned.
769 * So set size_div to 0 for the rest */
770 size_div = 0;
771 }
772
773out:
774 return ret;
775}
776
666static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb, 777static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
667 struct iov_iter *iter, 778 struct iov_iter *iter,
668 loff_t offset) 779 loff_t offset)
@@ -677,8 +788,8 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
677 struct buffer_head *di_bh = NULL; 788 struct buffer_head *di_bh = NULL;
678 size_t count = iter->count; 789 size_t count = iter->count;
679 journal_t *journal = osb->journal->j_journal; 790 journal_t *journal = osb->journal->j_journal;
680 u32 zero_len; 791 u64 zero_len_head, zero_len_tail;
681 int cluster_align; 792 int cluster_align_head, cluster_align_tail;
682 loff_t final_size = offset + count; 793 loff_t final_size = offset + count;
683 int append_write = offset >= i_size_read(inode) ? 1 : 0; 794 int append_write = offset >= i_size_read(inode) ? 1 : 0;
684 unsigned int num_clusters = 0; 795 unsigned int num_clusters = 0;
@@ -686,9 +797,16 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
686 797
687 { 798 {
688 u64 o = offset; 799 u64 o = offset;
800 u64 s = i_size_read(inode);
801
802 zero_len_head = do_div(o, 1 << osb->s_clustersize_bits);
803 cluster_align_head = !zero_len_head;
689 804
690 zero_len = do_div(o, 1 << osb->s_clustersize_bits); 805 zero_len_tail = osb->s_clustersize -
691 cluster_align = !zero_len; 806 do_div(s, osb->s_clustersize);
807 if ((offset - i_size_read(inode)) < zero_len_tail)
808 zero_len_tail = offset - i_size_read(inode);
809 cluster_align_tail = !zero_len_tail;
692 } 810 }
693 811
694 /* 812 /*
@@ -712,10 +830,13 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
712 goto clean_orphan; 830 goto clean_orphan;
713 } 831 }
714 832
833 /* zeroing out the previously allocated cluster tail
834 * that but not zeroed */
715 if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) 835 if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
716 ret = ocfs2_zero_extend(inode, di_bh, offset); 836 ret = ocfs2_direct_IO_zero_extend(osb, inode, offset,
837 zero_len_tail, cluster_align_tail);
717 else 838 else
718 ret = ocfs2_extend_no_holes(inode, di_bh, offset, 839 ret = ocfs2_direct_IO_extend_no_holes(osb, inode,
719 offset); 840 offset);
720 if (ret < 0) { 841 if (ret < 0) {
721 mlog_errno(ret); 842 mlog_errno(ret);
@@ -768,7 +889,8 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
768 mlog_errno(ret); 889 mlog_errno(ret);
769 } 890 }
770 } else if (written > 0 && append_write && !is_overwrite && 891 } else if (written > 0 && append_write && !is_overwrite &&
771 !cluster_align) { 892 !cluster_align_head) {
893 /* zeroing out the allocated cluster head */
772 u32 p_cpos = 0; 894 u32 p_cpos = 0;
773 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset); 895 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset);
774 896
@@ -790,7 +912,7 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
790 912
791 ret = blkdev_issue_zeroout(osb->sb->s_bdev, 913 ret = blkdev_issue_zeroout(osb->sb->s_bdev,
792 p_cpos << (osb->s_clustersize_bits - 9), 914 p_cpos << (osb->s_clustersize_bits - 9),
793 zero_len >> 9, GFP_NOFS, false); 915 zero_len_head >> 9, GFP_NOFS, false);
794 if (ret < 0) 916 if (ret < 0)
795 mlog_errno(ret); 917 mlog_errno(ret);
796 918