diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c index d8202da15aca..dd6d2e08faff 100644 --- a/fs/xfs/xfs_file.c +++ b/fs/xfs/xfs_file.c @@ -1872,17 +1872,21 @@ xfs_file_release( return 0; /* - * If we can't get the iolock just skip truncating the blocks past EOF - * because we could deadlock with the mmap_lock otherwise. We'll get - * another chance to drop them once the last reference to the inode is - * dropped, so we'll never leak blocks permanently. + * If we can't get the iolock or if the filesystem is frozen, just skip + * truncating the blocks past EOF because we could deadlock with the + * mmap_lock or hang the close() call. We'll get another chance to drop + * them once the last reference to the inode is dropped, so we'll never + * leak blocks permanently. */ if (!xfs_iflags_test(ip, XFS_EOFBLOCKS_RELEASED) && - xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { - if (xfs_can_free_eofblocks(ip) && - !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED)) - xfs_free_eofblocks(ip); - xfs_iunlock(ip, XFS_IOLOCK_EXCL); + sb_start_write_trylock(mp->m_super)) { + if (xfs_ilock_nowait(ip, XFS_IOLOCK_EXCL)) { + if (xfs_can_free_eofblocks(ip) && + !xfs_iflags_test_and_set(ip, XFS_EOFBLOCKS_RELEASED)) + xfs_free_eofblocks(ip); + xfs_iunlock(ip, XFS_IOLOCK_EXCL); + } + sb_end_write(mp->m_super); } return 0;