Commit c0d73a86 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents 774acb2a f0f7a674
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -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);
}

+4 −1
Original line number Diff line number Diff line
@@ -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:
+5 −1
Original line number Diff line number Diff line
@@ -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;
+1 −0
Original line number Diff line number Diff line
@@ -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. */
+22 −18
Original line number Diff line number Diff line
@@ -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);