summaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_qm_syscalls.c
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2018-05-05 00:30:19 +0200
committerDarrick J. Wong <darrick.wong@oracle.com>2018-05-10 17:56:47 +0200
commit7b6b50f55c1064e619f2da0696ed99f9db10b960 (patch)
tree141b3a966adcb0249c9f81d7c217a6c53fdf932e /fs/xfs/xfs_qm_syscalls.c
parentxfs: don't discard on free of unwritten extents (diff)
downloadlinux-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