• Darrick J. Wong's avatar
    xfs: release new dquot buffer on defer_finish error · 7b6b50f5
    Darrick J. Wong authored
    In commit efa092f3 "[XFS] Fixes a bug in the quota code when
    allocating a new dquot record", we allocate a new dquot block, grab a
    buffer to initialize it, and return the locked initialized dquot buffer
    to the caller for further in-core dquot initialization.  Unfortunately,
    if the _bmap_finish errored out, _qm_dqalloc would also error out
    without bothering to free the (locked) buffer.  Leaking a locked buffer
    caused hangs in generic/388 when quotas are enabled.
    
    Furthermore, the _bmap_finish -> _defer_finish conversion in
    310a75a3 ("xfs: change xfs_bmap_{finish,cancel,init,free} ->
    xfs_defer_*") failed to observe that the buffer was held going into
    _defer_finish and therefore failed to notice that the buffer lock is
    /not/ maintained afterwards.  Now that we can bjoin a buffer to a
    defer_ops, use this mechanism to ensure that the buffer stays locked
    across the _defer_finish.  Release the holds and locks on the buffer as
    appropriate if we have to error out.
    
    There is a subtlety here for the caller in that the buffer emerges
    locked and held to the transaction, so if the _trans_commit fails we
    have to release the buffer explicitly.  This fixes the unmount hang
    in generic/388 when quotas are enabled.
    Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
    Reviewed-by: default avatarBrian Foster <bfoster@redhat.com>
    7b6b50f5
xfs_dquot.c 29 KB