mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-26 10:49:33 +00:00
xfs: get our own reference to inodes that we want to scrub
When we want to scrub a file, get our own reference to the inode unconditionally. This will make disposal rules simpler in the long run. Signed-off-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Dave Chinner <dchinner@redhat.com>
This commit is contained in:
parent
d7a74cad8f
commit
1730853950
6 changed files with 37 additions and 14 deletions
|
@ -831,6 +831,25 @@ xchk_install_handle_inode(
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Install an already-referenced inode for scrubbing. Get our own reference to
|
||||
* the inode to make disposal simpler. The inode must not be in I_FREEING or
|
||||
* I_WILL_FREE state!
|
||||
*/
|
||||
int
|
||||
xchk_install_live_inode(
|
||||
struct xfs_scrub *sc,
|
||||
struct xfs_inode *ip)
|
||||
{
|
||||
if (!igrab(VFS_I(ip))) {
|
||||
xchk_ino_set_corrupt(sc, ip->i_ino);
|
||||
return -EFSCORRUPTED;
|
||||
}
|
||||
|
||||
sc->ip = ip;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* In preparation to scrub metadata structures that hang off of an inode,
|
||||
* grab either the inode referenced in the scrub control structure or the
|
||||
|
@ -854,10 +873,8 @@ xchk_iget_for_scrubbing(
|
|||
ASSERT(sc->tp == NULL);
|
||||
|
||||
/* We want to scan the inode we already had opened. */
|
||||
if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
|
||||
sc->ip = ip_in;
|
||||
return 0;
|
||||
}
|
||||
if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino)
|
||||
return xchk_install_live_inode(sc, ip_in);
|
||||
|
||||
/* Reject internal metadata files and obviously bad inode numbers. */
|
||||
if (xfs_internal_inum(mp, sc->sm->sm_ino))
|
||||
|
|
|
@ -137,6 +137,7 @@ int xchk_count_rmap_ownedby_ag(struct xfs_scrub *sc, struct xfs_btree_cur *cur,
|
|||
int xchk_setup_ag_btree(struct xfs_scrub *sc, bool force_log);
|
||||
int xchk_iget_for_scrubbing(struct xfs_scrub *sc);
|
||||
int xchk_setup_inode_contents(struct xfs_scrub *sc, unsigned int resblks);
|
||||
int xchk_install_live_inode(struct xfs_scrub *sc, struct xfs_inode *ip);
|
||||
void xchk_buffer_recheck(struct xfs_scrub *sc, struct xfs_buf *bp);
|
||||
|
||||
int xchk_iget(struct xfs_scrub *sc, xfs_ino_t inum, struct xfs_inode **ipp);
|
||||
|
|
|
@ -83,7 +83,10 @@ xchk_setup_inode(
|
|||
|
||||
/* We want to scan the opened inode, so lock it and exit. */
|
||||
if (sc->sm->sm_ino == 0 || sc->sm->sm_ino == ip_in->i_ino) {
|
||||
sc->ip = ip_in;
|
||||
error = xchk_install_live_inode(sc, ip_in);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return xchk_prepare_iscrub(sc);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,7 +59,11 @@ xchk_setup_quota(
|
|||
error = xchk_setup_fs(sc);
|
||||
if (error)
|
||||
return error;
|
||||
sc->ip = xfs_quota_inode(sc->mp, dqtype);
|
||||
|
||||
error = xchk_install_live_inode(sc, xfs_quota_inode(sc->mp, dqtype));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
xfs_ilock(sc->ip, XFS_ILOCK_EXCL);
|
||||
sc->ilock_flags = XFS_ILOCK_EXCL;
|
||||
return 0;
|
||||
|
|
|
@ -28,10 +28,12 @@ xchk_setup_rt(
|
|||
if (error)
|
||||
return error;
|
||||
|
||||
sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
|
||||
sc->ip = sc->mp->m_rbmip;
|
||||
xfs_ilock(sc->ip, sc->ilock_flags);
|
||||
error = xchk_install_live_inode(sc, sc->mp->m_rbmip);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
sc->ilock_flags = XFS_ILOCK_EXCL | XFS_ILOCK_RTBITMAP;
|
||||
xfs_ilock(sc->ip, sc->ilock_flags);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -167,8 +167,6 @@ xchk_teardown(
|
|||
struct xfs_scrub *sc,
|
||||
int error)
|
||||
{
|
||||
struct xfs_inode *ip_in = XFS_I(file_inode(sc->file));
|
||||
|
||||
xchk_ag_free(sc, &sc->sa);
|
||||
if (sc->tp) {
|
||||
if (error == 0 && (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR))
|
||||
|
@ -180,9 +178,7 @@ xchk_teardown(
|
|||
if (sc->ip) {
|
||||
if (sc->ilock_flags)
|
||||
xfs_iunlock(sc->ip, sc->ilock_flags);
|
||||
if (sc->ip != ip_in &&
|
||||
!xfs_internal_inum(sc->mp, sc->ip->i_ino))
|
||||
xchk_irele(sc, sc->ip);
|
||||
xchk_irele(sc, sc->ip);
|
||||
sc->ip = NULL;
|
||||
}
|
||||
if (sc->sm->sm_flags & XFS_SCRUB_IFLAG_REPAIR)
|
||||
|
|
Loading…
Reference in a new issue