diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2017-09-18 19:41:16 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-27 11:38:08 +0300 |
commit | 4e9de11c237724140c0ae14ead598c7fbc2847bd (patch) | |
tree | 166006019535bd6fb3e00a403adbb1db0ce8907d | |
parent | 13c5e97701091f9b02ded0c68809f8a6b08c747a (diff) | |
download | linux-4e9de11c237724140c0ae14ead598c7fbc2847bd.tar.xz |
xfs: don't unconditionally clear the reflink flag on zero-block files
commit cc6f77710a6de6210f9feda7cd53e2f5ee7a7e69 upstream.
If we have speculative cow preallocations hanging around in the cow
fork, don't let a truncate operation clear the reflink flag because if
we do then there's a chance we'll forget to free those extents when we
destroy the incore inode.
Reported-by: Amir Goldstein <amir73il@gmail.com>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | fs/xfs/xfs_inode.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index 9e795ab08a53..fe9a9a183b2d 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c @@ -1632,10 +1632,12 @@ xfs_itruncate_extents( goto out; /* - * Clear the reflink flag if we truncated everything. + * Clear the reflink flag if there are no data fork blocks and + * there are no extents staged in the cow fork. */ - if (ip->i_d.di_nblocks == 0 && xfs_is_reflink_inode(ip)) { - ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; + if (xfs_is_reflink_inode(ip) && ip->i_cnextents == 0) { + if (ip->i_d.di_nblocks == 0) + ip->i_d.di_flags2 &= ~XFS_DIFLAG2_REFLINK; xfs_inode_clear_cowblocks_tag(ip); } |