1
0
Fork 0

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
alistair/sensors
Linus Torvalds 2020-04-18 11:46:39 -07:00
commit c0d73a868d
5 changed files with 42 additions and 20 deletions

View File

@ -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);
}

View File

@ -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:

View File

@ -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;

View File

@ -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. */

View File

@ -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);