public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: Dave Chinner <david@fromorbit.com>
To: Mark Tinguely <tinguely@sgi.com>
Cc: xfs@oss.sgi.com
Subject: Re: [PATCH] xfs: fix unlock in xfs_bmap_add_attrfork
Date: Wed, 6 Nov 2013 16:39:51 +1100	[thread overview]
Message-ID: <20131106053951.GC6188@dastard> (raw)
In-Reply-To: <20131105202719.667077352@eagdhcp-232-150.americas.sgi.com>

On Tue, Nov 05, 2013 at 02:27:07PM -0600, Mark Tinguely wrote:
> xfs_trans_ijoin() activates the inode in a transaction and
> also can specify which lock to free when the transaction is
> committed or canceled.
> 
> xfs_bmap_add_attrfork adds the XFS_ILOCK_EXCL flag when calling
> xfs_trans_ijoin() so it wrong to also free this lock before doing
> a xfs_trans_cancel. Add the unlock to the error case before the
> xfs_trans_ijoin and remove the unlock from the error recovery.
> While here, clean up the goto names.

Definitely a bug, but I suspect it is the wrong fix. This is a
permanent log transaction, which means there are multiple commits
before the final commit, and xfs_trans_ijoin(XFS_ILOCK_EXCL) means
we will unlock the inode at the first commit that is made after the
join, not after the modifications are completed. Hence someone else
can come in and lock and modify the inode before we've finish all
the work in this function.

Hence I suspect the right fix is to make this code use
xfs_trans_ijoin(0) and do manual unlocking of the inode after the
last commit/cancel is done, similar to how it is done in 
xfs_iomap_write_allocate/direct...

Coupl eof other minor things:

> ===================================================================
> --- a/fs/xfs/xfs_bmap.c
> +++ b/fs/xfs/xfs_bmap.c
> @@ -1137,9 +1137,11 @@ xfs_bmap_add_attrfork(
>  	int			committed;	/* xaction was committed */
>  	int			logflags;	/* logging flags */
>  	int			error;		/* error return value */
> +	int			cancel_flags;
>  
>  	ASSERT(XFS_IFORK_Q(ip) == 0);
>  
> +	cancel_flags = XFS_TRANS_RELEASE_LOG_RES|XFS_TRANS_ABORT;
>  	mp = ip->i_mount;
>  	ASSERT(!XFS_NOT_DQATTACHED(mp, ip));
>  	tp = xfs_trans_alloc(mp, XFS_TRANS_ADDAFORK);
> @@ -1148,18 +1150,20 @@ xfs_bmap_add_attrfork(
>  		tp->t_flags |= XFS_TRANS_RESERVE;
>  	error = xfs_trans_reserve(tp, &M_RES(mp)->tr_addafork, blks, 0);
>  	if (error)
> -		goto error0;
> +		goto trans_cancel;

No reservation exists, so xfs_trans_cancel(tp, 0) is appropriate
here. i.e. cancel_flags gets initialised to 0, and after we have a
reservation we do:

	cancel_flags |= XFS_TRANS_RELEASE_LOG_RES;

>  	xfs_ilock(ip, XFS_ILOCK_EXCL);
>  	error = xfs_trans_reserve_quota_nblks(tp, ip, blks, 0, rsvd ?
>  			XFS_QMOPT_RES_REGBLKS | XFS_QMOPT_FORCE_RES :
>  			XFS_QMOPT_RES_REGBLKS);
>  	if (error) {
> +		cancel_flags = XFS_TRANS_RELEASE_LOG_RES;
>  		xfs_iunlock(ip, XFS_ILOCK_EXCL);
> -		xfs_trans_cancel(tp, XFS_TRANS_RELEASE_LOG_RES);
> -		return error;
> +		goto trans_cancel;
> +	}

Now we potentially have dirty objects in the transaction, so

	cancel_flags |= XFS_TRANS_ABORT;

Cheers,

Dave.
-- 
Dave Chinner
david@fromorbit.com

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

  reply	other threads:[~2013-11-06  5:40 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-05 20:27 [PATCH] xfs: fix unlock in xfs_bmap_add_attrfork Mark Tinguely
2013-11-06  5:39 ` Dave Chinner [this message]
2013-11-06 14:59   ` Mark Tinguely

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=20131106053951.GC6188@dastard \
    --to=david@fromorbit.com \
    --cc=tinguely@sgi.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox