mirror of
https://github.com/Fishwaldo/linux-bl808.git
synced 2025-03-21 06:24:12 +00:00
xfs: consolidate incore inode radix tree posteof/cowblocks tags
The clearing of posteof blocks and cowblocks serve the same purpose: removing speculative block preallocations from inactive files. We don't need to burn two radix tree tags on this, so combine them into one. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
865ac8e253
commit
ce2d3bbe06
3 changed files with 58 additions and 66 deletions
|
@ -1291,6 +1291,9 @@ xfs_inode_free_eofblocks(
|
||||||
|
|
||||||
wait = eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC);
|
wait = eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC);
|
||||||
|
|
||||||
|
if (!xfs_iflags_test(ip, XFS_IEOFBLOCKS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!xfs_can_free_eofblocks(ip, false)) {
|
if (!xfs_can_free_eofblocks(ip, false)) {
|
||||||
/* inode could be preallocated or append-only */
|
/* inode could be preallocated or append-only */
|
||||||
trace_xfs_inode_free_eofblocks_invalid(ip);
|
trace_xfs_inode_free_eofblocks_invalid(ip);
|
||||||
|
@ -1333,7 +1336,7 @@ xfs_queue_eofblocks(
|
||||||
struct xfs_mount *mp)
|
struct xfs_mount *mp)
|
||||||
{
|
{
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_EOFBLOCKS_TAG))
|
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
|
||||||
queue_delayed_work(mp->m_eofblocks_workqueue,
|
queue_delayed_work(mp->m_eofblocks_workqueue,
|
||||||
&mp->m_eofblocks_work,
|
&mp->m_eofblocks_work,
|
||||||
msecs_to_jiffies(xfs_eofb_secs * 1000));
|
msecs_to_jiffies(xfs_eofb_secs * 1000));
|
||||||
|
@ -1350,67 +1353,54 @@ xfs_eofblocks_worker(
|
||||||
if (!sb_start_write_trylock(mp->m_super))
|
if (!sb_start_write_trylock(mp->m_super))
|
||||||
return;
|
return;
|
||||||
xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, NULL,
|
xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, NULL,
|
||||||
XFS_ICI_EOFBLOCKS_TAG);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
sb_end_write(mp->m_super);
|
sb_end_write(mp->m_super);
|
||||||
|
|
||||||
xfs_queue_eofblocks(mp);
|
xfs_queue_eofblocks(mp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline unsigned long
|
|
||||||
xfs_iflag_for_tag(
|
|
||||||
int tag)
|
|
||||||
{
|
|
||||||
switch (tag) {
|
|
||||||
case XFS_ICI_EOFBLOCKS_TAG:
|
|
||||||
return XFS_IEOFBLOCKS;
|
|
||||||
case XFS_ICI_COWBLOCKS_TAG:
|
|
||||||
return XFS_ICOWBLOCKS;
|
|
||||||
default:
|
|
||||||
ASSERT(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__xfs_inode_set_blocks_tag(
|
xfs_blockgc_set_iflag(
|
||||||
xfs_inode_t *ip,
|
struct xfs_inode *ip,
|
||||||
void (*execute)(struct xfs_mount *mp),
|
void (*execute)(struct xfs_mount *mp),
|
||||||
void (*set_tp)(struct xfs_mount *mp, xfs_agnumber_t agno,
|
unsigned long iflag)
|
||||||
int error, unsigned long caller_ip),
|
|
||||||
int tag)
|
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
struct xfs_perag *pag;
|
struct xfs_perag *pag;
|
||||||
int tagged;
|
int tagged;
|
||||||
|
|
||||||
|
ASSERT((iflag & ~(XFS_IEOFBLOCKS | XFS_ICOWBLOCKS)) == 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Don't bother locking the AG and looking up in the radix trees
|
* Don't bother locking the AG and looking up in the radix trees
|
||||||
* if we already know that we have the tag set.
|
* if we already know that we have the tag set.
|
||||||
*/
|
*/
|
||||||
if (ip->i_flags & xfs_iflag_for_tag(tag))
|
if (ip->i_flags & iflag)
|
||||||
return;
|
return;
|
||||||
spin_lock(&ip->i_flags_lock);
|
spin_lock(&ip->i_flags_lock);
|
||||||
ip->i_flags |= xfs_iflag_for_tag(tag);
|
ip->i_flags |= iflag;
|
||||||
spin_unlock(&ip->i_flags_lock);
|
spin_unlock(&ip->i_flags_lock);
|
||||||
|
|
||||||
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
|
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
|
||||||
spin_lock(&pag->pag_ici_lock);
|
spin_lock(&pag->pag_ici_lock);
|
||||||
|
|
||||||
tagged = radix_tree_tagged(&pag->pag_ici_root, tag);
|
tagged = radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_BLOCKGC_TAG);
|
||||||
radix_tree_tag_set(&pag->pag_ici_root,
|
radix_tree_tag_set(&pag->pag_ici_root,
|
||||||
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), tag);
|
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
|
||||||
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
if (!tagged) {
|
if (!tagged) {
|
||||||
/* propagate the eofblocks tag up into the perag radix tree */
|
/* propagate the blockgc tag up into the perag radix tree */
|
||||||
spin_lock(&ip->i_mount->m_perag_lock);
|
spin_lock(&ip->i_mount->m_perag_lock);
|
||||||
radix_tree_tag_set(&ip->i_mount->m_perag_tree,
|
radix_tree_tag_set(&ip->i_mount->m_perag_tree,
|
||||||
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
||||||
tag);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
spin_unlock(&ip->i_mount->m_perag_lock);
|
spin_unlock(&ip->i_mount->m_perag_lock);
|
||||||
|
|
||||||
/* kick off background trimming */
|
/* kick off background trimming */
|
||||||
execute(ip->i_mount);
|
execute(ip->i_mount);
|
||||||
|
|
||||||
set_tp(ip->i_mount, pag->pag_agno, -1, _RET_IP_);
|
trace_xfs_perag_set_blockgc(ip->i_mount, pag->pag_agno, -1,
|
||||||
|
_RET_IP_);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&pag->pag_ici_lock);
|
spin_unlock(&pag->pag_ici_lock);
|
||||||
|
@ -1422,38 +1412,43 @@ xfs_inode_set_eofblocks_tag(
|
||||||
xfs_inode_t *ip)
|
xfs_inode_t *ip)
|
||||||
{
|
{
|
||||||
trace_xfs_inode_set_eofblocks_tag(ip);
|
trace_xfs_inode_set_eofblocks_tag(ip);
|
||||||
return __xfs_inode_set_blocks_tag(ip, xfs_queue_eofblocks,
|
return xfs_blockgc_set_iflag(ip, xfs_queue_eofblocks, XFS_IEOFBLOCKS);
|
||||||
trace_xfs_perag_set_eofblocks,
|
|
||||||
XFS_ICI_EOFBLOCKS_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
__xfs_inode_clear_blocks_tag(
|
xfs_blockgc_clear_iflag(
|
||||||
xfs_inode_t *ip,
|
struct xfs_inode *ip,
|
||||||
void (*clear_tp)(struct xfs_mount *mp, xfs_agnumber_t agno,
|
unsigned long iflag)
|
||||||
int error, unsigned long caller_ip),
|
|
||||||
int tag)
|
|
||||||
{
|
{
|
||||||
struct xfs_mount *mp = ip->i_mount;
|
struct xfs_mount *mp = ip->i_mount;
|
||||||
struct xfs_perag *pag;
|
struct xfs_perag *pag;
|
||||||
|
bool clear_tag;
|
||||||
|
|
||||||
|
ASSERT((iflag & ~(XFS_IEOFBLOCKS | XFS_ICOWBLOCKS)) == 0);
|
||||||
|
|
||||||
spin_lock(&ip->i_flags_lock);
|
spin_lock(&ip->i_flags_lock);
|
||||||
ip->i_flags &= ~xfs_iflag_for_tag(tag);
|
ip->i_flags &= ~iflag;
|
||||||
|
clear_tag = (ip->i_flags & (XFS_IEOFBLOCKS | XFS_ICOWBLOCKS)) == 0;
|
||||||
spin_unlock(&ip->i_flags_lock);
|
spin_unlock(&ip->i_flags_lock);
|
||||||
|
|
||||||
|
if (!clear_tag)
|
||||||
|
return;
|
||||||
|
|
||||||
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
|
pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ip->i_ino));
|
||||||
spin_lock(&pag->pag_ici_lock);
|
spin_lock(&pag->pag_ici_lock);
|
||||||
|
|
||||||
radix_tree_tag_clear(&pag->pag_ici_root,
|
radix_tree_tag_clear(&pag->pag_ici_root,
|
||||||
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino), tag);
|
XFS_INO_TO_AGINO(ip->i_mount, ip->i_ino),
|
||||||
if (!radix_tree_tagged(&pag->pag_ici_root, tag)) {
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
/* clear the eofblocks tag from the perag radix tree */
|
if (!radix_tree_tagged(&pag->pag_ici_root, XFS_ICI_BLOCKGC_TAG)) {
|
||||||
|
/* clear the blockgc tag from the perag radix tree */
|
||||||
spin_lock(&ip->i_mount->m_perag_lock);
|
spin_lock(&ip->i_mount->m_perag_lock);
|
||||||
radix_tree_tag_clear(&ip->i_mount->m_perag_tree,
|
radix_tree_tag_clear(&ip->i_mount->m_perag_tree,
|
||||||
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
XFS_INO_TO_AGNO(ip->i_mount, ip->i_ino),
|
||||||
tag);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
spin_unlock(&ip->i_mount->m_perag_lock);
|
spin_unlock(&ip->i_mount->m_perag_lock);
|
||||||
clear_tp(ip->i_mount, pag->pag_agno, -1, _RET_IP_);
|
trace_xfs_perag_clear_blockgc(ip->i_mount, pag->pag_agno, -1,
|
||||||
|
_RET_IP_);
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_unlock(&pag->pag_ici_lock);
|
spin_unlock(&pag->pag_ici_lock);
|
||||||
|
@ -1465,8 +1460,7 @@ xfs_inode_clear_eofblocks_tag(
|
||||||
xfs_inode_t *ip)
|
xfs_inode_t *ip)
|
||||||
{
|
{
|
||||||
trace_xfs_inode_clear_eofblocks_tag(ip);
|
trace_xfs_inode_clear_eofblocks_tag(ip);
|
||||||
return __xfs_inode_clear_blocks_tag(ip,
|
return xfs_blockgc_clear_iflag(ip, XFS_IEOFBLOCKS);
|
||||||
trace_xfs_perag_clear_eofblocks, XFS_ICI_EOFBLOCKS_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1524,6 +1518,9 @@ xfs_inode_free_cowblocks(
|
||||||
|
|
||||||
wait = eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC);
|
wait = eofb && (eofb->eof_flags & XFS_EOF_FLAGS_SYNC);
|
||||||
|
|
||||||
|
if (!xfs_iflags_test(ip, XFS_ICOWBLOCKS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!xfs_prep_free_cowblocks(ip))
|
if (!xfs_prep_free_cowblocks(ip))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -1569,7 +1566,7 @@ xfs_queue_cowblocks(
|
||||||
struct xfs_mount *mp)
|
struct xfs_mount *mp)
|
||||||
{
|
{
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_COWBLOCKS_TAG))
|
if (radix_tree_tagged(&mp->m_perag_tree, XFS_ICI_BLOCKGC_TAG))
|
||||||
queue_delayed_work(mp->m_eofblocks_workqueue,
|
queue_delayed_work(mp->m_eofblocks_workqueue,
|
||||||
&mp->m_cowblocks_work,
|
&mp->m_cowblocks_work,
|
||||||
msecs_to_jiffies(xfs_cowb_secs * 1000));
|
msecs_to_jiffies(xfs_cowb_secs * 1000));
|
||||||
|
@ -1586,7 +1583,7 @@ xfs_cowblocks_worker(
|
||||||
if (!sb_start_write_trylock(mp->m_super))
|
if (!sb_start_write_trylock(mp->m_super))
|
||||||
return;
|
return;
|
||||||
xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, NULL,
|
xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, NULL,
|
||||||
XFS_ICI_COWBLOCKS_TAG);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
sb_end_write(mp->m_super);
|
sb_end_write(mp->m_super);
|
||||||
|
|
||||||
xfs_queue_cowblocks(mp);
|
xfs_queue_cowblocks(mp);
|
||||||
|
@ -1597,9 +1594,7 @@ xfs_inode_set_cowblocks_tag(
|
||||||
xfs_inode_t *ip)
|
xfs_inode_t *ip)
|
||||||
{
|
{
|
||||||
trace_xfs_inode_set_cowblocks_tag(ip);
|
trace_xfs_inode_set_cowblocks_tag(ip);
|
||||||
return __xfs_inode_set_blocks_tag(ip, xfs_queue_cowblocks,
|
return xfs_blockgc_set_iflag(ip, xfs_queue_cowblocks, XFS_ICOWBLOCKS);
|
||||||
trace_xfs_perag_set_cowblocks,
|
|
||||||
XFS_ICI_COWBLOCKS_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -1607,8 +1602,7 @@ xfs_inode_clear_cowblocks_tag(
|
||||||
xfs_inode_t *ip)
|
xfs_inode_t *ip)
|
||||||
{
|
{
|
||||||
trace_xfs_inode_clear_cowblocks_tag(ip);
|
trace_xfs_inode_clear_cowblocks_tag(ip);
|
||||||
return __xfs_inode_clear_blocks_tag(ip,
|
return xfs_blockgc_clear_iflag(ip, XFS_ICOWBLOCKS);
|
||||||
trace_xfs_perag_clear_cowblocks, XFS_ICI_COWBLOCKS_TAG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Disable post-EOF and CoW block auto-reclamation. */
|
/* Disable post-EOF and CoW block auto-reclamation. */
|
||||||
|
@ -1638,12 +1632,12 @@ xfs_blockgc_scan(
|
||||||
int error;
|
int error;
|
||||||
|
|
||||||
error = xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, eofb,
|
error = xfs_inode_walk(mp, 0, xfs_inode_free_eofblocks, eofb,
|
||||||
XFS_ICI_EOFBLOCKS_TAG);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
error = xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, eofb,
|
error = xfs_inode_walk(mp, 0, xfs_inode_free_cowblocks, eofb,
|
||||||
XFS_ICI_COWBLOCKS_TAG);
|
XFS_ICI_BLOCKGC_TAG);
|
||||||
if (error)
|
if (error)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ struct xfs_eofblocks {
|
||||||
#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup
|
#define XFS_ICI_NO_TAG (-1) /* special flag for an untagged lookup
|
||||||
in xfs_inode_walk */
|
in xfs_inode_walk */
|
||||||
#define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */
|
#define XFS_ICI_RECLAIM_TAG 0 /* inode is to be reclaimed */
|
||||||
#define XFS_ICI_EOFBLOCKS_TAG 1 /* inode has blocks beyond EOF */
|
/* Inode has speculative preallocations (posteof or cow) to clean. */
|
||||||
#define XFS_ICI_COWBLOCKS_TAG 2 /* inode can have cow blocks to gc */
|
#define XFS_ICI_BLOCKGC_TAG 1
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flags for xfs_iget()
|
* Flags for xfs_iget()
|
||||||
|
|
|
@ -155,10 +155,8 @@ DEFINE_PERAG_REF_EVENT(xfs_perag_get_tag);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
|
DEFINE_PERAG_REF_EVENT(xfs_perag_put);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_set_reclaim);
|
DEFINE_PERAG_REF_EVENT(xfs_perag_set_reclaim);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_reclaim);
|
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_reclaim);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_set_eofblocks);
|
DEFINE_PERAG_REF_EVENT(xfs_perag_set_blockgc);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_eofblocks);
|
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_blockgc);
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_set_cowblocks);
|
|
||||||
DEFINE_PERAG_REF_EVENT(xfs_perag_clear_cowblocks);
|
|
||||||
|
|
||||||
DECLARE_EVENT_CLASS(xfs_ag_class,
|
DECLARE_EVENT_CLASS(xfs_ag_class,
|
||||||
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno),
|
TP_PROTO(struct xfs_mount *mp, xfs_agnumber_t agno),
|
||||||
|
|
Loading…
Add table
Reference in a new issue