Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 410b11a6 authored by Brian Foster's avatar Brian Foster Committed by Dave Chinner
Browse files

xfs: use tr_qm_dqalloc log reservation for dquot alloc



The dquot allocation path in xfs_qm_dqread() currently uses the
attribute set log reservation, which appears to be incorrect. We
have reports of transaction reservation overruns with the current
code. E.g., a repeated run of xfstests test generic/270 on a 512b
block size fs occassionally produces the following in dmesg:

	XFS (sdN): xlog_write: reservation summary:
	  trans type  = QM_DQALLOC (30)
	  unit res    = 7080 bytes
	  current res = -632 bytes
	  total reg   = 0 bytes (o/flow = 0 bytes)
	  ophdrs      = 0 (ophdr space = 0 bytes)
	  ophdr + reg = 0 bytes
	  num regions = 0

	XFS (sdN): xlog_write: reservation ran out. Need to up reservation

The dquot allocation case should consist of a write reservation
(i.e., we are allocating a range of the internal quota file) plus
the size of the actual dquots. We already have a log reservation
definition for this operation (tr_qm_dqalloc). Use it in
xfs_qm_dqread() and update the log reservation calculation function
to use the write res. calculation function rather than reading the
assumed to be pre-calculated value directly.

Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarJie Liu <jeff.liu@oracle.com>
Reviewed-by: default avatarBen Myers <bpm@sgi.com>
Signed-off-by: default avatarDave Chinner <david@fromorbit.com>
parent c19ec235
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -615,7 +615,7 @@ xfs_qm_dqread(


	if (flags & XFS_QMOPT_DQALLOC) {
	if (flags & XFS_QMOPT_DQALLOC) {
		tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC);
		tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC);
		error = xfs_trans_reserve(tp, &M_RES(mp)->tr_attrsetm,
		error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_dqalloc,
					  XFS_QM_DQALLOC_SPACE_RES(mp), 0);
					  XFS_QM_DQALLOC_SPACE_RES(mp), 0);
		if (error)
		if (error)
			goto error1;
			goto error1;
+2 −3
Original line number Original line Diff line number Diff line
@@ -644,15 +644,14 @@ xfs_calc_qm_setqlim_reservation(


/*
/*
 * Allocating quota on disk if needed.
 * Allocating quota on disk if needed.
 *	the write transaction log space: M_RES(mp)->tr_write.tr_logres
 *	the write transaction log space for quota file extent allocation
 *	the unit of quota allocation: one system block size
 *	the unit of quota allocation: one system block size
 */
 */
STATIC uint
STATIC uint
xfs_calc_qm_dqalloc_reservation(
xfs_calc_qm_dqalloc_reservation(
	struct xfs_mount	*mp)
	struct xfs_mount	*mp)
{
{
	ASSERT(M_RES(mp)->tr_write.tr_logres);
	return xfs_calc_write_reservation(mp) +
	return M_RES(mp)->tr_write.tr_logres +
		xfs_calc_buf_res(1,
		xfs_calc_buf_res(1,
			XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
			XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1);
}
}