All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Brian Foster <bfoster@redhat.com>
Cc: linux-xfs@vger.kernel.org, Eryu Guan <eguan@redhat.com>,
	Dave Chinner <david@fromorbit.com>
Subject: Re: [PATCH 4/5] xfs: update ag iterator to support wait on new inodes
Date: Thu, 27 Apr 2017 14:17:15 -0700	[thread overview]
Message-ID: <20170427211715.GB22884@birch.djwong.org> (raw)
In-Reply-To: <1487173247-5965-5-git-send-email-bfoster@redhat.com>

On Wed, Feb 15, 2017 at 10:40:46AM -0500, Brian Foster wrote:
> The AG inode iterator currently skips new inodes as such inodes are
> inserted into the inode radix tree before they are fully
> constructed. Certain contexts require the ability to wait on the
> construction of new inodes, however. The fs-wide dquot release from
> the quotaoff sequence is an example of this.
> 
> Update the AG inode iterator to support the ability to wait on
> inodes flagged with XFS_INEW upon request. Create a new
> xfs_inode_ag_iterator_flags() interface and support a set of
> iteration flags to modify the iteration behavior. When the
> XFS_AGITER_INEW_WAIT flag is set, include XFS_INEW flags in the
> radix tree inode lookup and wait on them before the callback is
> executed.
> 
> Signed-off-by: Brian Foster <bfoster@redhat.com>

Looks ok,
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>

--D

> ---
>  fs/xfs/xfs_icache.c | 53 +++++++++++++++++++++++++++++++++++++++++++++--------
>  fs/xfs/xfs_icache.h |  8 ++++++++
>  2 files changed, 53 insertions(+), 8 deletions(-)
> 
> diff --git a/fs/xfs/xfs_icache.c b/fs/xfs/xfs_icache.c
> index bb55fd7..cb45a70 100644
> --- a/fs/xfs/xfs_icache.c
> +++ b/fs/xfs/xfs_icache.c
> @@ -262,6 +262,22 @@ xfs_inode_clear_reclaim_tag(
>  	xfs_perag_clear_reclaim_tag(pag);
>  }
>  
> +static void
> +xfs_inew_wait(
> +	struct xfs_inode	*ip)
> +{
> +	wait_queue_head_t *wq = bit_waitqueue(&ip->i_flags, __XFS_INEW_BIT);
> +	DEFINE_WAIT_BIT(wait, &ip->i_flags, __XFS_INEW_BIT);
> +
> +	do {
> +		prepare_to_wait(wq, &wait.wait, TASK_UNINTERRUPTIBLE);
> +		if (!xfs_iflags_test(ip, XFS_INEW))
> +			break;
> +		schedule();
> +	} while (true);
> +	finish_wait(wq, &wait.wait);
> +}
> +
>  /*
>   * When we recycle a reclaimable inode, we need to re-initialise the VFS inode
>   * part of the structure. This is made more complex by the fact we store
> @@ -626,9 +642,11 @@ xfs_iget(
>  
>  STATIC int
>  xfs_inode_ag_walk_grab(
> -	struct xfs_inode	*ip)
> +	struct xfs_inode	*ip,
> +	int			flags)
>  {
>  	struct inode		*inode = VFS_I(ip);
> +	bool			newinos = !!(flags & XFS_AGITER_INEW_WAIT);
>  
>  	ASSERT(rcu_read_lock_held());
>  
> @@ -646,7 +664,8 @@ xfs_inode_ag_walk_grab(
>  		goto out_unlock_noent;
>  
>  	/* avoid new or reclaimable inodes. Leave for reclaim code to flush */
> -	if (__xfs_iflags_test(ip, XFS_INEW | XFS_IRECLAIMABLE | XFS_IRECLAIM))
> +	if ((!newinos && __xfs_iflags_test(ip, XFS_INEW)) ||
> +	    __xfs_iflags_test(ip, XFS_IRECLAIMABLE | XFS_IRECLAIM))
>  		goto out_unlock_noent;
>  	spin_unlock(&ip->i_flags_lock);
>  
> @@ -674,7 +693,8 @@ xfs_inode_ag_walk(
>  					   void *args),
>  	int			flags,
>  	void			*args,
> -	int			tag)
> +	int			tag,
> +	int			iter_flags)
>  {
>  	uint32_t		first_index;
>  	int			last_error = 0;
> @@ -716,7 +736,7 @@ xfs_inode_ag_walk(
>  		for (i = 0; i < nr_found; i++) {
>  			struct xfs_inode *ip = batch[i];
>  
> -			if (done || xfs_inode_ag_walk_grab(ip))
> +			if (done || xfs_inode_ag_walk_grab(ip, iter_flags))
>  				batch[i] = NULL;
>  
>  			/*
> @@ -744,6 +764,9 @@ xfs_inode_ag_walk(
>  		for (i = 0; i < nr_found; i++) {
>  			if (!batch[i])
>  				continue;
> +			if ((iter_flags & XFS_AGITER_INEW_WAIT) &&
> +			    xfs_iflags_test(batch[i], XFS_INEW))
> +				xfs_inew_wait(batch[i]);
>  			error = execute(batch[i], flags, args);
>  			IRELE(batch[i]);
>  			if (error == -EAGAIN) {
> @@ -823,12 +846,13 @@ xfs_cowblocks_worker(
>  }
>  
>  int
> -xfs_inode_ag_iterator(
> +xfs_inode_ag_iterator_flags(
>  	struct xfs_mount	*mp,
>  	int			(*execute)(struct xfs_inode *ip, int flags,
>  					   void *args),
>  	int			flags,
> -	void			*args)
> +	void			*args,
> +	int			iter_flags)
>  {
>  	struct xfs_perag	*pag;
>  	int			error = 0;
> @@ -838,7 +862,8 @@ xfs_inode_ag_iterator(
>  	ag = 0;
>  	while ((pag = xfs_perag_get(mp, ag))) {
>  		ag = pag->pag_agno + 1;
> -		error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1);
> +		error = xfs_inode_ag_walk(mp, pag, execute, flags, args, -1,
> +					  iter_flags);
>  		xfs_perag_put(pag);
>  		if (error) {
>  			last_error = error;
> @@ -850,6 +875,17 @@ xfs_inode_ag_iterator(
>  }
>  
>  int
> +xfs_inode_ag_iterator(
> +	struct xfs_mount	*mp,
> +	int			(*execute)(struct xfs_inode *ip, int flags,
> +					   void *args),
> +	int			flags,
> +	void			*args)
> +{
> +	return xfs_inode_ag_iterator_flags(mp, execute, flags, args, 0);
> +}
> +
> +int
>  xfs_inode_ag_iterator_tag(
>  	struct xfs_mount	*mp,
>  	int			(*execute)(struct xfs_inode *ip, int flags,
> @@ -866,7 +902,8 @@ xfs_inode_ag_iterator_tag(
>  	ag = 0;
>  	while ((pag = xfs_perag_get_tag(mp, ag, tag))) {
>  		ag = pag->pag_agno + 1;
> -		error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag);
> +		error = xfs_inode_ag_walk(mp, pag, execute, flags, args, tag,
> +					  0);
>  		xfs_perag_put(pag);
>  		if (error) {
>  			last_error = error;
> diff --git a/fs/xfs/xfs_icache.h b/fs/xfs/xfs_icache.h
> index 8a7c849..9183f77 100644
> --- a/fs/xfs/xfs_icache.h
> +++ b/fs/xfs/xfs_icache.h
> @@ -48,6 +48,11 @@ struct xfs_eofblocks {
>  #define XFS_IGET_UNTRUSTED	0x2
>  #define XFS_IGET_DONTCACHE	0x4
>  
> +/*
> + * flags for AG inode iterator
> + */
> +#define XFS_AGITER_INEW_WAIT	0x1	/* wait on new inodes */
> +
>  int xfs_iget(struct xfs_mount *mp, struct xfs_trans *tp, xfs_ino_t ino,
>  	     uint flags, uint lock_flags, xfs_inode_t **ipp);
>  
> @@ -79,6 +84,9 @@ void xfs_cowblocks_worker(struct work_struct *);
>  int xfs_inode_ag_iterator(struct xfs_mount *mp,
>  	int (*execute)(struct xfs_inode *ip, int flags, void *args),
>  	int flags, void *args);
> +int xfs_inode_ag_iterator_flags(struct xfs_mount *mp,
> +	int (*execute)(struct xfs_inode *ip, int flags, void *args),
> +	int flags, void *args, int iter_flags);
>  int xfs_inode_ag_iterator_tag(struct xfs_mount *mp,
>  	int (*execute)(struct xfs_inode *ip, int flags, void *args),
>  	int flags, void *args, int tag);
> -- 
> 2.7.4
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

  reply	other threads:[~2017-04-27 21:17 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-15 15:40 [PATCH 0/5] xfs: quota deadlock fixes Brian Foster
2017-02-15 15:40 ` [PATCH 1/5] xfs: bypass dquot reclaim to avoid quotacheck deadlock Brian Foster
2017-02-16 22:37   ` Dave Chinner
2017-02-17 18:30     ` Brian Foster
2017-02-17 23:12       ` Dave Chinner
2017-02-18 12:55         ` Brian Foster
2017-02-15 15:40 ` [PATCH 2/5] xfs: allocate quotaoff transactions up front to avoid log deadlock Brian Foster
2017-04-26 21:23   ` Darrick J. Wong
2017-04-27 12:03     ` Brian Foster
2017-04-27 15:47       ` Darrick J. Wong
2017-02-15 15:40 ` [PATCH 3/5] xfs: support ability to wait on new inodes Brian Foster
2017-04-27 21:15   ` Darrick J. Wong
2017-02-15 15:40 ` [PATCH 4/5] xfs: update ag iterator to support " Brian Foster
2017-04-27 21:17   ` Darrick J. Wong [this message]
2017-02-15 15:40 ` [PATCH 5/5] xfs: wait on new inodes during quotaoff dquot release Brian Foster
2017-04-27 21:17   ` Darrick J. Wong
2017-02-16  7:42 ` [PATCH 0/5] xfs: quota deadlock fixes Eryu Guan
2017-02-16 12:01   ` Brian Foster
2017-02-17  6:53 ` Eryu Guan
2017-02-17 17:54   ` Brian Foster
2017-02-20  3:52     ` Eryu Guan
2017-02-20 13:25       ` Brian Foster
2017-02-22 15:35         ` Brian Foster

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=20170427211715.GB22884@birch.djwong.org \
    --to=darrick.wong@oracle.com \
    --cc=bfoster@redhat.com \
    --cc=david@fromorbit.com \
    --cc=eguan@redhat.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.