Commit 2ba13721 authored by Brian Foster's avatar Brian Foster Committed by Darrick J. Wong

xfs: use ->t_dfops in dqalloc transaction

xfs_dquot_disk_alloc() receives a transaction from the caller and
passes a local dfops along to xfs_bmapi_write(). If we attach this
dfops to the transaction, we have to make sure to clear it before
returning to avoid invalid access of stack memory.

Since xfs_qm_dqread_alloc() is the only caller, pull dfops into the
caller and attach it to the transaction to eliminate this pattern
entirely.
Signed-off-by: default avatarBrian Foster <bfoster@redhat.com>
Reviewed-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
Signed-off-by: default avatarDarrick J. Wong <darrick.wong@oracle.com>
parent 32a9b7c6
...@@ -286,8 +286,8 @@ xfs_dquot_disk_alloc( ...@@ -286,8 +286,8 @@ xfs_dquot_disk_alloc(
struct xfs_buf **bpp) struct xfs_buf **bpp)
{ {
struct xfs_bmbt_irec map; struct xfs_bmbt_irec map;
struct xfs_defer_ops dfops; struct xfs_trans *tp = *tpp;
struct xfs_mount *mp = (*tpp)->t_mountp; struct xfs_mount *mp = tp->t_mountp;
struct xfs_buf *bp; struct xfs_buf *bp;
struct xfs_inode *quotip = xfs_quota_inode(mp, dqp->dq_flags); struct xfs_inode *quotip = xfs_quota_inode(mp, dqp->dq_flags);
xfs_fsblock_t firstblock; xfs_fsblock_t firstblock;
...@@ -296,7 +296,8 @@ xfs_dquot_disk_alloc( ...@@ -296,7 +296,8 @@ xfs_dquot_disk_alloc(
trace_xfs_dqalloc(dqp); trace_xfs_dqalloc(dqp);
xfs_defer_init(&dfops, &firstblock); xfs_defer_init(tp->t_dfops, &firstblock);
xfs_ilock(quotip, XFS_ILOCK_EXCL); xfs_ilock(quotip, XFS_ILOCK_EXCL);
if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) { if (!xfs_this_quota_on(dqp->q_mount, dqp->dq_flags)) {
/* /*
...@@ -308,11 +309,11 @@ xfs_dquot_disk_alloc( ...@@ -308,11 +309,11 @@ xfs_dquot_disk_alloc(
} }
/* Create the block mapping. */ /* Create the block mapping. */
xfs_trans_ijoin(*tpp, quotip, XFS_ILOCK_EXCL); xfs_trans_ijoin(tp, quotip, XFS_ILOCK_EXCL);
error = xfs_bmapi_write(*tpp, quotip, dqp->q_fileoffset, error = xfs_bmapi_write(tp, quotip, dqp->q_fileoffset,
XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA, XFS_DQUOT_CLUSTER_SIZE_FSB, XFS_BMAPI_METADATA,
&firstblock, XFS_QM_DQALLOC_SPACE_RES(mp), &firstblock, XFS_QM_DQALLOC_SPACE_RES(mp),
&map, &nmaps, &dfops); &map, &nmaps, tp->t_dfops);
if (error) if (error)
goto error0; goto error0;
ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB); ASSERT(map.br_blockcount == XFS_DQUOT_CLUSTER_SIZE_FSB);
...@@ -326,7 +327,7 @@ xfs_dquot_disk_alloc( ...@@ -326,7 +327,7 @@ xfs_dquot_disk_alloc(
dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock); dqp->q_blkno = XFS_FSB_TO_DADDR(mp, map.br_startblock);
/* now we can just get the buffer (there's nothing to read yet) */ /* now we can just get the buffer (there's nothing to read yet) */
bp = xfs_trans_get_buf(*tpp, mp->m_ddev_targp, dqp->q_blkno, bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, dqp->q_blkno,
mp->m_quotainfo->qi_dqchunklen, 0); mp->m_quotainfo->qi_dqchunklen, 0);
if (!bp) { if (!bp) {
error = -ENOMEM; error = -ENOMEM;
...@@ -338,7 +339,7 @@ xfs_dquot_disk_alloc( ...@@ -338,7 +339,7 @@ xfs_dquot_disk_alloc(
* Make a chunk of dquots out of this buffer and log * Make a chunk of dquots out of this buffer and log
* the entire thing. * the entire thing.
*/ */
xfs_qm_init_dquot_blk(*tpp, mp, be32_to_cpu(dqp->q_core.d_id), xfs_qm_init_dquot_blk(tp, mp, be32_to_cpu(dqp->q_core.d_id),
dqp->dq_flags & XFS_DQ_ALLTYPES, bp); dqp->dq_flags & XFS_DQ_ALLTYPES, bp);
xfs_buf_set_ref(bp, XFS_DQUOT_REF); xfs_buf_set_ref(bp, XFS_DQUOT_REF);
...@@ -364,14 +365,15 @@ xfs_dquot_disk_alloc( ...@@ -364,14 +365,15 @@ xfs_dquot_disk_alloc(
* is responsible for unlocking any buffer passed back, either * is responsible for unlocking any buffer passed back, either
* manually or by committing the transaction. * manually or by committing the transaction.
*/ */
xfs_trans_bhold(*tpp, bp); xfs_trans_bhold(tp, bp);
error = xfs_defer_bjoin(&dfops, bp); error = xfs_defer_bjoin(tp->t_dfops, bp);
if (error) { if (error) {
xfs_trans_bhold_release(*tpp, bp); xfs_trans_bhold_release(tp, bp);
xfs_trans_brelse(*tpp, bp); xfs_trans_brelse(tp, bp);
goto error1; goto error1;
} }
error = xfs_defer_finish(tpp, &dfops); error = xfs_defer_finish(tpp, tp->t_dfops);
tp = *tpp;
if (error) { if (error) {
xfs_buf_relse(bp); xfs_buf_relse(bp);
goto error1; goto error1;
...@@ -380,7 +382,7 @@ xfs_dquot_disk_alloc( ...@@ -380,7 +382,7 @@ xfs_dquot_disk_alloc(
return 0; return 0;
error1: error1:
xfs_defer_cancel(&dfops); xfs_defer_cancel(tp->t_dfops);
error0: error0:
return error; return error;
} }
...@@ -538,13 +540,17 @@ xfs_qm_dqread_alloc( ...@@ -538,13 +540,17 @@ xfs_qm_dqread_alloc(
struct xfs_buf **bpp) struct xfs_buf **bpp)
{ {
struct xfs_trans *tp; struct xfs_trans *tp;
struct xfs_defer_ops dfops;
struct xfs_buf *bp; struct xfs_buf *bp;
xfs_fsblock_t firstblock;
int error; int error;
error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc, error = xfs_trans_alloc(mp, &M_RES(mp)->tr_qm_dqalloc,
XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp); XFS_QM_DQALLOC_SPACE_RES(mp), 0, 0, &tp);
if (error) if (error)
goto err; goto err;
xfs_defer_init(&dfops, &firstblock);
tp->t_dfops = &dfops;
error = xfs_dquot_disk_alloc(&tp, dqp, &bp); error = xfs_dquot_disk_alloc(&tp, dqp, &bp);
if (error) if (error)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment