Fixes for 5.7:
- Fix a partially uninitialized variable. - Teach the background gc threads to apply for fsfreeze protection. - Fix some scaling problems when multiple threads try to flush the filesystem when we're about to hit ENOSPC. -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEUzaAxoMeQq6m2jMV+H93GTRKtOsFAl6ZSVQACgkQ+H93GTRK tOuPfg//XQ9HX0VAd4xYM3uAr50gNIUPMfOjrlUdZfnj+DOxJDb7IbN9t6+NXYU7 dfVdUeSPy7vwC/JUyVVgBbTfCX1CnQoeNWtg6EAdEF0msJIlbCH4sm+pI2Vofnqp 1VDT9fU1cmrtz/dtS6teJT49P/uCPCmKRGAcnIJn/E7FZUiDS0je2iwV8jbJtAyo xfTHO39t5jBxBRBLRSuJUzYYvvW1ix3zheebLUQZMolnKRkKafWPja1I2N2lRt23 VnXwEjgFpqkT2OcDk5jljkJLbImHmNNVTc6J7SomtxZfWZDwvVfIHgMUC1OsyvW3 tJCp/22xAqqkBQS6Gx6qoXQubnqsfka86krq8C/juz5q5Doc7TPClpc4eyY/XZ0+ q3/67K9Z5MbudUQRmDBrNqmBBiI93qVB6DmeDLvQbBIIBDNFcWTRar0WB+/s/i3S V4BMTyGfwU7u6ZSVzx+W619uLfgwH1mG4uzDg4xk4b4Uia3+/3zjJkh2WzrT98eq N+jwQr5MbWyxmjbFtcsO6ZUqlh7X5RXmjFXBAZjauVwCQAaSvnHR2SdyAvUrD2bG V2ujYVJ8dAJjXeS/9ILWW+oo/tQTlmmUE898oP6ZljuSYj/ONLqM4AMUoR4Ie1Vp BTuRr0VkAoJH2yTK/OTXYe6mBCFSyrp2l3CEC7EDLrCRQQInbRo= =YkcH -----END PGP SIGNATURE----- Merge tag 'xfs-5.7-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux Pull xfs fixes from Darrick Wong: "The three commits here fix some livelocks and other clashes with fsfreeze, a potential corruption problem, and a minor race between processes freeing and allocating space when the filesystem is near ENOSPC. Summary: - Fix a partially uninitialized variable. - Teach the background gc threads to apply for fsfreeze protection. - Fix some scaling problems when multiple threads try to flush the filesystem when we're about to hit ENOSPC" * tag 'xfs-5.7-fixes-3' of git://git.kernel.org/pub/scm/fs/xfs/xfs-linux: xfs: move inode flush to the sync workqueue xfs: fix partially uninitialized structure in xfs_reflink_remap_extent xfs: acquire superblock freeze protection on eofblocks scans
This commit is contained in:
Коммит
c0d73a868d
|
@ -911,7 +911,12 @@ xfs_eofblocks_worker(
|
|||
{
|
||||
struct xfs_mount *mp = container_of(to_delayed_work(work),
|
||||
struct xfs_mount, m_eofblocks_work);
|
||||
|
||||
if (!sb_start_write_trylock(mp->m_super))
|
||||
return;
|
||||
xfs_icache_free_eofblocks(mp, NULL);
|
||||
sb_end_write(mp->m_super);
|
||||
|
||||
xfs_queue_eofblocks(mp);
|
||||
}
|
||||
|
||||
|
@ -938,7 +943,12 @@ xfs_cowblocks_worker(
|
|||
{
|
||||
struct xfs_mount *mp = container_of(to_delayed_work(work),
|
||||
struct xfs_mount, m_cowblocks_work);
|
||||
|
||||
if (!sb_start_write_trylock(mp->m_super))
|
||||
return;
|
||||
xfs_icache_free_cowblocks(mp, NULL);
|
||||
sb_end_write(mp->m_super);
|
||||
|
||||
xfs_queue_cowblocks(mp);
|
||||
}
|
||||
|
||||
|
|
|
@ -2363,7 +2363,10 @@ xfs_file_ioctl(
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
return xfs_icache_free_eofblocks(mp, &keofb);
|
||||
sb_start_write(mp->m_super);
|
||||
error = xfs_icache_free_eofblocks(mp, &keofb);
|
||||
sb_end_write(mp->m_super);
|
||||
return error;
|
||||
}
|
||||
|
||||
default:
|
||||
|
|
|
@ -167,8 +167,12 @@ typedef struct xfs_mount {
|
|||
struct xfs_kobj m_error_meta_kobj;
|
||||
struct xfs_error_cfg m_error_cfg[XFS_ERR_CLASS_MAX][XFS_ERR_ERRNO_MAX];
|
||||
struct xstats m_stats; /* per-fs stats */
|
||||
struct ratelimit_state m_flush_inodes_ratelimit;
|
||||
|
||||
/*
|
||||
* Workqueue item so that we can coalesce multiple inode flush attempts
|
||||
* into a single flush.
|
||||
*/
|
||||
struct work_struct m_flush_inodes_work;
|
||||
struct workqueue_struct *m_buf_workqueue;
|
||||
struct workqueue_struct *m_unwritten_workqueue;
|
||||
struct workqueue_struct *m_cil_workqueue;
|
||||
|
|
|
@ -1051,6 +1051,7 @@ xfs_reflink_remap_extent(
|
|||
uirec.br_startblock = irec->br_startblock + rlen;
|
||||
uirec.br_startoff = irec->br_startoff + rlen;
|
||||
uirec.br_blockcount = unmap_len - rlen;
|
||||
uirec.br_state = irec->br_state;
|
||||
unmap_len = rlen;
|
||||
|
||||
/* If this isn't a real mapping, we're done. */
|
||||
|
|
|
@ -516,6 +516,20 @@ xfs_destroy_mount_workqueues(
|
|||
destroy_workqueue(mp->m_buf_workqueue);
|
||||
}
|
||||
|
||||
static void
|
||||
xfs_flush_inodes_worker(
|
||||
struct work_struct *work)
|
||||
{
|
||||
struct xfs_mount *mp = container_of(work, struct xfs_mount,
|
||||
m_flush_inodes_work);
|
||||
struct super_block *sb = mp->m_super;
|
||||
|
||||
if (down_read_trylock(&sb->s_umount)) {
|
||||
sync_inodes_sb(sb);
|
||||
up_read(&sb->s_umount);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush all dirty data to disk. Must not be called while holding an XFS_ILOCK
|
||||
* or a page lock. We use sync_inodes_sb() here to ensure we block while waiting
|
||||
|
@ -526,15 +540,15 @@ void
|
|||
xfs_flush_inodes(
|
||||
struct xfs_mount *mp)
|
||||
{
|
||||
struct super_block *sb = mp->m_super;
|
||||
|
||||
if (!__ratelimit(&mp->m_flush_inodes_ratelimit))
|
||||
/*
|
||||
* If flush_work() returns true then that means we waited for a flush
|
||||
* which was already in progress. Don't bother running another scan.
|
||||
*/
|
||||
if (flush_work(&mp->m_flush_inodes_work))
|
||||
return;
|
||||
|
||||
if (down_read_trylock(&sb->s_umount)) {
|
||||
sync_inodes_sb(sb);
|
||||
up_read(&sb->s_umount);
|
||||
}
|
||||
queue_work(mp->m_sync_workqueue, &mp->m_flush_inodes_work);
|
||||
flush_work(&mp->m_flush_inodes_work);
|
||||
}
|
||||
|
||||
/* Catch misguided souls that try to use this interface on XFS */
|
||||
|
@ -1369,17 +1383,6 @@ xfs_fc_fill_super(
|
|||
if (error)
|
||||
goto out_free_names;
|
||||
|
||||
/*
|
||||
* Cap the number of invocations of xfs_flush_inodes to 16 for every
|
||||
* quarter of a second. The magic numbers here were determined by
|
||||
* observation neither to cause stalls in writeback when there are a
|
||||
* lot of IO threads and the fs is near ENOSPC, nor cause any fstest
|
||||
* regressions. YMMV.
|
||||
*/
|
||||
ratelimit_state_init(&mp->m_flush_inodes_ratelimit, HZ / 4, 16);
|
||||
ratelimit_set_flags(&mp->m_flush_inodes_ratelimit,
|
||||
RATELIMIT_MSG_ON_RELEASE);
|
||||
|
||||
error = xfs_init_mount_workqueues(mp);
|
||||
if (error)
|
||||
goto out_close_devices;
|
||||
|
@ -1752,6 +1755,7 @@ static int xfs_init_fs_context(
|
|||
spin_lock_init(&mp->m_perag_lock);
|
||||
mutex_init(&mp->m_growlock);
|
||||
atomic_set(&mp->m_active_trans, 0);
|
||||
INIT_WORK(&mp->m_flush_inodes_work, xfs_flush_inodes_worker);
|
||||
INIT_DELAYED_WORK(&mp->m_reclaim_work, xfs_reclaim_worker);
|
||||
INIT_DELAYED_WORK(&mp->m_eofblocks_work, xfs_eofblocks_worker);
|
||||
INIT_DELAYED_WORK(&mp->m_cowblocks_work, xfs_cowblocks_worker);
|
||||
|
|
Загрузка…
Ссылка в новой задаче