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: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Brian Foster <bfoster@redhat.com>
This commit is contained in:
Darrick J. Wong 2021-01-22 16:48:36 -08:00
parent 3d4feec006
commit 111068f80e
3 changed files with 23 additions and 15 deletions

View File

@ -702,14 +702,14 @@ write_retry:
* metadata space. This reduces the chances that the eofblocks scan * metadata space. This reduces the chances that the eofblocks scan
* waits on dirty mappings. Since xfs_flush_inodes() is serialized, this * waits on dirty mappings. Since xfs_flush_inodes() is serialized, this
* also behaves as a filter to prevent too many eofblocks scans from * 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) { if (ret == -EDQUOT && !cleared_space) {
xfs_iunlock(ip, iolock); xfs_iunlock(ip, iolock);
cleared_space = xfs_blockgc_free_quota(ip); xfs_blockgc_free_quota(ip, XFS_EOF_FLAGS_SYNC);
if (cleared_space) cleared_space = true;
goto write_retry; goto write_retry;
iolock = 0;
} else if (ret == -ENOSPC && !cleared_space) { } else if (ret == -ENOSPC && !cleared_space) {
struct xfs_eofblocks eofb = {0}; struct xfs_eofblocks eofb = {0};

View File

@ -1650,20 +1650,26 @@ xfs_start_block_reaping(
* with multiple quotas, we don't know exactly which quota caused an allocation * 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 * failure. We make a best effort by including each quota under low free space
* conditions (less than 1% free space) in the scan. * 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( xfs_blockgc_free_quota(
struct xfs_inode *ip) struct xfs_inode *ip,
unsigned int eof_flags)
{ {
struct xfs_eofblocks eofb = {0}; struct xfs_eofblocks eofb = {0};
struct xfs_dquot *dq; struct xfs_dquot *dq;
bool do_work = false; bool do_work = false;
int error;
/* /*
* Run a sync scan to increase effectiveness and use the union filter to * Run a scan to free blocks using the union filter to cover all
* cover all applicable quotas in a single scan. * 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)) { if (XFS_IS_UQUOTA_ENFORCED(ip->i_mount)) {
dq = xfs_inode_dquot(ip, XFS_DQTYPE_USER); dq = xfs_inode_dquot(ip, XFS_DQTYPE_USER);
@ -1693,9 +1699,11 @@ xfs_blockgc_free_quota(
} }
if (!do_work) if (!do_work)
return false; return 0;
xfs_icache_free_eofblocks(ip->i_mount, &eofb); error = xfs_icache_free_eofblocks(ip->i_mount, &eofb);
xfs_icache_free_cowblocks(ip->i_mount, &eofb); if (error)
return true; return error;
return xfs_icache_free_cowblocks(ip->i_mount, &eofb);
} }

View File

@ -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); 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_set_eofblocks_tag(struct xfs_inode *ip);
void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip); void xfs_inode_clear_eofblocks_tag(struct xfs_inode *ip);