Re: [PATCH 4/5] xfs: update ag iterator to support wait on new inodes

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx>

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

--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@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe linux-xfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [XFS Filesystem Development (older mail)]     [Linux Filesystem Development]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux RAID]     [Linux SCSI]


  Powered by Linux