• Brian Foster's avatar
    xfs: don't truncate attribute extents if no extents exist · 5abab6ef
    Brian Foster authored
    commit f66bf042 upstream.
    
    The xfs_attr3_root_inactive() call from xfs_attr_inactive() assumes that
    attribute blocks exist to invalidate. It is possible to have an
    attribute fork without extents, however. Consider the case where the
    attribute fork is created towards the beginning of xfs_attr_set() but
    some part of the subsequent attribute set fails.
    
    If an inode in such a state hits xfs_attr_inactive(), it eventually
    calls xfs_dabuf_map() and possibly xfs_bmapi_read(). The former emits a
    filesystem corruption warning, returns an error that bubbles back up to
    xfs_attr_inactive(), and leads to destruction of the in-core attribute
    fork without an on-disk reset. If the inode happens to make it back
    through xfs_inactive() in this state (e.g., via a concurrent bulkstat
    that cycles the inode from the reclaim state and releases it), i_afp
    might not exist when xfs_bmapi_read() is called and causes a NULL
    dereference panic.
    
    A '-p 2' fsstress run to ENOSPC on a relatively small fs (1GB)
    reproduces these problems. The behavior is a regression caused by:
    
    6dfe5a04 xfs: xfs_attr_inactive leaves inconsistent attr fork state behind
    
    ... which removed logic that avoided the attribute extent truncate when
    no extents exist. Restore this logic to ensure the attribute fork is
    destroyed and reset correctly if it exists without any allocated
    extents.
    Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
    Reviewed-by: default avatarDave Chinner <dchinner@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    5abab6ef
xfs_attr_inactive.c 11.8 KB