@@ -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+ */
275279int
276280xfs_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
357349out_remove_pag :
358350 xfs_defer_drain_free (& pag -> pag_intents_drain );
359351 pag = xa_erase (& mp -> m_perags , index );
360352out_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+
362381out_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
0 commit comments