mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-17 13:58:46 +00:00
xfs: split xfs_initialize_perag
Factor out a xfs_perag_alloc helper that allocates a single perag structure. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Signed-off-by: Darrick J. Wong <djwong@kernel.org>
This commit is contained in:
parent
c4ae021bcb
commit
201c5fa342
@ -272,6 +272,10 @@ xfs_agino_range(
|
||||
return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the perag of the previous tail AG if it has been changed during
|
||||
* recovery (i.e. recovery of a growfs).
|
||||
*/
|
||||
int
|
||||
xfs_update_last_ag_size(
|
||||
struct xfs_mount *mp,
|
||||
@ -289,69 +293,57 @@ xfs_update_last_ag_size(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_initialize_perag(
|
||||
static int
|
||||
xfs_perag_alloc(
|
||||
struct xfs_mount *mp,
|
||||
xfs_agnumber_t old_agcount,
|
||||
xfs_agnumber_t new_agcount,
|
||||
xfs_rfsblock_t dblocks,
|
||||
xfs_agnumber_t *maxagi)
|
||||
xfs_agnumber_t index,
|
||||
xfs_agnumber_t agcount,
|
||||
xfs_rfsblock_t dblocks)
|
||||
{
|
||||
struct xfs_perag *pag;
|
||||
xfs_agnumber_t index;
|
||||
int error;
|
||||
|
||||
for (index = old_agcount; index < new_agcount; index++) {
|
||||
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
|
||||
if (!pag) {
|
||||
error = -ENOMEM;
|
||||
goto out_unwind_new_pags;
|
||||
}
|
||||
pag->pag_agno = index;
|
||||
pag->pag_mount = mp;
|
||||
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
|
||||
if (!pag)
|
||||
return -ENOMEM;
|
||||
|
||||
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
|
||||
if (error) {
|
||||
WARN_ON_ONCE(error == -EBUSY);
|
||||
goto out_free_pag;
|
||||
}
|
||||
pag->pag_agno = index;
|
||||
pag->pag_mount = mp;
|
||||
|
||||
#ifdef __KERNEL__
|
||||
/* Place kernel structure only init below this point. */
|
||||
spin_lock_init(&pag->pag_ici_lock);
|
||||
spin_lock_init(&pag->pagb_lock);
|
||||
spin_lock_init(&pag->pag_state_lock);
|
||||
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
|
||||
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
|
||||
xfs_defer_drain_init(&pag->pag_intents_drain);
|
||||
init_waitqueue_head(&pag->pagb_wait);
|
||||
pag->pagb_tree = RB_ROOT;
|
||||
xfs_hooks_init(&pag->pag_rmap_update_hooks);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
error = xfs_buf_cache_init(&pag->pag_bcache);
|
||||
if (error)
|
||||
goto out_remove_pag;
|
||||
|
||||
/* Active ref owned by mount indicates AG is online. */
|
||||
atomic_set(&pag->pag_active_ref, 1);
|
||||
|
||||
/*
|
||||
* Pre-calculated geometry
|
||||
*/
|
||||
pag->block_count = __xfs_ag_block_count(mp, index, new_agcount,
|
||||
dblocks);
|
||||
pag->min_block = XFS_AGFL_BLOCK(mp);
|
||||
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
|
||||
&pag->agino_max);
|
||||
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
|
||||
if (error) {
|
||||
WARN_ON_ONCE(error == -EBUSY);
|
||||
goto out_free_pag;
|
||||
}
|
||||
|
||||
index = xfs_set_inode_alloc(mp, new_agcount);
|
||||
#ifdef __KERNEL__
|
||||
/* Place kernel structure only init below this point. */
|
||||
spin_lock_init(&pag->pag_ici_lock);
|
||||
spin_lock_init(&pag->pagb_lock);
|
||||
spin_lock_init(&pag->pag_state_lock);
|
||||
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
|
||||
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
|
||||
xfs_defer_drain_init(&pag->pag_intents_drain);
|
||||
init_waitqueue_head(&pag->pagb_wait);
|
||||
pag->pagb_tree = RB_ROOT;
|
||||
xfs_hooks_init(&pag->pag_rmap_update_hooks);
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
if (maxagi)
|
||||
*maxagi = index;
|
||||
error = xfs_buf_cache_init(&pag->pag_bcache);
|
||||
if (error)
|
||||
goto out_remove_pag;
|
||||
|
||||
/* Active ref owned by mount indicates AG is online. */
|
||||
atomic_set(&pag->pag_active_ref, 1);
|
||||
|
||||
/*
|
||||
* Pre-calculated geometry
|
||||
*/
|
||||
pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks);
|
||||
pag->min_block = XFS_AGFL_BLOCK(mp);
|
||||
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
|
||||
&pag->agino_max);
|
||||
|
||||
mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
|
||||
return 0;
|
||||
|
||||
out_remove_pag:
|
||||
@ -359,8 +351,35 @@ out_remove_pag:
|
||||
pag = xa_erase(&mp->m_perags, index);
|
||||
out_free_pag:
|
||||
kfree(pag);
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
xfs_initialize_perag(
|
||||
struct xfs_mount *mp,
|
||||
xfs_agnumber_t orig_agcount,
|
||||
xfs_agnumber_t new_agcount,
|
||||
xfs_rfsblock_t dblocks,
|
||||
xfs_agnumber_t *maxagi)
|
||||
{
|
||||
xfs_agnumber_t index;
|
||||
int error;
|
||||
|
||||
if (orig_agcount >= new_agcount)
|
||||
return 0;
|
||||
|
||||
for (index = orig_agcount; index < new_agcount; index++) {
|
||||
error = xfs_perag_alloc(mp, index, new_agcount, dblocks);
|
||||
if (error)
|
||||
goto out_unwind_new_pags;
|
||||
}
|
||||
|
||||
*maxagi = xfs_set_inode_alloc(mp, new_agcount);
|
||||
mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
|
||||
return 0;
|
||||
|
||||
out_unwind_new_pags:
|
||||
xfs_free_perag_range(mp, old_agcount, index);
|
||||
xfs_free_perag_range(mp, orig_agcount, index);
|
||||
return error;
|
||||
}
|
||||
|
||||
|
@ -142,8 +142,8 @@ __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
|
||||
__XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
|
||||
__XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
|
||||
|
||||
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
|
||||
xfs_agnumber_t agcount, xfs_rfsblock_t dcount,
|
||||
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t orig_agcount,
|
||||
xfs_agnumber_t new_agcount, xfs_rfsblock_t dcount,
|
||||
xfs_agnumber_t *maxagi);
|
||||
void xfs_free_perag_range(struct xfs_mount *mp, xfs_agnumber_t first_agno,
|
||||
xfs_agnumber_t end_agno);
|
||||
|
@ -724,9 +724,8 @@ xlog_recover_do_primary_sb_buffer(
|
||||
}
|
||||
|
||||
/*
|
||||
* Growfs can also grow the last existing AG. In this case we also need
|
||||
* to update the length in the in-core perag structure and values
|
||||
* depending on it.
|
||||
* If the last AG was grown or shrunk, we also need to update the
|
||||
* length in the in-core perag structure and values depending on it.
|
||||
*/
|
||||
error = xfs_update_last_ag_size(mp, orig_agcount);
|
||||
if (error)
|
||||
|
Loading…
x
Reference in New Issue
Block a user