Skip to content

Commit 201c5fa

Browse files
Christoph HellwigDarrick J. Wong
authored andcommitted
xfs: split xfs_initialize_perag
Factor out a xfs_perag_alloc helper that allocates a single perag structure. Signed-off-by: Christoph Hellwig <[email protected]> Reviewed-by: Darrick J. Wong <[email protected]> Signed-off-by: Darrick J. Wong <[email protected]>
1 parent c4ae021 commit 201c5fa

File tree

3 files changed

+74
-56
lines changed

3 files changed

+74
-56
lines changed

fs/xfs/libxfs/xfs_ag.c

Lines changed: 70 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,10 @@ xfs_agino_range(
272272
return __xfs_agino_range(mp, xfs_ag_block_count(mp, agno), first, last);
273273
}
274274

275+
/*
276+
* Update the perag of the previous tail AG if it has been changed during
277+
* recovery (i.e. recovery of a growfs).
278+
*/
275279
int
276280
xfs_update_last_ag_size(
277281
struct xfs_mount *mp,
@@ -289,78 +293,93 @@ xfs_update_last_ag_size(
289293
return 0;
290294
}
291295

292-
int
293-
xfs_initialize_perag(
296+
static int
297+
xfs_perag_alloc(
294298
struct xfs_mount *mp,
295-
xfs_agnumber_t old_agcount,
296-
xfs_agnumber_t new_agcount,
297-
xfs_rfsblock_t dblocks,
298-
xfs_agnumber_t *maxagi)
299+
xfs_agnumber_t index,
300+
xfs_agnumber_t agcount,
301+
xfs_rfsblock_t dblocks)
299302
{
300303
struct xfs_perag *pag;
301-
xfs_agnumber_t index;
302304
int error;
303305

304-
for (index = old_agcount; index < new_agcount; index++) {
305-
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
306-
if (!pag) {
307-
error = -ENOMEM;
308-
goto out_unwind_new_pags;
309-
}
310-
pag->pag_agno = index;
311-
pag->pag_mount = mp;
306+
pag = kzalloc(sizeof(*pag), GFP_KERNEL);
307+
if (!pag)
308+
return -ENOMEM;
312309

313-
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
314-
if (error) {
315-
WARN_ON_ONCE(error == -EBUSY);
316-
goto out_free_pag;
317-
}
310+
pag->pag_agno = index;
311+
pag->pag_mount = mp;
312+
313+
error = xa_insert(&mp->m_perags, index, pag, GFP_KERNEL);
314+
if (error) {
315+
WARN_ON_ONCE(error == -EBUSY);
316+
goto out_free_pag;
317+
}
318318

319319
#ifdef __KERNEL__
320-
/* Place kernel structure only init below this point. */
321-
spin_lock_init(&pag->pag_ici_lock);
322-
spin_lock_init(&pag->pagb_lock);
323-
spin_lock_init(&pag->pag_state_lock);
324-
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
325-
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
326-
xfs_defer_drain_init(&pag->pag_intents_drain);
327-
init_waitqueue_head(&pag->pagb_wait);
328-
pag->pagb_tree = RB_ROOT;
329-
xfs_hooks_init(&pag->pag_rmap_update_hooks);
320+
/* Place kernel structure only init below this point. */
321+
spin_lock_init(&pag->pag_ici_lock);
322+
spin_lock_init(&pag->pagb_lock);
323+
spin_lock_init(&pag->pag_state_lock);
324+
INIT_DELAYED_WORK(&pag->pag_blockgc_work, xfs_blockgc_worker);
325+
INIT_RADIX_TREE(&pag->pag_ici_root, GFP_ATOMIC);
326+
xfs_defer_drain_init(&pag->pag_intents_drain);
327+
init_waitqueue_head(&pag->pagb_wait);
328+
pag->pagb_tree = RB_ROOT;
329+
xfs_hooks_init(&pag->pag_rmap_update_hooks);
330330
#endif /* __KERNEL__ */
331331

332-
error = xfs_buf_cache_init(&pag->pag_bcache);
333-
if (error)
334-
goto out_remove_pag;
335-
336-
/* Active ref owned by mount indicates AG is online. */
337-
atomic_set(&pag->pag_active_ref, 1);
338-
339-
/*
340-
* Pre-calculated geometry
341-
*/
342-
pag->block_count = __xfs_ag_block_count(mp, index, new_agcount,
343-
dblocks);
344-
pag->min_block = XFS_AGFL_BLOCK(mp);
345-
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
346-
&pag->agino_max);
347-
}
332+
error = xfs_buf_cache_init(&pag->pag_bcache);
333+
if (error)
334+
goto out_remove_pag;
348335

349-
index = xfs_set_inode_alloc(mp, new_agcount);
336+
/* Active ref owned by mount indicates AG is online. */
337+
atomic_set(&pag->pag_active_ref, 1);
350338

351-
if (maxagi)
352-
*maxagi = index;
339+
/*
340+
* Pre-calculated geometry
341+
*/
342+
pag->block_count = __xfs_ag_block_count(mp, index, agcount, dblocks);
343+
pag->min_block = XFS_AGFL_BLOCK(mp);
344+
__xfs_agino_range(mp, pag->block_count, &pag->agino_min,
345+
&pag->agino_max);
353346

354-
mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
355347
return 0;
356348

357349
out_remove_pag:
358350
xfs_defer_drain_free(&pag->pag_intents_drain);
359351
pag = xa_erase(&mp->m_perags, index);
360352
out_free_pag:
361353
kfree(pag);
354+
return error;
355+
}
356+
357+
int
358+
xfs_initialize_perag(
359+
struct xfs_mount *mp,
360+
xfs_agnumber_t orig_agcount,
361+
xfs_agnumber_t new_agcount,
362+
xfs_rfsblock_t dblocks,
363+
xfs_agnumber_t *maxagi)
364+
{
365+
xfs_agnumber_t index;
366+
int error;
367+
368+
if (orig_agcount >= new_agcount)
369+
return 0;
370+
371+
for (index = orig_agcount; index < new_agcount; index++) {
372+
error = xfs_perag_alloc(mp, index, new_agcount, dblocks);
373+
if (error)
374+
goto out_unwind_new_pags;
375+
}
376+
377+
*maxagi = xfs_set_inode_alloc(mp, new_agcount);
378+
mp->m_ag_prealloc_blocks = xfs_prealloc_blocks(mp);
379+
return 0;
380+
362381
out_unwind_new_pags:
363-
xfs_free_perag_range(mp, old_agcount, index);
382+
xfs_free_perag_range(mp, orig_agcount, index);
364383
return error;
365384
}
366385

fs/xfs/libxfs/xfs_ag.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,8 @@ __XFS_AG_OPSTATE(prefers_metadata, PREFERS_METADATA)
142142
__XFS_AG_OPSTATE(allows_inodes, ALLOWS_INODES)
143143
__XFS_AG_OPSTATE(agfl_needs_reset, AGFL_NEEDS_RESET)
144144

145-
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t old_agcount,
146-
xfs_agnumber_t agcount, xfs_rfsblock_t dcount,
145+
int xfs_initialize_perag(struct xfs_mount *mp, xfs_agnumber_t orig_agcount,
146+
xfs_agnumber_t new_agcount, xfs_rfsblock_t dcount,
147147
xfs_agnumber_t *maxagi);
148148
void xfs_free_perag_range(struct xfs_mount *mp, xfs_agnumber_t first_agno,
149149
xfs_agnumber_t end_agno);

fs/xfs/xfs_buf_item_recover.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -724,9 +724,8 @@ xlog_recover_do_primary_sb_buffer(
724724
}
725725

726726
/*
727-
* Growfs can also grow the last existing AG. In this case we also need
728-
* to update the length in the in-core perag structure and values
729-
* depending on it.
727+
* If the last AG was grown or shrunk, we also need to update the
728+
* length in the in-core perag structure and values depending on it.
730729
*/
731730
error = xfs_update_last_ag_size(mp, orig_agcount);
732731
if (error)

0 commit comments

Comments
 (0)