All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Darrick J. Wong" <darrick.wong@oracle.com>
To: Gao Xiang <hsiangkao@redhat.com>
Cc: linux-xfs@vger.kernel.org, Dave Chinner <david@fromorbit.com>,
	Christoph Hellwig <hch@lst.de>,
	Dave Chinner <dchinner@redhat.com>
Subject: Re: [PATCH v2 5/6] xfs: spilt xfs_dialloc() into 2 functions
Date: Thu, 3 Dec 2020 11:29:26 -0800	[thread overview]
Message-ID: <20201203192926.GH106272@magnolia> (raw)
In-Reply-To: <20201203161028.1900929-6-hsiangkao@redhat.com>

On Fri, Dec 04, 2020 at 12:10:27AM +0800, Gao Xiang wrote:
> From: Dave Chinner <dchinner@redhat.com>
> 
> This patch explicitly separates free inode chunk allocation and
> inode allocation into two individual high level operations.
> 
> Signed-off-by: Dave Chinner <dchinner@redhat.com>
> Signed-off-by: Gao Xiang <hsiangkao@redhat.com>

FWIW I thought about doing some similar things with the xfs_dir_ialloc
in the metadata directory tree patchset, so this makes sense to me (and
will probably simplify things) so:

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

--D

> ---
>  fs/xfs/libxfs/xfs_ialloc.c | 59 +++++++++++++++++---------------------
>  fs/xfs/libxfs/xfs_ialloc.h | 20 +++++++++----
>  fs/xfs/xfs_inode.c         | 19 ++++++++----
>  3 files changed, 55 insertions(+), 43 deletions(-)
> 
> diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c
> index d2d7378abf49..597629353d4d 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.c
> +++ b/fs/xfs/libxfs/xfs_ialloc.c
> @@ -1570,7 +1570,7 @@ xfs_dialloc_ag_update_inobt(
>   * The caller selected an AG for us, and made sure that free inodes are
>   * available.
>   */
> -STATIC int
> +int
>  xfs_dialloc_ag(
>  	struct xfs_trans	*tp,
>  	struct xfs_buf		*agbp,
> @@ -1728,21 +1728,22 @@ xfs_dialloc_roll(
>  }
>  
>  /*
> - * Allocate an inode on disk.
> + * Select and prepare an AG for inode allocation.
>   *
> - * Mode is used to tell whether the new inode will need space, and whether it
> - * is a directory.
> + * Mode is used to tell whether the new inode is a directory and hence where to
> + * locate it.
>   *
> - * Once we successfully pick an inode its number is returned and the on-disk
> - * data structures are updated.  The inode itself is not read in, since doing so
> - * would break ordering constraints with xfs_reclaim.
> + * This function will ensure that the selected AG has free inodes available to
> + * allocate from. The selected AGI will be returned locked to the caller, and it
> + * will allocate more free inodes if required. If no free inodes are found or
> + * can be allocated, no AGI will be returned.
>   */
>  int
> -xfs_dialloc(
> +xfs_dialloc_select_ag(
>  	struct xfs_trans	**tpp,
>  	xfs_ino_t		parent,
>  	umode_t			mode,
> -	xfs_ino_t		*inop)
> +	struct xfs_buf		**IO_agbp)
>  {
>  	struct xfs_mount	*mp = (*tpp)->t_mountp;
>  	struct xfs_buf		*agbp;
> @@ -1755,15 +1756,15 @@ xfs_dialloc(
>  	struct xfs_ino_geometry	*igeo = M_IGEO(mp);
>  	bool			okalloc = true;
>  
> +	*IO_agbp = NULL;
> +
>  	/*
>  	 * We do not have an agbp, so select an initial allocation
>  	 * group for inode allocation.
>  	 */
>  	start_agno = xfs_ialloc_ag_select(*tpp, parent, mode);
> -	if (start_agno == NULLAGNUMBER) {
> -		*inop = NULLFSINO;
> +	if (start_agno == NULLAGNUMBER)
>  		return 0;
> -	}
>  
>  	/*
>  	 * If we have already hit the ceiling of inode blocks then clear
> @@ -1796,7 +1797,7 @@ xfs_dialloc(
>  		if (!pag->pagi_init) {
>  			error = xfs_ialloc_pagi_init(mp, *tpp, agno);
>  			if (error)
> -				goto out_error;
> +				break;
>  		}
>  
>  		/*
> @@ -1811,11 +1812,12 @@ xfs_dialloc(
>  		 */
>  		error = xfs_ialloc_read_agi(mp, *tpp, agno, &agbp);
>  		if (error)
> -			goto out_error;
> +			break;
>  
>  		if (pag->pagi_freecount) {
>  			xfs_perag_put(pag);
> -			goto out_alloc;
> +			*IO_agbp = agbp;
> +			return 0;
>  		}
>  
>  		if (!okalloc)
> @@ -1826,19 +1828,17 @@ xfs_dialloc(
>  		if (error) {
>  			xfs_trans_brelse(*tpp, agbp);
>  
> -			if (error != -ENOSPC)
> -				goto out_error;
> -
> -			xfs_perag_put(pag);
> -			*inop = NULLFSINO;
> -			return 0;
> +			if (error == -ENOSPC)
> +				error = 0;
> +			break;
>  		}
>  
>  		if (ialloced) {
>  			/*
> -			 * We successfully allocated some inodes, roll the
> -			 * transaction so they can allocate one of the free
> -			 * inodes we just prepared for them.
> +			 * We successfully allocated some inodes, so roll the
> +			 * transaction and return the locked AGI buffer to the
> +			 * caller so they can allocate one of the free inodes we
> +			 * just prepared for them.
>  			 */
>  			ASSERT(pag->pagi_freecount > 0);
>  			xfs_perag_put(pag);
> @@ -1847,8 +1847,8 @@ xfs_dialloc(
>  			if (error)
>  				return error;
>  
> -			*inop = NULLFSINO;
> -			goto out_alloc;
> +			*IO_agbp = agbp;
> +			return 0;
>  		}
>  
>  nextag_relse_buffer:
> @@ -1857,15 +1857,10 @@ xfs_dialloc(
>  		xfs_perag_put(pag);
>  		if (++agno == mp->m_sb.sb_agcount)
>  			agno = 0;
> -		if (agno == start_agno) {
> -			*inop = NULLFSINO;
> +		if (agno == start_agno)
>  			return noroom ? -ENOSPC : 0;
> -		}
>  	}
>  
> -out_alloc:
> -	return xfs_dialloc_ag(*tpp, agbp, parent, inop);
> -out_error:
>  	xfs_perag_put(pag);
>  	return error;
>  }
> diff --git a/fs/xfs/libxfs/xfs_ialloc.h b/fs/xfs/libxfs/xfs_ialloc.h
> index 13810ffe4af9..3511086a7ae1 100644
> --- a/fs/xfs/libxfs/xfs_ialloc.h
> +++ b/fs/xfs/libxfs/xfs_ialloc.h
> @@ -37,16 +37,26 @@ xfs_make_iptr(struct xfs_mount *mp, struct xfs_buf *b, int o)
>   * Mode is used to tell whether the new inode will need space, and whether
>   * it is a directory.
>   *
> - * Once we successfully pick an inode its number is returned and the
> - * on-disk data structures are updated.  The inode itself is not read
> - * in, since doing so would break ordering constraints with xfs_reclaim.
> + * There are two phases to inode allocation: selecting an AG and ensuring
> + * that it contains free inodes, followed by allocating one of the free
> + * inodes. xfs_dialloc_select_ag() does the former and returns a locked AGI
> + * to the caller, ensuring that followup call to xfs_dialloc_ag() will
> + * have free inodes to allocate from. xfs_dialloc_ag() will return the inode
> + * number of the free inode we allocated.
>   */
>  int					/* error */
> -xfs_dialloc(
> +xfs_dialloc_select_ag(
>  	struct xfs_trans **tpp,		/* double pointer of transaction */
>  	xfs_ino_t	parent,		/* parent inode (directory) */
>  	umode_t		mode,		/* mode bits for new inode */
> -	xfs_ino_t	*inop);		/* inode number allocated */
> +	struct xfs_buf	**IO_agbp);
> +
> +int
> +xfs_dialloc_ag(
> +	struct xfs_trans	*tp,
> +	struct xfs_buf		*agbp,
> +	xfs_ino_t		parent,
> +	xfs_ino_t		*inop);
>  
>  /*
>   * Free disk inode.  Carefully avoids touching the incore inode, all
> diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
> index c039fc56b396..d0ae0d6ee892 100644
> --- a/fs/xfs/xfs_inode.c
> +++ b/fs/xfs/xfs_inode.c
> @@ -908,10 +908,11 @@ xfs_dir_ialloc(
>  	xfs_inode_t	**ipp)		/* pointer to inode; it will be
>  					   locked. */
>  {
> -	xfs_inode_t	*ip;
> -	xfs_ino_t	pino = dp ? dp->i_ino : 0;
> -	xfs_ino_t	ino;
> -	int		error;
> +	struct xfs_buf		*agibp;
> +	struct xfs_inode	*ip;
> +	xfs_ino_t		pino = dp ? dp->i_ino : 0;
> +	xfs_ino_t		ino;
> +	int			error;
>  
>  	ASSERT((*tpp)->t_flags & XFS_TRANS_PERM_LOG_RES);
>  	*ipp = NULL;
> @@ -927,13 +928,19 @@ xfs_dir_ialloc(
>  	 * commit so that no other process can steal the inode(s) that we've
>  	 * just allocated.
>  	 */
> -	error = xfs_dialloc(tpp, pino, mode, &ino);
> +	error = xfs_dialloc_select_ag(tpp, pino, mode, &agibp);
>  	if (error)
>  		return error;
>  
> -	if (ino == NULLFSINO)
> +	if (!agibp)
>  		return -ENOSPC;
>  
> +	/* Allocate an inode from the selected AG */
> +	error = xfs_dialloc_ag(*tpp, agibp, pino, &ino);
> +	if (error)
> +		return error;
> +	ASSERT(ino != NULLFSINO);
> +
>  	/* Initialise the newly allocated inode. */
>  	ip = xfs_ialloc(*tpp, dp, ino, mode, nlink, rdev, prid);
>  	if (IS_ERR(ip))
> -- 
> 2.18.4
> 

  reply	other threads:[~2020-12-03 19:30 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-03 16:10 [PATCH v2 0/6] xfs: some xfs_dialloc() cleanup Gao Xiang
2020-12-03 16:10 ` [PATCH v2 1/6] xfs: convert noroom, okalloc in xfs_dialloc() to bool Gao Xiang
2020-12-03 20:32   ` Dave Chinner
2020-12-03 16:10 ` [PATCH v2 2/6] xfs: introduce xfs_dialloc_roll() Gao Xiang
2020-12-03 19:20   ` Darrick J. Wong
2020-12-03 16:10 ` [PATCH v2 3/6] xfs: move on-disk inode allocation out of xfs_ialloc() Gao Xiang
2020-12-03 19:21   ` Darrick J. Wong
2020-12-03 20:31   ` Dave Chinner
2020-12-04  0:58     ` Gao Xiang
2020-12-03 16:10 ` [PATCH v2 4/6] xfs: move xfs_dialloc_roll() into xfs_dialloc() Gao Xiang
2020-12-03 19:25   ` Darrick J. Wong
2020-12-03 16:10 ` [PATCH v2 5/6] xfs: spilt xfs_dialloc() into 2 functions Gao Xiang
2020-12-03 19:29   ` Darrick J. Wong [this message]
2020-12-03 16:10 ` [PATCH v2 6/6] xfs: kill ialloced in xfs_dialloc() Gao Xiang
2020-12-03 19:08   ` Darrick J. Wong
2020-12-03 20:33   ` Dave Chinner

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=20201203192926.GH106272@magnolia \
    --to=darrick.wong@oracle.com \
    --cc=david@fromorbit.com \
    --cc=dchinner@redhat.com \
    --cc=hch@lst.de \
    --cc=hsiangkao@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.