• Darrick J. Wong's avatar
    xfs: retain the AGI when we can't iget an inode to scrub the core · 38bb1310
    Darrick J. Wong authored
    xchk_get_inode is not quite the right function to be calling from the
    inode scrubber setup function.  The common get_inode function either
    gets an inode and installs it in the scrub context, or it returns an
    error code explaining what happened.  This is acceptable for most file
    scrubbers because it is not in their scope to fix corruptions in the
    inode core and fork areas that cause iget to fail.
    
    Dealing with these problems is within the scope of the inode scrubber,
    however.  If iget fails with EFSCORRUPTED, we need to xchk_inode to flag
    that as corruption.  Since we can't get our hands on an incore inode, we
    need to hold the AGI to prevent inode allocation activity so that
    nothing changes in the inode metadata.
    
    Looking ahead to the inode core repair patches, we will also need to
    hold the AGI buffer into xrep_inode so that we can make modifications to
    the xfs_dinode structure without any other thread swooping in to
    allocate or free the inode.
    
    Adapt the xchk_get_inode into xchk_setup_inode since this is a one-off
    use case where the error codes we check for are a little different, and
    the return state is much different from the common function.
    
    xchk_setup_inode prepares to check or repair an inode record, so it must
    continue the scrub operation even if the inode/inobt verifiers cause
    xfs_iget to return EFSCORRUPTED.  This is done by attaching the locked
    AGI buffer to the scrub transaction and returning 0 to move on to the
    actual scrub.  (Later, the online inode repair code will also want the
    xfs_imap structure so that it can reset the ondisk xfs_dinode
    structure.)
    
    xchk_get_inode retrieves an inode on behalf of a scrubber that operates
    on an incore inode -- data/attr/cow forks, directories, xattrs,
    symlinks, parent pointers, etc.  If the inode/inobt verifiers fail and
    xfs_iget returns EFSCORRUPTED, we want to exit to userspace (because the
    caller should be fix the inode first) and drop everything we acquired
    along the way.
    
    A behavior common to both functions is that it's possible that xfs_scrub
    asked for a scrub-by-handle concurrent with the inode being freed or the
    passed-in inumber is invalid.  In this case, we call xfs_imap to see if
    the inobt index thinks the inode is allocated, and return ENOENT
    ("nothing to check here") to userspace if this is not the case.  The
    imap lookup is why both functions call xchk_iget_agi.
    Signed-off-by: default avatarDarrick J. Wong <djwong@kernel.org>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    38bb1310
common.c 30.1 KB