aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c51
1 files changed, 28 insertions, 23 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index de32f0fe47c8..edfa6a55b064 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1692,32 +1692,34 @@ xfs_release(
1692 if (xfs_can_free_eofblocks(ip, false)) { 1692 if (xfs_can_free_eofblocks(ip, false)) {
1693 1693
1694 /* 1694 /*
1695 * Check if the inode is being opened, written and closed
1696 * frequently and we have delayed allocation blocks outstanding
1697 * (e.g. streaming writes from the NFS server), truncating the
1698 * blocks past EOF will cause fragmentation to occur.
1699 *
1700 * In this case don't do the truncation, but we have to be
1701 * careful how we detect this case. Blocks beyond EOF show up as
1702 * i_delayed_blks even when the inode is clean, so we need to
1703 * truncate them away first before checking for a dirty release.
1704 * Hence on the first dirty close we will still remove the
1705 * speculative allocation, but after that we will leave it in
1706 * place.
1707 */
1708 if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE))
1709 return 0;
1710 /*
1695 * If we can't get the iolock just skip truncating the blocks 1711 * If we can't get the iolock just skip truncating the blocks
1696 * past EOF because we could deadlock with the mmap_sem 1712 * past EOF because we could deadlock with the mmap_sem
1697 * otherwise. We'll get another chance to drop them once the 1713 * otherwise. We'll get another chance to drop them once the
1698 * last reference to the inode is dropped, so we'll never leak 1714 * last reference to the inode is dropped, so we'll never leak
1699 * blocks permanently. 1715 * blocks permanently.
1700 *
1701 * Further, check if the inode is being opened, written and
1702 * closed frequently and we have delayed allocation blocks
1703 * outstanding (e.g. streaming writes from the NFS server),
1704 * truncating the blocks past EOF will cause fragmentation to
1705 * occur.
1706 *
1707 * In this case don't do the truncation, either, but we have to
1708 * be careful how we detect this case. Blocks beyond EOF show
1709 * up as i_delayed_blks even when the inode is clean, so we
1710 * need to truncate them away first before checking for a dirty
1711 * release. Hence on the first dirty close we will still remove
1712 * the speculative allocation, but after that we will leave it
1713 * in place.
1714 */ 1716 */
1715 if (xfs_iflags_test(ip, XFS_IDIRTY_RELEASE)) 1717 if (xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) {
1716 return 0; 1718 error = xfs_free_eofblocks(ip);
1717 1719 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1718 error = xfs_free_eofblocks(mp, ip, true); 1720 if (error)
1719 if (error && error != -EAGAIN) 1721 return error;
1720 return error; 1722 }
1721 1723
1722 /* delalloc blocks after truncation means it really is dirty */ 1724 /* delalloc blocks after truncation means it really is dirty */
1723 if (ip->i_delayed_blks) 1725 if (ip->i_delayed_blks)
@@ -1904,8 +1906,11 @@ xfs_inactive(
1904 * cache. Post-eof blocks must be freed, lest we end up with 1906 * cache. Post-eof blocks must be freed, lest we end up with
1905 * broken free space accounting. 1907 * broken free space accounting.
1906 */ 1908 */
1907 if (xfs_can_free_eofblocks(ip, true)) 1909 if (xfs_can_free_eofblocks(ip, true)) {
1908 xfs_free_eofblocks(mp, ip, false); 1910 xfs_ilock(ip, XFS_IOLOCK_EXCL);
1911 xfs_free_eofblocks(ip);
1912 xfs_iunlock(ip, XFS_IOLOCK_EXCL);
1913 }
1909 1914
1910 return; 1915 return;
1911 } 1916 }