Skip to content

Commit 4b674b9

Browse files
Brian Fosterdjwong
authored andcommitted
xfs: acquire superblock freeze protection on eofblocks scans
The filesystem freeze sequence in XFS waits on any background eofblocks or cowblocks scans to complete before the filesystem is quiesced. At this point, the freezer has already stopped the transaction subsystem, however, which means a truncate or cowblock cancellation in progress is likely blocked in transaction allocation. This results in a deadlock between freeze and the associated scanner. Fix this problem by holding superblock write protection across calls into the block reapers. Since protection for background scans is acquired from the workqueue task context, trylock to avoid a similar deadlock between freeze and blocking on the write lock. Fixes: d6b636e ("xfs: halt auto-reclamation activities while rebuilding rmap") Reported-by: Paul Furtado <[email protected]> Signed-off-by: Brian Foster <[email protected]> Reviewed-by: Chandan Rajendra <[email protected]> Reviewed-by: Christoph Hellwig <[email protected]> Reviewed-by: Allison Collins <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent 8f3d9f3 commit 4b674b9

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

fs/xfs/xfs_icache.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,7 +911,12 @@ xfs_eofblocks_worker(
911911
{
912912
struct xfs_mount *mp = container_of(to_delayed_work(work),
913913
struct xfs_mount, m_eofblocks_work);
914+
915+
if (!sb_start_write_trylock(mp->m_super))
916+
return;
914917
xfs_icache_free_eofblocks(mp, NULL);
918+
sb_end_write(mp->m_super);
919+
915920
xfs_queue_eofblocks(mp);
916921
}
917922

@@ -938,7 +943,12 @@ xfs_cowblocks_worker(
938943
{
939944
struct xfs_mount *mp = container_of(to_delayed_work(work),
940945
struct xfs_mount, m_cowblocks_work);
946+
947+
if (!sb_start_write_trylock(mp->m_super))
948+
return;
941949
xfs_icache_free_cowblocks(mp, NULL);
950+
sb_end_write(mp->m_super);
951+
942952
xfs_queue_cowblocks(mp);
943953
}
944954

fs/xfs/xfs_ioctl.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2363,7 +2363,10 @@ xfs_file_ioctl(
23632363
if (error)
23642364
return error;
23652365

2366-
return xfs_icache_free_eofblocks(mp, &keofb);
2366+
sb_start_write(mp->m_super);
2367+
error = xfs_icache_free_eofblocks(mp, &keofb);
2368+
sb_end_write(mp->m_super);
2369+
return error;
23672370
}
23682371

23692372
default:

0 commit comments

Comments
 (0)