Pull xfs fixes from Darrick Wong: - fix a race between overlapping copy on write aio - fix cow fork swapping when we defragment reflinked files * tag 'xfs-4.14-fixes-4' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: handle racy AIO in xfs_reflink_end_cow xfs: always swap the cow forks when swapping extents
Unified · Split
| @@ -2122,11 +2122,31 @@ xfs_swap_extents( · 2121 unmodified lines | ||
| 2122 | 2122 | ip->i_d.di_flags2 |= tip->i_d.di_flags2 & XFS_DIFLAG2_REFLINK; |
| 2123 | 2123 | tip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; |
| 2124 | 2124 | tip->i_d.di_flags2 |= f & XFS_DIFLAG2_REFLINK; |
| 2125 | + } | |
| 2126 | + | |
| 2127 | + /* Swap the cow forks. */ | |
| 2128 | + if (xfs_sb_version_hasreflink(&mp->m_sb)) { | |
| 2129 | + xfs_extnum_t extnum; | |
| 2130 | + | |
| 2131 | + ASSERT(ip->i_cformat == XFS_DINODE_FMT_EXTENTS); | |
| 2132 | + ASSERT(tip->i_cformat == XFS_DINODE_FMT_EXTENTS); | |
| 2133 | + | |
| 2134 | + extnum = ip->i_cnextents; | |
| 2135 | + ip->i_cnextents = tip->i_cnextents; | |
| 2136 | + tip->i_cnextents = extnum; | |
| 2137 | + | |
| 2125 | 2138 | cowfp = ip->i_cowfp; |
| 2126 | 2139 | ip->i_cowfp = tip->i_cowfp; |
| 2127 | 2140 | tip->i_cowfp = cowfp; |
| 2128 | − xfs_inode_set_cowblocks_tag(ip); | |
| 2129 | − xfs_inode_set_cowblocks_tag(tip); | |
| 2141 | + | |
| 2142 | + if (ip->i_cowfp && ip->i_cnextents) | |
| 2143 | + xfs_inode_set_cowblocks_tag(ip); | |
| 2144 | + else | |
| 2145 | + xfs_inode_clear_cowblocks_tag(ip); | |
| 2146 | + if (tip->i_cowfp && tip->i_cnextents) | |
| 2147 | + xfs_inode_set_cowblocks_tag(tip); | |
| 2148 | + else | |
| 2149 | + xfs_inode_clear_cowblocks_tag(tip); | |
| 2130 | 2150 | } |
| 2131 | 2151 | |
| 2132 | 2152 | xfs_trans_log_inode(tp, ip, src_log_flags); |
| @@ -736,7 +736,13 @@ xfs_reflink_end_cow( · 735 unmodified lines | ||
| 736 | 736 | /* If there is a hole at end_fsb - 1 go to the previous extent */ |
| 737 | 737 | if (!xfs_iext_lookup_extent(ip, ifp, end_fsb - 1, &idx, &got) || |
| 738 | 738 | got.br_startoff > end_fsb) { |
| 739 | − ASSERT(idx > 0); | |
| 739 | + /* | |
| 740 | + * In case of racing, overlapping AIO writes no COW extents | |
| 741 | + * might be left by the time I/O completes for the loser of | |
| 742 | + * the race. In that case we are done. | |
| 743 | + */ | |
| 744 | + if (idx <= 0) | |
| 745 | + goto out_cancel; | |
| 740 | 746 | xfs_iext_get_extent(ifp, --idx, &got); |
| 741 | 747 | } |
| 742 | 748 | |
| @@ -809,6 +815,7 @@ next_extent: · 66 unmodified lines | ||
| 809 | 815 | |
| 810 | 816 | out_defer: |
| 811 | 817 | xfs_defer_cancel(&dfops); |
| 818 | +out_cancel: | |
| 812 | 819 | xfs_trans_cancel(tp); |
| 813 | 820 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
| 814 | 821 | out: |