From: Brian Foster <bfoster@redhat.com>
To: Dave Chinner <david@fromorbit.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH 04/14 V2] xfs: avoid nesting transactions in xfs_qm_scall_setqlim()
Date: Tue, 21 May 2013 06:51:08 -0400 [thread overview]
Message-ID: <519B519C.5030405@redhat.com> (raw)
In-Reply-To: <20130521003647.GK24543@dastard>
On 05/20/2013 08:36 PM, Dave Chinner wrote:
> From: Dave Chinner <dchinner@redhat.com>
>
> Lockdep reports:
>
> =============================================
> [ INFO: possible recursive locking detected ]
> 3.9.0+ #3 Not tainted
> ---------------------------------------------
> setquota/28368 is trying to acquire lock:
> (sb_internal){++++.?}, at: [<c11e8846>] xfs_trans_alloc+0x26/0x50
>
> but task is already holding lock:
> (sb_internal){++++.?}, at: [<c11e8846>] xfs_trans_alloc+0x26/0x50
>
> from xfs_qm_scall_setqlim()->xfs_dqread() when a dquot needs to be
> allocated.
>
> xfs_qm_scall_setqlim() is starting a transaction and then not
> passing it into xfs_qm_dqet() and so it starts it's own transaction
> when allocating the dquot. Splat!
>
> Fix this by not allocating the dquot in xfs_qm_scall_setqlim()
> inside the setqlim transaction. This requires getting the dquot
> first (and allocating it if necessary) then dropping and relocking
> the dquot before joining it to the setqlim transaction.
>
> Reported-by: Michael L. Semon <mlsemon35@gmail.com>
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> ---
> V2: fix error handling path that failed to release the dquot.
>
Looks good.
Reviewed-by: Brian Foster <bfoster@redhat.com>
> fs/xfs/xfs_qm_syscalls.c | 40 +++++++++++++++++++++++-----------------
> 1 file changed, 23 insertions(+), 17 deletions(-)
>
> diff --git a/fs/xfs/xfs_qm_syscalls.c b/fs/xfs/xfs_qm_syscalls.c
> index c41190c..6cdf6ff 100644
> --- a/fs/xfs/xfs_qm_syscalls.c
> +++ b/fs/xfs/xfs_qm_syscalls.c
> @@ -489,31 +489,36 @@ xfs_qm_scall_setqlim(
> if ((newlim->d_fieldmask & XFS_DQ_MASK) == 0)
> return 0;
>
> - tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
> - error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp),
> - 0, 0, XFS_DEFAULT_LOG_COUNT);
> - if (error) {
> - xfs_trans_cancel(tp, 0);
> - return (error);
> - }
> -
> /*
> * We don't want to race with a quotaoff so take the quotaoff lock.
> - * (We don't hold an inode lock, so there's nothing else to stop
> - * a quotaoff from happening). (XXXThis doesn't currently happen
> - * because we take the vfslock before calling xfs_qm_sysent).
> + * We don't hold an inode lock, so there's nothing else to stop
> + * a quotaoff from happening.
> */
> mutex_lock(&q->qi_quotaofflock);
>
> /*
> - * Get the dquot (locked), and join it to the transaction.
> - * Allocate the dquot if this doesn't exist.
> + * Get the dquot (locked) before we start, as we need to do a
> + * transaction to allocate it if it doesn't exist. Once we have the
> + * dquot, unlock it so we can start the next transaction safely. We hold
> + * a reference to the dquot, so it's safe to do this unlock/lock without
> + * it being reclaimed in the mean time.
> */
> - if ((error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp))) {
> - xfs_trans_cancel(tp, XFS_TRANS_ABORT);
> + error = xfs_qm_dqget(mp, NULL, id, type, XFS_QMOPT_DQALLOC, &dqp);
> + if (error) {
> ASSERT(error != ENOENT);
> goto out_unlock;
> }
> + xfs_dqunlock(dqp);
> +
> + tp = xfs_trans_alloc(mp, XFS_TRANS_QM_SETQLIM);
> + error = xfs_trans_reserve(tp, 0, XFS_QM_SETQLIM_LOG_RES(mp),
> + 0, 0, XFS_DEFAULT_LOG_COUNT);
> + if (error) {
> + xfs_trans_cancel(tp, 0);
> + goto out_rele;
> + }
> +
> + xfs_dqlock(dqp);
> xfs_trans_dqjoin(tp, dqp);
> ddq = &dqp->q_core;
>
> @@ -621,9 +626,10 @@ xfs_qm_scall_setqlim(
> xfs_trans_log_dquot(tp, dqp);
>
> error = xfs_trans_commit(tp, 0);
> - xfs_qm_dqrele(dqp);
>
> - out_unlock:
> +out_rele:
> + xfs_qm_dqrele(dqp);
> +out_unlock:
> mutex_unlock(&q->qi_quotaofflock);
> return error;
> }
>
> _______________________________________________
> xfs mailing list
> xfs@oss.sgi.com
> http://oss.sgi.com/mailman/listinfo/xfs
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2013-05-21 10:54 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-05-19 23:51 [PATCH 00/14] xfs: fixes for 3.10-rc2 (update) Dave Chinner
2013-05-19 23:51 ` [PATCH 01/14] xfs: fix sub-page blocksize data integrity writes Dave Chinner
2013-05-20 18:02 ` Brian Foster
2013-05-20 19:18 ` Ben Myers
2013-05-19 23:51 ` [PATCH 02/14] xfs: fix rounding in xfs_free_file_space Dave Chinner
2013-05-20 18:03 ` Brian Foster
2013-05-19 23:51 ` [PATCH 03/14] xfs: Don't reference the EFI after it is freed Dave Chinner
2013-05-20 18:03 ` Brian Foster
2013-05-19 23:51 ` [PATCH 04/14] xfs: avoid nesting transactions in xfs_qm_scall_setqlim() Dave Chinner
2013-05-20 18:03 ` Brian Foster
2013-05-21 0:06 ` Dave Chinner
2013-05-21 0:36 ` [PATCH 04/14 V2] " Dave Chinner
2013-05-21 10:51 ` Brian Foster [this message]
2013-05-19 23:51 ` [PATCH 05/14] xfs: fix missing KM_NOFS tags to keep lockdep happy Dave Chinner
2013-05-20 21:16 ` Ben Myers
2013-05-21 0:08 ` Dave Chinner
2013-05-19 23:51 ` [PATCH 06/14] xfs: xfs_da3_node_read_verify() doesn't handle XFS_ATTR3_LEAF_MAGIC Dave Chinner
2013-05-20 21:32 ` Ben Myers
2013-05-19 23:51 ` [PATCH 07/14] xfs: xfs_attr_shortform_allfit() does not handle attr3 format Dave Chinner
2013-05-20 21:52 ` Ben Myers
2013-05-19 23:51 ` [PATCH 08/14] xfs: remote attribute allocation may be contiguous Dave Chinner
2013-05-20 19:03 ` Brian Foster
2013-05-20 22:04 ` Ben Myers
2013-05-21 0:25 ` Dave Chinner
2013-05-19 23:51 ` [PATCH 09/14] xfs: remote attribute lookups require the value length Dave Chinner
2013-05-20 22:15 ` Ben Myers
2013-05-19 23:51 ` [PATCH 10/14] xfs: remote attribute read too short Dave Chinner
2013-05-20 23:00 ` Ben Myers
2013-05-19 23:51 ` [PATCH 11/14] xfs: remote attribute tail zeroing does too much Dave Chinner
2013-05-20 23:01 ` Ben Myers
2013-05-19 23:51 ` [PATCH 12/14] xfs: correctly map remote attr buffers during removal Dave Chinner
2013-05-19 23:51 ` [PATCH 13/14] xfs: fully initialise temp leaf in xfs_attr3_leaf_unbalance Dave Chinner
2013-05-19 23:51 ` [PATCH 14/14] xfs: fully initialise temp leaf in xfs_attr3_leaf_compact Dave Chinner
2013-05-20 19:37 ` [PATCH 00/14] xfs: fixes for 3.10-rc2 (update) Ben Myers
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=519B519C.5030405@redhat.com \
--to=bfoster@redhat.com \
--cc=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.