Skip to content

Commit e0a7240

Browse files
djwongSomasundaram Krishnasamy
authored andcommitted
xfs: decide if inode needs inactivation
Add a predicate function to decide if an inode needs (deferred) inactivation. Any file that has been unlinked or has speculative preallocations either for post-EOF writes or for CoW qualifies. This function will also be used by the upcoming deferred inactivation patch. Signed-off-by: Darrick J. Wong <[email protected]> (cherry picked from commit f20a128f44b5eff13afa9f87d76e6310d3607d92) cherry-pick-repo=kernel/git/djwong/xfs-linux.git Orabug: 30898016 Signed-off-by: Junxiao Bi <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Somasundaram Krishnasamy <[email protected]>
1 parent a074c30 commit e0a7240

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

fs/xfs/xfs_inode.c

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,6 +1859,65 @@ xfs_inactive_ifree(
18591859
return 0;
18601860
}
18611861

1862+
/*
1863+
* Returns true if we need to update the on-disk metadata before we can free
1864+
* the memory used by this inode. Updates include freeing post-eof
1865+
* preallocations; freeing COW staging extents; and marking the inode free in
1866+
* the inobt if it is on the unlinked list.
1867+
*/
1868+
bool
1869+
xfs_inode_needs_inactivation(
1870+
struct xfs_inode *ip)
1871+
{
1872+
struct xfs_mount *mp = ip->i_mount;
1873+
struct xfs_ifork *cow_ifp = XFS_IFORK_PTR(ip, XFS_COW_FORK);
1874+
1875+
/*
1876+
* If the inode is already free, then there can be nothing
1877+
* to clean up here.
1878+
*/
1879+
if (VFS_I(ip)->i_mode == 0)
1880+
return false;
1881+
1882+
/* If this is a read-only mount, don't do this (would generate I/O) */
1883+
if (mp->m_flags & XFS_MOUNT_RDONLY)
1884+
return false;
1885+
1886+
/* Try to clean out the cow blocks if there are any. */
1887+
if (cow_ifp && cow_ifp->if_bytes > 0)
1888+
return true;
1889+
1890+
if (VFS_I(ip)->i_nlink != 0) {
1891+
int error;
1892+
bool has;
1893+
1894+
/*
1895+
* force is true because we are evicting an inode from the
1896+
* cache. Post-eof blocks must be freed, lest we end up with
1897+
* broken free space accounting.
1898+
*
1899+
* Note: don't bother with iolock here since lockdep complains
1900+
* about acquiring it in reclaim context. We have the only
1901+
* reference to the inode at this point anyways.
1902+
*
1903+
* If the predicate errors out, send the inode through
1904+
* inactivation anyway, because that's what we did before.
1905+
* The inactivation worker will ignore an inode that doesn't
1906+
* actually need it.
1907+
*/
1908+
if (!xfs_can_free_eofblocks(ip, true))
1909+
return false;
1910+
error = xfs_has_eofblocks(ip, &has);
1911+
return error != 0 || has;
1912+
}
1913+
1914+
/*
1915+
* Link count dropped to zero, which means we have to mark the inode
1916+
* free on disk and remove it from the AGI unlinked list.
1917+
*/
1918+
return true;
1919+
}
1920+
18621921
/*
18631922
* xfs_inactive
18641923
*

fs/xfs/xfs_inode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -510,5 +510,6 @@ extern struct kmem_zone *xfs_inode_zone;
510510

511511
bool xfs_inode_verify_forks(struct xfs_inode *ip);
512512
int xfs_has_eofblocks(struct xfs_inode *ip, bool *has);
513+
bool xfs_inode_needs_inactivation(struct xfs_inode *ip);
513514

514515
#endif /* __XFS_INODE_H__ */

0 commit comments

Comments
 (0)