diff options
author | Dave Chinner | 2020-12-09 10:05:16 -0800 |
---|---|---|
committer | Darrick J. Wong | 2020-12-12 10:48:25 -0800 |
commit | 8d822dc38ad781b1bfa5c03227da80dbd87e9959 (patch) | |
tree | 1f0b1258241bbd07d19eaa546e126b149f7e89b4 /fs/xfs/libxfs/xfs_ialloc.c | |
parent | f3bf6e0f1196c69a7b0412521596cd1cc7622a82 (diff) |
xfs: spilt xfs_dialloc() into 2 functions
This patch explicitly separates free inode chunk allocation and
inode allocation into two individual high level operations.
Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Gao Xiang <hsiangkao@redhat.com>
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Diffstat (limited to 'fs/xfs/libxfs/xfs_ialloc.c')
-rw-r--r-- | fs/xfs/libxfs/xfs_ialloc.c | 54 |
1 files changed, 24 insertions, 30 deletions
diff --git a/fs/xfs/libxfs/xfs_ialloc.c b/fs/xfs/libxfs/xfs_ialloc.c index cf1cc9b40e1b..4c45d0bb17ba 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, @@ -1718,21 +1718,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; @@ -1745,15 +1746,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 @@ -1786,7 +1787,7 @@ xfs_dialloc( if (!pag->pagi_init) { error = xfs_ialloc_pagi_init(mp, *tpp, agno); if (error) - goto out_error; + break; } /* @@ -1801,11 +1802,11 @@ 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; + goto found_ag; } if (!okalloc) @@ -1816,12 +1817,9 @@ 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) { @@ -1838,9 +1836,7 @@ xfs_dialloc( xfs_buf_relse(agbp); return error; } - - *inop = NULLFSINO; - goto out_alloc; + goto found_ag; } nextag_relse_buffer: @@ -1849,17 +1845,15 @@ nextag: 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; +found_ag: + *IO_agbp = agbp; + return 0; } /* |