summaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/aops.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/aops.c')
-rw-r--r--fs/ocfs2/aops.c155
1 files changed, 141 insertions, 14 deletions
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index e1bf18c5d25e..8d2bc840c288 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -664,6 +664,117 @@ static int ocfs2_is_overwrite(struct ocfs2_super *osb,
664 return 0; 664 return 0;
665} 665}
666 666
667static int ocfs2_direct_IO_zero_extend(struct ocfs2_super *osb,
668 struct inode *inode, loff_t offset,
669 u64 zero_len, int cluster_align)
670{
671 u32 p_cpos = 0;
672 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, i_size_read(inode));
673 unsigned int num_clusters = 0;
674 unsigned int ext_flags = 0;
675 int ret = 0;
676
677 if (offset <= i_size_read(inode) || cluster_align)
678 return 0;
679
680 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos, &num_clusters,
681 &ext_flags);
682 if (ret < 0) {
683 mlog_errno(ret);
684 return ret;
685 }
686
687 if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
688 u64 s = i_size_read(inode);
689 sector_t sector = (p_cpos << (osb->s_clustersize_bits - 9)) +
690 (do_div(s, osb->s_clustersize) >> 9);
691
692 ret = blkdev_issue_zeroout(osb->sb->s_bdev, sector,
693 zero_len >> 9, GFP_NOFS, false);
694 if (ret < 0)
695 mlog_errno(ret);
696 }
697
698 return ret;
699}
700
701static int ocfs2_direct_IO_extend_no_holes(struct ocfs2_super *osb,
702 struct inode *inode, loff_t offset)
703{
704 u64 zero_start, zero_len, total_zero_len;
705 u32 p_cpos = 0, clusters_to_add;
706 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, i_size_read(inode));
707 unsigned int num_clusters = 0;
708 unsigned int ext_flags = 0;
709 u32 size_div, offset_div;
710 int ret = 0;
711
712 {
713 u64 o = offset;
714 u64 s = i_size_read(inode);
715
716 offset_div = do_div(o, osb->s_clustersize);
717 size_div = do_div(s, osb->s_clustersize);
718 }
719
720 if (offset <= i_size_read(inode))
721 return 0;
722
723 clusters_to_add = ocfs2_bytes_to_clusters(inode->i_sb, offset) -
724 ocfs2_bytes_to_clusters(inode->i_sb, i_size_read(inode));
725 total_zero_len = offset - i_size_read(inode);
726 if (clusters_to_add)
727 total_zero_len -= offset_div;
728
729 /* Allocate clusters to fill out holes, and this is only needed
730 * when we add more than one clusters. Otherwise the cluster will
731 * be allocated during direct IO */
732 if (clusters_to_add > 1) {
733 ret = ocfs2_extend_allocation(inode,
734 OCFS2_I(inode)->ip_clusters,
735 clusters_to_add - 1, 0);
736 if (ret) {
737 mlog_errno(ret);
738 goto out;
739 }
740 }
741
742 while (total_zero_len) {
743 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos, &num_clusters,
744 &ext_flags);
745 if (ret < 0) {
746 mlog_errno(ret);
747 goto out;
748 }
749
750 zero_start = ocfs2_clusters_to_bytes(osb->sb, p_cpos) +
751 size_div;
752 zero_len = ocfs2_clusters_to_bytes(osb->sb, num_clusters) -
753 size_div;
754 zero_len = min(total_zero_len, zero_len);
755
756 if (p_cpos && !(ext_flags & OCFS2_EXT_UNWRITTEN)) {
757 ret = blkdev_issue_zeroout(osb->sb->s_bdev,
758 zero_start >> 9, zero_len >> 9,
759 GFP_NOFS, false);
760 if (ret < 0) {
761 mlog_errno(ret);
762 goto out;
763 }
764 }
765
766 total_zero_len -= zero_len;
767 v_cpos += ocfs2_bytes_to_clusters(osb->sb, zero_len + size_div);
768
769 /* Only at first iteration can be cluster not aligned.
770 * So set size_div to 0 for the rest */
771 size_div = 0;
772 }
773
774out:
775 return ret;
776}
777
667static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb, 778static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
668 struct iov_iter *iter, 779 struct iov_iter *iter,
669 loff_t offset) 780 loff_t offset)
@@ -678,8 +789,8 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
678 struct buffer_head *di_bh = NULL; 789 struct buffer_head *di_bh = NULL;
679 size_t count = iter->count; 790 size_t count = iter->count;
680 journal_t *journal = osb->journal->j_journal; 791 journal_t *journal = osb->journal->j_journal;
681 u32 zero_len; 792 u64 zero_len_head, zero_len_tail;
682 int cluster_align; 793 int cluster_align_head, cluster_align_tail;
683 loff_t final_size = offset + count; 794 loff_t final_size = offset + count;
684 int append_write = offset >= i_size_read(inode) ? 1 : 0; 795 int append_write = offset >= i_size_read(inode) ? 1 : 0;
685 unsigned int num_clusters = 0; 796 unsigned int num_clusters = 0;
@@ -687,9 +798,16 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
687 798
688 { 799 {
689 u64 o = offset; 800 u64 o = offset;
801 u64 s = i_size_read(inode);
802
803 zero_len_head = do_div(o, 1 << osb->s_clustersize_bits);
804 cluster_align_head = !zero_len_head;
690 805
691 zero_len = do_div(o, 1 << osb->s_clustersize_bits); 806 zero_len_tail = osb->s_clustersize -
692 cluster_align = !zero_len; 807 do_div(s, osb->s_clustersize);
808 if ((offset - i_size_read(inode)) < zero_len_tail)
809 zero_len_tail = offset - i_size_read(inode);
810 cluster_align_tail = !zero_len_tail;
693 } 811 }
694 812
695 /* 813 /*
@@ -707,21 +825,23 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
707 } 825 }
708 826
709 if (append_write) { 827 if (append_write) {
710 ret = ocfs2_inode_lock(inode, &di_bh, 1); 828 ret = ocfs2_inode_lock(inode, NULL, 1);
711 if (ret < 0) { 829 if (ret < 0) {
712 mlog_errno(ret); 830 mlog_errno(ret);
713 goto clean_orphan; 831 goto clean_orphan;
714 } 832 }
715 833
834 /* zeroing out the previously allocated cluster tail
835 * that but not zeroed */
716 if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb))) 836 if (ocfs2_sparse_alloc(OCFS2_SB(inode->i_sb)))
717 ret = ocfs2_zero_extend(inode, di_bh, offset); 837 ret = ocfs2_direct_IO_zero_extend(osb, inode, offset,
838 zero_len_tail, cluster_align_tail);
718 else 839 else
719 ret = ocfs2_extend_no_holes(inode, di_bh, offset, 840 ret = ocfs2_direct_IO_extend_no_holes(osb, inode,
720 offset); 841 offset);
721 if (ret < 0) { 842 if (ret < 0) {
722 mlog_errno(ret); 843 mlog_errno(ret);
723 ocfs2_inode_unlock(inode, 1); 844 ocfs2_inode_unlock(inode, 1);
724 brelse(di_bh);
725 goto clean_orphan; 845 goto clean_orphan;
726 } 846 }
727 847
@@ -729,13 +849,10 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
729 if (is_overwrite < 0) { 849 if (is_overwrite < 0) {
730 mlog_errno(is_overwrite); 850 mlog_errno(is_overwrite);
731 ocfs2_inode_unlock(inode, 1); 851 ocfs2_inode_unlock(inode, 1);
732 brelse(di_bh);
733 goto clean_orphan; 852 goto clean_orphan;
734 } 853 }
735 854
736 ocfs2_inode_unlock(inode, 1); 855 ocfs2_inode_unlock(inode, 1);
737 brelse(di_bh);
738 di_bh = NULL;
739 } 856 }
740 857
741 written = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev, 858 written = __blockdev_direct_IO(WRITE, iocb, inode, inode->i_sb->s_bdev,
@@ -772,15 +889,23 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
772 if (ret < 0) 889 if (ret < 0)
773 mlog_errno(ret); 890 mlog_errno(ret);
774 } 891 }
775 } else if (written < 0 && append_write && !is_overwrite && 892 } else if (written > 0 && append_write && !is_overwrite &&
776 !cluster_align) { 893 !cluster_align_head) {
894 /* zeroing out the allocated cluster head */
777 u32 p_cpos = 0; 895 u32 p_cpos = 0;
778 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset); 896 u32 v_cpos = ocfs2_bytes_to_clusters(osb->sb, offset);
779 897
898 ret = ocfs2_inode_lock(inode, NULL, 0);
899 if (ret < 0) {
900 mlog_errno(ret);
901 goto clean_orphan;
902 }
903
780 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos, 904 ret = ocfs2_get_clusters(inode, v_cpos, &p_cpos,
781 &num_clusters, &ext_flags); 905 &num_clusters, &ext_flags);
782 if (ret < 0) { 906 if (ret < 0) {
783 mlog_errno(ret); 907 mlog_errno(ret);
908 ocfs2_inode_unlock(inode, 0);
784 goto clean_orphan; 909 goto clean_orphan;
785 } 910 }
786 911
@@ -788,9 +913,11 @@ static ssize_t ocfs2_direct_IO_write(struct kiocb *iocb,
788 913
789 ret = blkdev_issue_zeroout(osb->sb->s_bdev, 914 ret = blkdev_issue_zeroout(osb->sb->s_bdev,
790 p_cpos << (osb->s_clustersize_bits - 9), 915 p_cpos << (osb->s_clustersize_bits - 9),
791 zero_len >> 9, GFP_KERNEL, false); 916 zero_len_head >> 9, GFP_NOFS, false);
792 if (ret < 0) 917 if (ret < 0)
793 mlog_errno(ret); 918 mlog_errno(ret);
919
920 ocfs2_inode_unlock(inode, 0);
794 } 921 }
795 922
796clean_orphan: 923clean_orphan: