diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2018-05-05 00:30:19 +0200 |
---|---|---|
committer | Darrick J. Wong <darrick.wong@oracle.com> | 2018-05-10 17:56:47 +0200 |
commit | 7b6b50f55c1064e619f2da0696ed99f9db10b960 (patch) | |
tree | 141b3a966adcb0249c9f81d7c217a6c53fdf932e /fs/xfs/xfs_qm_syscalls.c | |
parent | xfs: don't discard on free of unwritten extents (diff) | |
download | linux-7b6b50f55c1064e619f2da0696ed99f9db10b960.tar.xz linux-7b6b50f55c1064e619f2da0696ed99f9db10b960.zip |
xfs: release new dquot buffer on defer_finish error
In commit efa092f3d4c6 "[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
310a75a3c6c747 ("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: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Brian Foster <bfoster@redhat.com>
Diffstat (limited to 'fs/xfs/xfs_qm_syscalls.c')
0 files changed, 0 insertions, 0 deletions