diff options
author | Brian Foster <bfoster@redhat.com> | 2014-02-06 22:55:54 -0500 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2014-02-06 22:55:54 -0500 |
commit | 410b11a675dca827e893f07c3155691eda3b5887 (patch) | |
tree | a9a176e4ed1cdc9c272192860ca42fc8e968af92 /fs/xfs | |
parent | c19ec235352c2a001c9dc7e86acdfd9f2b62150d (diff) |
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: Brian Foster <bfoster@redhat.com>
Reviewed-by: Jie Liu <jeff.liu@oracle.com>
Reviewed-by: Ben Myers <bpm@sgi.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r-- | fs/xfs/xfs_dquot.c | 2 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_resv.c | 5 |
2 files changed, 3 insertions, 4 deletions
diff --git a/fs/xfs/xfs_dquot.c b/fs/xfs/xfs_dquot.c index 7aeb4c895b32..868b19f096bf 100644 --- a/fs/xfs/xfs_dquot.c +++ b/fs/xfs/xfs_dquot.c | |||
@@ -615,7 +615,7 @@ xfs_qm_dqread( | |||
615 | 615 | ||
616 | if (flags & XFS_QMOPT_DQALLOC) { | 616 | if (flags & XFS_QMOPT_DQALLOC) { |
617 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC); | 617 | tp = xfs_trans_alloc(mp, XFS_TRANS_QM_DQALLOC); |
618 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_attrsetm, | 618 | error = xfs_trans_reserve(tp, &M_RES(mp)->tr_qm_dqalloc, |
619 | XFS_QM_DQALLOC_SPACE_RES(mp), 0); | 619 | XFS_QM_DQALLOC_SPACE_RES(mp), 0); |
620 | if (error) | 620 | if (error) |
621 | goto error1; | 621 | goto error1; |
diff --git a/fs/xfs/xfs_trans_resv.c b/fs/xfs/xfs_trans_resv.c index c9d2708dd74d..8515b0449dc8 100644 --- a/fs/xfs/xfs_trans_resv.c +++ b/fs/xfs/xfs_trans_resv.c | |||
@@ -644,15 +644,14 @@ xfs_calc_qm_setqlim_reservation( | |||
644 | 644 | ||
645 | /* | 645 | /* |
646 | * Allocating quota on disk if needed. | 646 | * Allocating quota on disk if needed. |
647 | * the write transaction log space: M_RES(mp)->tr_write.tr_logres | 647 | * the write transaction log space for quota file extent allocation |
648 | * the unit of quota allocation: one system block size | 648 | * the unit of quota allocation: one system block size |
649 | */ | 649 | */ |
650 | STATIC uint | 650 | STATIC uint |
651 | xfs_calc_qm_dqalloc_reservation( | 651 | xfs_calc_qm_dqalloc_reservation( |
652 | struct xfs_mount *mp) | 652 | struct xfs_mount *mp) |
653 | { | 653 | { |
654 | ASSERT(M_RES(mp)->tr_write.tr_logres); | 654 | return xfs_calc_write_reservation(mp) + |
655 | return M_RES(mp)->tr_write.tr_logres + | ||
656 | xfs_calc_buf_res(1, | 655 | xfs_calc_buf_res(1, |
657 | XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); | 656 | XFS_FSB_TO_B(mp, XFS_DQUOT_CLUSTER_SIZE_FSB) - 1); |
658 | } | 657 | } |