• Dave Chinner's avatar
    xfs: xfs_attr_inactive leaves inconsistent attr fork state behind · 3a1d406d
    Dave Chinner authored
    commit 6dfe5a04 upstream.
    
    xfs_attr_inactive() is supposed to clean up the attribute fork when
    the inode is being freed. While it removes attribute fork extents,
    it completely ignores attributes in local format, which means that
    there can still be active attributes on the inode after
    xfs_attr_inactive() has run.
    
    This leads to problems with concurrent inode writeback - the in-core
    inode attribute fork is removed without locking on the assumption
    that nothing will be attempting to access the attribute fork after a
    call to xfs_attr_inactive() because it isn't supposed to exist on
    disk any more.
    
    To fix this, make xfs_attr_inactive() completely remove all traces
    of the attribute fork from the inode, regardless of it's state.
    Further, also remove the in-core attribute fork structure safely so
    that there is nothing further that needs to be done by callers to
    clean up the attribute fork. This means we can remove the in-core
    and on-disk attribute forks atomically.
    
    Also, on error simply remove the in-memory attribute fork. There's
    nothing that can be done with it once we have failed to remove the
    on-disk attribute fork, so we may as well just blow it away here
    anyway.
    Reported-by: default avatarWaiman Long <waiman.long@hp.com>
    Signed-off-by: default avatarDave Chinner <dchinner@redhat.com>
    Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
    Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
    [ luis: backported to 3.16:
      - no libxfs in 3.16, xfs_attr_leaf.{c,h} in fs/xfs/ dir
      - adjusted context ]
    Signed-off-by: default avatarLuis Henriques <luis.henriques@canonical.com>
    3a1d406d
xfs_attr_leaf.c 76 KB