Skip to content
  • Brian Foster's avatar
    xfs: refactor xfs_buf_log_item reference count handling · 95808459
    Brian Foster authored
    
    
    The xfs_buf_log_item structure has a reference counter with slightly
    tricky semantics. In the common case, a buffer is logged and
    committed in a transaction, committed to the on-disk log (added to
    the AIL) and then finally written back and removed from the AIL. The
    bli refcount covers two potentially overlapping timeframes:
    
     1. the bli is held in an active transaction
     2. the bli is pinned by the log
    
    The caveat to this approach is that the reference counter does not
    purely dictate the lifetime of the bli. IOW, when a dirty buffer is
    physically logged and unpinned, the bli refcount may go to zero as
    the log item is inserted into the AIL. Only once the buffer is
    written back can the bli finally be freed.
    
    The above semantics means that it is not enough for the various
    refcount decrementing contexts to release the bli on decrement to
    zero. xfs_trans_brelse(), transaction commit (->iop_unlock()) and
    unpin (->iop_unpin()) must all drop the associated reference and
    make additional checks to determine if the current context is
    responsible for freeing the item.
    
    For example, if a transaction holds but does not dirty a particular
    bli, the commit may drop the refcount to zero. If the bli itself is
    clean, it is also not AIL resident and must be freed at this time.
    The same is true for xfs_trans_brelse(). If the transaction dirties
    a bli and then aborts or an unpin results in an abort due to a log
    I/O error, the last reference count holder is expected to explicitly
    remove the item from the AIL and release it (since an abort means
    filesystem shutdown and metadata writeback will never occur).
    
    This leads to fairly complex checks being replicated in a few
    different places. Since ->iop_unlock() and xfs_trans_brelse() are
    nearly identical, refactor the logic into a common helper that
    implements and documents the semantics in one place. This patch does
    not change behavior.
    
    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>
    
    95808459