diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/xfs_mount.c | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index f6fe47d8c4dc..39cf6f3267c3 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -1182,6 +1182,17 @@ xfs_unmountfs(xfs_mount_t *mp, struct cred *cr) | |||
1182 | int64_t fsid; | 1182 | int64_t fsid; |
1183 | #endif | 1183 | #endif |
1184 | 1184 | ||
1185 | /* | ||
1186 | * We can potentially deadlock here if we have an inode cluster | ||
1187 | * that has been freed has it's buffer still pinned in memory because | ||
1188 | * the transaction is still sitting in a iclog. The stale inodes | ||
1189 | * on that buffer will have their flush locks held until the | ||
1190 | * transaction hits the disk and the callbacks run. the inode | ||
1191 | * flush takes the flush lock unconditionally and with nothing to | ||
1192 | * push out the iclog we will never get that unlocked. hence we | ||
1193 | * need to force the log first. | ||
1194 | */ | ||
1195 | xfs_log_force(mp, (xfs_lsn_t)0, XFS_LOG_FORCE | XFS_LOG_SYNC); | ||
1185 | xfs_iflush_all(mp); | 1196 | xfs_iflush_all(mp); |
1186 | 1197 | ||
1187 | XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING); | 1198 | XFS_QM_DQPURGEALL(mp, XFS_QMOPT_QUOTALL | XFS_QMOPT_UMOUNTING); |