diff options
Diffstat (limited to 'fs/xfs/scrub')
-rw-r--r-- | fs/xfs/scrub/common.c | 25 | ||||
-rw-r--r-- | fs/xfs/scrub/common.h | 3 | ||||
-rw-r--r-- | fs/xfs/scrub/dir.c | 2 | ||||
-rw-r--r-- | fs/xfs/scrub/dir_repair.c | 4 | ||||
-rw-r--r-- | fs/xfs/scrub/inode_repair.c | 3 | ||||
-rw-r--r-- | fs/xfs/scrub/parent.c | 6 | ||||
-rw-r--r-- | fs/xfs/scrub/parent_repair.c | 9 | ||||
-rw-r--r-- | fs/xfs/scrub/quotacheck.c | 4 | ||||
-rw-r--r-- | fs/xfs/scrub/rmap_repair.c | 5 | ||||
-rw-r--r-- | fs/xfs/scrub/rtrmap_repair.c | 5 | ||||
-rw-r--r-- | fs/xfs/scrub/scrub.c | 11 |
11 files changed, 47 insertions, 30 deletions
diff --git a/fs/xfs/scrub/common.c b/fs/xfs/scrub/common.c index 6113b6c3d5c4..c28444d10188 100644 --- a/fs/xfs/scrub/common.c +++ b/fs/xfs/scrub/common.c @@ -849,8 +849,7 @@ xchk_get_inode( /* Look up the inode, see if the generation number matches. */ if (xfs_internal_inum(mp, sc->sm->sm_ino)) return -ENOENT; - error = xfs_iget(mp, NULL, sc->sm->sm_ino, - XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE, 0, &ip); + error = xfs_iget(mp, NULL, sc->sm->sm_ino, XFS_IGET_UNTRUSTED, 0, &ip); switch (error) { case -ENOENT: /* Inode doesn't exist, just bail out. */ @@ -872,7 +871,7 @@ xchk_get_inode( * that it no longer exists. */ error = xfs_imap(sc->mp, sc->tp, sc->sm->sm_ino, &imap, - XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE); + XFS_IGET_UNTRUSTED); if (error) return -ENOENT; error = -EFSCORRUPTED; @@ -897,7 +896,7 @@ xchk_get_inode( */ if (VFS_I(ip)->i_generation != sc->sm->sm_gen || (xfs_is_metadata_inode(ip) && !S_ISDIR(VFS_I(ip)->i_mode))) { - xfs_irele(ip); + xchk_irele(sc, ip); return -ENOENT; } @@ -905,6 +904,24 @@ xchk_get_inode( return 0; } +void +__xchk_irele( + struct xfs_inode *ip, + bool set_dontcache) +{ + if (set_dontcache && atomic_read(&VFS_I(ip)->i_count) == 1) + d_mark_dontcache(VFS_I(ip)); + xfs_irele(ip); +} + +void +xchk_irele( + struct xfs_scrub *sc, + struct xfs_inode *ip) +{ + __xchk_irele(ip, !(sc->sm->sm_flags & XFS_SCRUB_IFLAG_RETAIN_INODES)); +} + /* Set us up to scrub a file's contents. */ int xchk_setup_inode_contents( diff --git a/fs/xfs/scrub/common.h b/fs/xfs/scrub/common.h index 4e92bb89ef5d..08bf69610288 100644 --- a/fs/xfs/scrub/common.h +++ b/fs/xfs/scrub/common.h @@ -152,6 +152,9 @@ int xchk_install_inode(struct xfs_scrub *sc, struct xfs_inode *ip); void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp); void xchk_whine(const struct xfs_mount *mp, const char *fmt, ...); +void __xchk_irele(struct xfs_inode *ip, bool set_dontcache); +void xchk_irele(struct xfs_scrub *sc, struct xfs_inode *ip); + /* * Don't bother cross-referencing if we already found corruption or cross * referencing discrepancies. diff --git a/fs/xfs/scrub/dir.c b/fs/xfs/scrub/dir.c index 7881ff4754f4..81d2c8427f85 100644 --- a/fs/xfs/scrub/dir.c +++ b/fs/xfs/scrub/dir.c @@ -142,7 +142,7 @@ xchk_dir_check_ftype( if (xfs_is_metadata_inode(ip) ^ xfs_is_metadata_inode(sdc->sc->ip)) xchk_fblock_set_corrupt(sdc->sc, XFS_DATA_FORK, 0); - xfs_irele(ip); + xchk_irele(sdc->sc, ip); out: return error; } diff --git a/fs/xfs/scrub/dir_repair.c b/fs/xfs/scrub/dir_repair.c index 2d91194c83e2..00aa095535e8 100644 --- a/fs/xfs/scrub/dir_repair.c +++ b/fs/xfs/scrub/dir_repair.c @@ -173,12 +173,12 @@ xrep_dir_salvage_entry( /* Don't mix metadata and regular directory trees. */ if (xfs_is_metadata_inode(ip) ^ xfs_is_metadata_inode(rd->sc->ip)) { - xfs_irele(ip); + xchk_irele(rd->sc, ip); return 0; } key.ftype = xfs_mode_to_ftype(VFS_I(ip)->i_mode); - xfs_irele(ip); + xchk_irele(rd->sc, ip); /* Remember this for later. */ error = xblob_put(rd->dir_names, &key.name_cookie, name, key.namelen); diff --git a/fs/xfs/scrub/inode_repair.c b/fs/xfs/scrub/inode_repair.c index ab1a94147286..9d92fc0203a7 100644 --- a/fs/xfs/scrub/inode_repair.c +++ b/fs/xfs/scrub/inode_repair.c @@ -1162,8 +1162,7 @@ xrep_dinode_core( sc->tp = NULL; /* ...and reload it? */ - error = xfs_iget(sc->mp, sc->tp, ino, - XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE, 0, &sc->ip); + error = xfs_iget(sc->mp, sc->tp, ino, XFS_IGET_UNTRUSTED, 0, &sc->ip); if (error) return error; sc->ilock_flags = XFS_IOLOCK_EXCL | XFS_MMAPLOCK_EXCL; diff --git a/fs/xfs/scrub/parent.c b/fs/xfs/scrub/parent.c index 06ce60b73a9d..a0f94c5a1e26 100644 --- a/fs/xfs/scrub/parent.c +++ b/fs/xfs/scrub/parent.c @@ -285,11 +285,11 @@ xchk_parent_validate( /* Drat, parent changed. Try again! */ if (dnum != dp->i_ino) { - xfs_irele(dp); + xchk_irele(sc, dp); *try_again = true; return 0; } - xfs_irele(dp); + xchk_irele(sc, dp); /* * '..' didn't change, so check that there was only one entry @@ -302,7 +302,7 @@ xchk_parent_validate( out_unlock: xfs_iunlock(dp, XFS_IOLOCK_SHARED); out_rele: - xfs_irele(dp); + xchk_irele(sc, dp); out: return error; } diff --git a/fs/xfs/scrub/parent_repair.c b/fs/xfs/scrub/parent_repair.c index 579754a51a88..382cccf128a3 100644 --- a/fs/xfs/scrub/parent_repair.c +++ b/fs/xfs/scrub/parent_repair.c @@ -179,7 +179,7 @@ xrep_parents_iwalk( out_unlock: xfs_iunlock(dp, XFS_IOLOCK_SHARED); out_rele: - xfs_irele(dp); + xchk_irele(rps->sc, dp); return error; } @@ -221,8 +221,9 @@ xrep_parents_walk( /* Check the dentry cache to see if it thinks it knows of a parent. */ STATIC xfs_ino_t xrep_parent_check_dcache( - struct xfs_inode *dp) + struct xfs_scrub *sc) { + struct xfs_inode *dp = sc->ip; struct inode *pip = NULL; struct dentry *dentry, *parent; xfs_ino_t ret = NULLFSINO; @@ -248,7 +249,7 @@ xrep_parent_check_dcache( if (S_ISDIR(pip->i_mode)) ret = XFS_I(pip)->i_ino; - xfs_irele(XFS_I(pip)); + xchk_irele(sc, XFS_I(pip)); out_dput: dput(dentry); @@ -377,7 +378,7 @@ xrep_dir_parent_find( } /* Maybe the dcache will supply us with a parent? */ - suggestion = xrep_parent_check_dcache(sc->ip); + suggestion = xrep_parent_check_dcache(sc); if (!xfs_verify_dir_ino(sc->mp, suggestion)) { error = xrep_dir_parent_check(sc, suggestion, &is_parent); if (error) diff --git a/fs/xfs/scrub/quotacheck.c b/fs/xfs/scrub/quotacheck.c index 1717e0f30cdd..b0baa76cef1e 100644 --- a/fs/xfs/scrub/quotacheck.c +++ b/fs/xfs/scrub/quotacheck.c @@ -493,7 +493,7 @@ xqcheck_collect_counts( struct xfs_scrub *sc = xqc->sc; struct xfs_inode *ip; xfs_ino_t ino = 0; - int flags = XFS_IGET_UNTRUSTED | XFS_IGET_DONTCACHE; + int flags = XFS_IGET_UNTRUSTED; unsigned int retries = 20; int error; @@ -505,7 +505,7 @@ xqcheck_collect_counts( switch (error) { case 0: error = xqcheck_inode(xqc, ip); - xfs_irele(ip); + xchk_irele(sc, ip); if (error) return error; retries = 20; diff --git a/fs/xfs/scrub/rmap_repair.c b/fs/xfs/scrub/rmap_repair.c index 6d40d6fbf1fa..c5212686f257 100644 --- a/fs/xfs/scrub/rmap_repair.c +++ b/fs/xfs/scrub/rmap_repair.c @@ -616,8 +616,7 @@ xrep_rmap_scan_inode( int error; /* Grab inode and lock it so we can scan it. */ - error = xfs_iget(mp, rr->sc->tp, ino, - XFS_IGET_DONTCACHE | XFS_IGET_UNLINKED, 0, &ip); + error = xfs_iget(mp, rr->sc->tp, ino, XFS_IGET_UNLINKED, 0, &ip); if (error) return error; @@ -637,7 +636,7 @@ xrep_rmap_scan_inode( out_unlock: xfs_iunlock(ip, lock_mode); - xfs_irele(ip); + xchk_irele(rr->sc, ip); return error; } diff --git a/fs/xfs/scrub/rtrmap_repair.c b/fs/xfs/scrub/rtrmap_repair.c index 34b1ed463cdd..1605364a4403 100644 --- a/fs/xfs/scrub/rtrmap_repair.c +++ b/fs/xfs/scrub/rtrmap_repair.c @@ -351,8 +351,7 @@ xrep_rtrmap_scan_inode( return 0; /* Grab inode and lock it so we can scan it. */ - error = xfs_iget(mp, rr->sc->tp, ino, - XFS_IGET_DONTCACHE | XFS_IGET_UNLINKED, 0, &ip); + error = xfs_iget(mp, rr->sc->tp, ino, XFS_IGET_UNLINKED, 0, &ip); if (error) return error; @@ -379,7 +378,7 @@ xrep_rtrmap_scan_inode( out_unlock: xfs_iunlock(ip, XFS_ILOCK_SHARED); out_rele: - xfs_irele(ip); + xchk_irele(rr->sc, ip); return error; } diff --git a/fs/xfs/scrub/scrub.c b/fs/xfs/scrub/scrub.c index e54bbe98a8c5..e1a2367e9042 100644 --- a/fs/xfs/scrub/scrub.c +++ b/fs/xfs/scrub/scrub.c @@ -170,7 +170,7 @@ xchk_teardown( if (sc->ip) { if (sc->ilock_flags) xfs_iunlock(sc->ip, sc->ilock_flags); - xfs_irele(sc->ip); + xchk_irele(sc, sc->ip); sc->ip = NULL; } if (sc->flags & XREP_ATOMIC_SWAPEXT) { @@ -725,7 +725,8 @@ xfs_scrubv_metadata( * consider setting dontcache at the end. */ if (v->sv_type < XFS_SCRUB_TYPE_NR && - meta_scrub_ops[v->sv_type].type == ST_INODE) + meta_scrub_ops[v->sv_type].type == ST_INODE && + !(vhead->svh_flags & XFS_SCRUB_VEC_IFLAG_RETAIN_INODES)) set_dontcache = true; trace_xchk_scrubv_item(mp, vhead, v); @@ -742,7 +743,7 @@ xfs_scrubv_metadata( if (ip && (VFS_I(ip)->i_generation != vhead->svh_gen || (xfs_is_metadata_inode(ip) && !S_ISDIR(VFS_I(ip)->i_mode)))) { - xfs_irele(ip); + __xchk_irele(ip, set_dontcache); ip = NULL; } } @@ -797,8 +798,6 @@ xfs_scrubv_metadata( * If we're holding the only reference to this inode and the scan was * clean, mark it dontcache so that we don't pollute the cache. */ - if (set_dontcache && atomic_read(&VFS_I(ip)->i_count) == 1) - d_mark_dontcache(VFS_I(ip)); - xfs_irele(ip); + __xchk_irele(ip, set_dontcache); return error; } |