Commit 111068f8 authored by Darrick J. Wong's avatar Darrick J. Wong
Browse files

xfs: pass flags and return gc errors from xfs_blockgc_free_quota



Change the signature of xfs_blockgc_free_quota in preparation for the
next few patches.  Callers can now pass EOF_FLAGS into the function to
control scan parameters; and the function will now pass back any
corruption errors seen while scanning, though for our retry loops we'll
just try again unconditionally.

Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
parent 3d4feec0
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -702,14 +702,14 @@ xfs_file_buffered_aio_write(
	 * metadata space. This reduces the chances that the eofblocks scan
	 * waits on dirty mappings. Since xfs_flush_inodes() is serialized, this
	 * also behaves as a filter to prevent too many eofblocks scans from
	 * running at the same time.
	 * running at the same time.  Use a synchronous scan to increase the
	 * effectiveness of the scan.
	 */
	if (ret == -EDQUOT && !cleared_space) {
		xfs_iunlock(ip, iolock);
		cleared_space = xfs_blockgc_free_quota(ip);
		if (cleared_space)
		xfs_blockgc_free_quota(ip, XFS_EOF_FLAGS_SYNC);
		cleared_space = true;
		goto write_retry;
		iolock = 0;
	} else if (ret == -ENOSPC && !cleared_space) {
		struct xfs_eofblocks eofb = {0};

+17 −9
Original line number Diff line number Diff line
@@ -1650,20 +1650,26 @@ xfs_start_block_reaping(
 * with multiple quotas, we don't know exactly which quota caused an allocation
 * failure. We make a best effort by including each quota under low free space
 * conditions (less than 1% free space) in the scan.
 *
 * Callers must not hold any inode's ILOCK.  If requesting a synchronous scan
 * (XFS_EOF_FLAGS_SYNC), the caller also must not hold any inode's IOLOCK or
 * MMAPLOCK.
 */
bool
int
xfs_blockgc_free_quota(
	struct xfs_inode	*ip)
	struct xfs_inode	*ip,
	unsigned int		eof_flags)
{
	struct xfs_eofblocks	eofb = {0};
	struct xfs_dquot	*dq;
	bool			do_work = false;
	int			error;

	/*
	 * Run a sync scan to increase effectiveness and use the union filter to
	 * cover all applicable quotas in a single scan.
	 * Run a scan to free blocks using the union filter to cover all
	 * applicable quotas in a single scan.
	 */
	eofb.eof_flags = XFS_EOF_FLAGS_UNION | XFS_EOF_FLAGS_SYNC;
	eofb.eof_flags = XFS_EOF_FLAGS_UNION | eof_flags;

	if (XFS_IS_UQUOTA_ENFORCED(ip->i_mount)) {
		dq = xfs_inode_dquot(ip, XFS_DQTYPE_USER);
@@ -1693,9 +1699,11 @@ xfs_blockgc_free_quota(
	}

	if (!do_work)
		return false;
		return 0;

	xfs_icache_free_eofblocks(ip->i_mount, &eofb);
	xfs_icache_free_cowblocks(ip->i_mount, &eofb);
	return true;
	error = xfs_icache_free_eofblocks(ip->i_mount, &eofb);
	if (error)
		return error;

	return xfs_icache_free_cowblocks(ip->i_mount, &eofb);
}
+1 −1
Original line number Diff line number Diff line
@@ -54,7 +54,7 @@ long xfs_reclaim_inodes_nr(struct xfs_mount *mp, int nr_to_scan);

void xfs_inode_set_reclaim_tag(struct xfs_inode *ip);

bool xfs_blockgc_free_quota(struct xfs_inode *ip);
int xfs_blockgc_free_quota(struct xfs_inode *ip, unsigned int eof_flags);

void xfs_inode_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);