diff options
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/scrub/quotacheck.c | 7 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.c | 17 | ||||
-rw-r--r-- | fs/xfs/xfs_icache.h | 1 |
3 files changed, 25 insertions, 0 deletions
diff --git a/fs/xfs/scrub/quotacheck.c b/fs/xfs/scrub/quotacheck.c index ed3aa84f093b..1717e0f30cdd 100644 --- a/fs/xfs/scrub/quotacheck.c +++ b/fs/xfs/scrub/quotacheck.c @@ -511,6 +511,13 @@ xqcheck_collect_counts( retries = 20; break; case -ENOENT: + /*¬ + * It's possible that this inode has lost all of its + * links but hasn't yet been inactivated. Try to push + * it towards inactivation. + */ + xfs_inodegc_flush_ino(xqc->sc->mp, ino); + /* fall through */ case -EINVAL: /* * We thought the inode was allocated, but iget failed diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c index a24364f25b4b..5fd13ba2482c 100644 --- a/fs/xfs/xfs_icache.c +++ b/fs/xfs/xfs_icache.c @@ -2010,6 +2010,23 @@ clear: clear_bit(XFS_OPFLAG_INACTIVATE_NOW_BIT, &mp->m_opflags); } +/* Flush inactivation work for all inodes in the same AGs as this inode. */ +void +xfs_inodegc_flush_ino( + struct xfs_mount *mp, + xfs_ino_t ino) +{ + struct xfs_perag *pag; + + if (!xfs_inodegc_running(mp)) + return; + + pag = xfs_perag_get(mp, XFS_INO_TO_AGNO(mp, ino)); + mod_delayed_work(mp->m_gc_workqueue, &pag->pag_inodegc_work, 0); + flush_delayed_work(&pag->pag_inodegc_work); + xfs_perag_put(pag); +} + /* Stop all queued inactivation work. */ void xfs_inodegc_stop( diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h index 0f832fa95fd4..1f94ef72fffb 100644 --- a/fs/xfs/xfs_icache.h +++ b/fs/xfs/xfs_icache.h @@ -75,6 +75,7 @@ void xfs_inew_wait(struct xfs_inode *ip); void xfs_inodegc_worker(struct work_struct *work); void xfs_inodegc_flush(struct xfs_mount *mp); void xfs_inodegc_flush_poll(struct xfs_mount *mp); +void xfs_inodegc_flush_ino(struct xfs_mount *mp, xfs_ino_t ino); void xfs_inodegc_stop(struct xfs_mount *mp); void xfs_inodegc_start(struct xfs_mount *mp); int xfs_inodegc_free_space(struct xfs_mount *mp, struct xfs_eofblocks *eofb); |