xfs: detach dquots from inode if we don't need to inactivate it

If we don't need to inactivate an inode, we can detach the dquots and
move on to reclamation.  This isn't strictly required here; it's a
preparation patch for deferred inactivation per reviewer request[1] to
move the creation of xfs_inode_needs_inactivation into a separate
change.  Eventually this !need_inactive chunk will turn into the code
path for inodes that skip xfs_inactive and go straight to memory
reclaim.

[1] https://lore.kernel.org/linux-xfs/20210609012838.GW2945738@locust/T/#mca6d958521cb88bbc1bfe1a30767203328d410b5
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
Darrick J. Wong 2021-08-06 11:05:39 -07:00
parent c6c2066db3
commit 62af7d54a0
3 changed files with 62 additions and 1 deletions

View File

@ -1752,8 +1752,14 @@ xfs_inode_mark_reclaimable(
{
struct xfs_mount *mp = ip->i_mount;
struct xfs_perag *pag;
bool need_inactive = xfs_inode_needs_inactive(ip);
xfs_inactive(ip);
if (!need_inactive) {
/* Going straight to reclaim, so drop the dquots. */
xfs_qm_dqdetach(ip);
} else {
xfs_inactive(ip);
}
if (!XFS_FORCED_SHUTDOWN(mp) && ip->i_delayed_blks) {
xfs_check_delalloc(ip, XFS_DATA_FORK);

View File

@ -1654,6 +1654,59 @@ xfs_inactive_ifree(
return 0;
}
/*
* Returns true if we need to update the on-disk metadata before we can free
* the memory used by this inode. Updates include freeing post-eof
* preallocations; freeing COW staging extents; and marking the inode free in
* the inobt if it is on the unlinked list.
*/
bool
xfs_inode_needs_inactive(
struct xfs_inode *ip)
{
struct xfs_mount *mp = ip->i_mount;
struct xfs_ifork *cow_ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
/*
* If the inode is already free, then there can be nothing
* to clean up here.
*/
if (VFS_I(ip)->i_mode == 0)
return false;
/* If this is a read-only mount, don't do this (would generate I/O) */
if (mp->m_flags & XFS_MOUNT_RDONLY)
return false;
/* If the log isn't running, push inodes straight to reclaim. */
if (XFS_FORCED_SHUTDOWN(mp) || (mp->m_flags & XFS_MOUNT_NORECOVERY))
return false;
/* Metadata inodes require explicit resource cleanup. */
if (xfs_is_metadata_inode(ip))
return false;
/* Want to clean out the cow blocks if there are any. */
if (cow_ifp && cow_ifp->if_bytes > 0)
return true;
/* Unlinked files must be freed. */
if (VFS_I(ip)->i_nlink == 0)
return true;
/*
* This file isn't being freed, so check if there are post-eof blocks
* to free. @force is true because we are evicting an inode from the
* cache. Post-eof blocks must be freed, lest we end up with broken
* free space accounting.
*
* Note: don't bother with iolock here since lockdep complains about
* acquiring it in reclaim context. We have the only reference to the
* inode at this point anyways.
*/
return xfs_can_free_eofblocks(ip, true);
}
/*
* xfs_inactive
*

View File

@ -493,6 +493,8 @@ extern struct kmem_zone *xfs_inode_zone;
/* The default CoW extent size hint. */
#define XFS_DEFAULT_COWEXTSZ_HINT 32
bool xfs_inode_needs_inactive(struct xfs_inode *ip);
int xfs_iunlink_init(struct xfs_perag *pag);
void xfs_iunlink_destroy(struct xfs_perag *pag);