All of lore.kernel.org
 help / color / mirror / Atom feed
From: Alli <allison.henderson@oracle.com>
To: Dave Chinner <david@fromorbit.com>
Cc: linux-xfs@vger.kernel.org
Subject: Re: [PATCH v1 11/17] xfs: add parent attributes to link
Date: Fri, 17 Jun 2022 17:32:47 -0700	[thread overview]
Message-ID: <37baf16c95601e8919ebd1ecda704084cb121148.camel@oracle.com> (raw)
In-Reply-To: <20220616223923.GG227878@dread.disaster.area>

On Fri, 2022-06-17 at 08:39 +1000, Dave Chinner wrote:
> On Sat, Jun 11, 2022 at 02:41:54AM -0700, Allison Henderson wrote:
> > This patch modifies xfs_link to add a parent pointer to the inode.
> > 
> > [bfoster: rebase, use VFS inode fields, fix xfs_bmap_finish()
> > usage]
> > [achender: rebased, changed __unint32_t to xfs_dir2_dataptr_t,
> >            fixed null pointer bugs]
> > 
> > Signed-off-by: Dave Chinner <dchinner@redhat.com>
> > Signed-off-by: Allison Henderson <allison.henderson@oracle.com>
> > ---
> >  fs/xfs/xfs_inode.c | 78 ++++++++++++++++++++++++++++++++++++----
> > ------
> >  fs/xfs/xfs_trans.c |  7 +++--
> >  fs/xfs/xfs_trans.h |  2 +-
> >  3 files changed, 67 insertions(+), 20 deletions(-)
> > 
> > diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> > index 6b1e4cb11b5c..41c58df8e568 100644
> > --- a/fs/xfs/xfs_inode.c
> > +++ b/fs/xfs/xfs_inode.c
> > @@ -1254,14 +1254,28 @@ xfs_create_tmpfile(
> >  
> >  int
> >  xfs_link(
> > -	xfs_inode_t		*tdp,
> > -	xfs_inode_t		*sip,
> > -	struct xfs_name		*target_name)
> > -{
> > -	xfs_mount_t		*mp = tdp->i_mount;
> > -	xfs_trans_t		*tp;
> > -	int			error, nospace_error = 0;
> > -	int			resblks;
> > +	xfs_inode_t			*tdp,
> > +	xfs_inode_t			*sip,
> > +	struct xfs_name			*target_name)
> > +{
> > +	xfs_mount_t			*mp = tdp->i_mount;
> > +	xfs_trans_t			*tp;
> > +	int				error, nospace_error = 0;
> > +	int				resblks;
> > +	struct xfs_parent_name_rec	rec;
> > +	xfs_dir2_dataptr_t		diroffset;
> > +
> > +	struct xfs_da_args		args = {
> > +		.dp		= sip,
> > +		.geo		= mp->m_attr_geo,
> > +		.whichfork	= XFS_ATTR_FORK,
> > +		.attr_filter	= XFS_ATTR_PARENT,
> > +		.op_flags	= XFS_DA_OP_OKNOENT,
> > +		.name		= (const uint8_t *)&rec,
> > +		.namelen	= sizeof(rec),
> > +		.value		= (void *)target_name->name,
> > +		.valuelen	= target_name->len,
> > +	};
> 
> Now that I've had a bit of a think about this, this pattern of
> placing the rec on the stack and then using it as a buffer that is
> then accessed in xfs_tran_commit() processing feels like a landmine.
> 
> That is, we pass transaction contexts around functions as they are
> largely independent constructs, but adding this stack variable to
> the defer ops attached to the transaction means that the transaction
> cannot be passed back to a caller for it to be committed - that will
> corrupt the stack buffer and hence silently corrupt the parent attr
> that is going to be logged when the transaction is finally committed.
> 
> Hence I think this needs to be wrapped up as a dynamically allocated
> structure that is freed when the defer ops are done with it. e.g.
> 
> struct xfs_parent_defer {
> 	struct xfs_parent_name_rec	rec;
> 	xfs_dir2_dataptr_t		diroffset;
> 	struct xfs_da_args		args;
> };
> 
> and then here:
> 
> >  
> >  	trace_xfs_link(tdp, target_name);
> >  
> > @@ -1278,11 +1292,17 @@ xfs_link(
> >  	if (error)
> >  		goto std_return;
> >  
> > +	if (xfs_has_larp(mp)) {
> > +		error = xfs_attr_grab_log_assist(mp);
> > +		if (error)
> > +			goto std_return;
> > +	}
> 
> 	struct xfs_parent_defer		*parent = NULL;
> .....
> 
> 	error = xfs_parent_init(mp, target_name, &parent);
> 	if (error)
> 		goto std_return;
> 
> and xfs_parent_init() looks something like this:
> 
> int
> xfs_parent_init(
> 	.....
> 	struct xfs_parent_defer		**parentp)
> {
> 	struct xfs_parent_defer		*parent;
> 
> 	if (!xfs_has_parent_pointers(mp))
> 		return 0;
> 
> 	error = xfs_attr_grab_log_assist(mp);
> 	if (error)
> 		return error;
> 
> 	parent = kzalloc(sizeof(*parent), GFP_KERNEL);
> 	if (!parent)
> 		return -ENOMEM;
> 
> 	/* init parent da_args */
> 
> 	*parentp = parent;
> 	return 0;
> }
> 
> With that in place, we then can wrap all this up:
> 
> >  
> > +	/*
> > +	 * If we have parent pointers, we now need to add the parent
> > record to
> > +	 * the attribute fork of the inode. If this is the initial
> > parent
> > +	 * attribute, we need to create it correctly, otherwise we can
> > just add
> > +	 * the parent to the inode.
> > +	 */
> > +	if (xfs_sb_version_hasparent(&mp->m_sb)) {
> > +		args.trans = tp;
> > +		xfs_init_parent_name_rec(&rec, tdp, diroffset);
> > +		args.hashval = xfs_da_hashname(args.name,
> > +					       args.namelen);
> > +		error = xfs_attr_defer_add(&args);
> > +		if (error)
> > +			goto out_defer_cancel;
> > +	}
> 
> with:
> 
> 	if (parent) {
> 		error = xfs_parent_defer_add(tp, tdp, parent,
> diroffset);
> 		if (error)
> 			goto out_defer_cancel;
> 	}
> 
> and implement it something like:
> 
> int
> xfs_parent_defer_add(
> 	struct xfs_trans	*tp,
> 	struct xfs_inode	*ip,
> 	struct xfs_parent_defer	*parent,
> 	xfs_dir2_dataptr_t	diroffset)
> {
> 	struct xfs_da_args	*args = &parent->args;
> 
> 	xfs_init_parent_name_rec(&parent->rec, ip, diroffset)
> 	args->trans = tp;
> 	args->hashval = xfs_da_hashname(args->name, args->namelen);
> 	return xfs_attr_defer_add(args);
> }
> 
> 
> > +
> >  	/*
> >  	 * If this is a synchronous mount, make sure that the
> >  	 * link transaction goes to disk before returning to
> > @@ -1331,11 +1367,21 @@ xfs_link(
> >  	if (xfs_has_wsync(mp) || xfs_has_dirsync(mp))
> >  		xfs_trans_set_sync(tp);
> >  
> > -	return xfs_trans_commit(tp);
> > +	error = xfs_trans_commit(tp);
> > +	xfs_iunlock(tdp, XFS_ILOCK_EXCL);
> > +	xfs_iunlock(sip, XFS_ILOCK_EXCL);
> 
> with a xfs_parent_free(parent) added here now that we are done with
> the parent update.
> 
> > +	return error;
> >  
> > - error_return:
> > +out_defer_cancel:
> > +	xfs_defer_cancel(tp);
> > +error_return:
> >  	xfs_trans_cancel(tp);
> > - std_return:
> > +	xfs_iunlock(tdp, XFS_ILOCK_EXCL);
> > +	xfs_iunlock(sip, XFS_ILOCK_EXCL);
> > +drop_incompat:
> > +	if (xfs_has_larp(mp))
> > +		xlog_drop_incompat_feat(mp->m_log);
> 
> And this can be replace with  xfs_parent_cancel(mp, parent); that
> drops the log incompat featuer and frees the parent if it is not
> null.

Sure, that sounds reasonable.  Let me punch it up and see how it does
int the tests.

> 
> > +std_return:
> >  	if (error == -ENOSPC && nospace_error)
> >  		error = nospace_error;
> >  	return error;
> > @@ -2819,7 +2865,7 @@ xfs_remove(
> >  	 */
> >  	resblks = XFS_REMOVE_SPACE_RES(mp);
> >  	error = xfs_trans_alloc_dir(dp, &M_RES(mp)->tr_remove, ip,
> > &resblks,
> > -			&tp, &dontcare);
> > +			&tp, &dontcare, XFS_ILOCK_EXCL);
> 
> So you add this flag here so that link and remove can do different
> things in xfs_trans_alloc_dir(), but in the very next patch
> this gets changed to zero, so both callers only pass 0 to the
> function.
> 
> Ideally there should be a patch prior to this one that converts
> the locking and joining of both link and remove to use external
> inode locking in a single patch, similar to the change in the second
> patch that changed the inode locking around xfs_init_new_inode() to
> require manual unlock. Then all the locking mods in this and the
> next patch go away, leaving just the parent pointer mods in this
> patch....
Sure, I can do it that way too.

Thanks for the reviews!
Allison

> 
> Cheers,
> 
> Dave.


  reply	other threads:[~2022-06-18  0:32 UTC|newest]

Thread overview: 58+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-06-11  9:41 [PATCH v1 00/17] Return of the Parent Pointers Allison Henderson
2022-06-11  9:41 ` [PATCH v1 01/17] xfs: Add larp state XFS_DAS_CREATE_FORK Allison Henderson
2022-06-15  1:09   ` Dave Chinner
2022-06-15 23:40     ` Alli
2022-06-16  2:08       ` Dave Chinner
2022-06-16  5:32         ` Dave Chinner
2022-06-29  6:33           ` Alli
2022-06-30  0:40             ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 02/17] xfs: Hold inode locks in xfs_ialloc Allison Henderson
2022-06-29 18:28   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 03/17] xfs: get directory offset when adding directory name Allison Henderson
2022-06-29 18:29   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 04/17] xfs: get directory offset when removing " Allison Henderson
2022-06-29 18:30   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 05/17] xfs: get directory offset when replacing a " Allison Henderson
2022-06-29 18:30   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 06/17] xfs: add parent pointer support to attribute code Allison Henderson
2022-06-29 18:33   ` Darrick J. Wong
2022-06-29 18:58     ` Alli
2022-06-11  9:41 ` [PATCH v1 07/17] xfs: define parent pointer xattr format Allison Henderson
2022-06-29 18:34   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 08/17] xfs: Add xfs_verify_pptr Allison Henderson
2022-06-29 18:35   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 09/17] xfs: extent transaction reservations for parent attributes Allison Henderson
2022-06-16  5:38   ` Dave Chinner
2022-06-18  0:31     ` Alli
2022-06-29 18:37   ` Darrick J. Wong
2022-06-29 19:23     ` Alli
2022-06-11  9:41 ` [PATCH v1 10/17] xfs: parent pointer attribute creation Allison Henderson
2022-06-11 15:10   ` kernel test robot
2022-06-16  5:49   ` Dave Chinner
2022-06-18  0:32     ` Alli
2022-06-29 18:41   ` Darrick J. Wong
2022-06-30  1:29     ` Alli
2022-06-11  9:41 ` [PATCH v1 11/17] xfs: add parent attributes to link Allison Henderson
2022-06-16 22:39   ` Dave Chinner
2022-06-18  0:32     ` Alli [this message]
2022-06-29 18:09       ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 12/17] xfs: remove parent pointers in unlink Allison Henderson
2022-06-29 17:35   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 13/17] xfs: Add parent pointers to rename Allison Henderson
2022-06-29 18:02   ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 14/17] xfs: Add the parent pointer support to the superblock version 5 Allison Henderson
2022-06-16  6:03   ` Dave Chinner
2022-06-18  0:32     ` Alli
2022-06-20  0:21       ` Dave Chinner
2022-06-29 18:16         ` Darrick J. Wong
2022-06-11  9:41 ` [PATCH v1 15/17] xfs: Add helper function xfs_attr_list_context_init Allison Henderson
2022-06-29 18:42   ` Darrick J. Wong
2022-06-30  1:30     ` Alli
2022-06-11  9:41 ` [PATCH v1 16/17] xfs: Increase XFS_DEFER_OPS_NR_INODES to 4 Allison Henderson
2022-06-16 21:54   ` Dave Chinner
2022-06-18  0:32     ` Alli
2022-06-29 18:43       ` Darrick J. Wong
2022-06-30  1:30         ` Alli
2022-06-11  9:42 ` [PATCH v1 17/17] xfs: Add parent pointer ioctl Allison Henderson
2022-06-29 18:52   ` Darrick J. Wong
2022-06-30  1:30     ` Alli

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=37baf16c95601e8919ebd1ecda704084cb121148.camel@oracle.com \
    --to=allison.henderson@oracle.com \
    --cc=david@fromorbit.com \
    --cc=linux-xfs@vger.kernel.org \
    /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.