@@ -185,17 +185,20 @@ xfs_initialize_perag_data(
185185}
186186
187187/*
188- * Free up the per-ag resources associated with the mount structure .
188+ * Free up the per-ag resources within the specified AG range .
189189 */
190190void
191- xfs_free_perag (
192- struct xfs_mount * mp )
191+ xfs_free_perag_range (
192+ struct xfs_mount * mp ,
193+ xfs_agnumber_t first_agno ,
194+ xfs_agnumber_t end_agno )
195+
193196{
194- struct xfs_perag * pag ;
195197 xfs_agnumber_t agno ;
196198
197- for (agno = 0 ; agno < mp -> m_sb .sb_agcount ; agno ++ ) {
198- pag = xa_erase (& mp -> m_perags , agno );
199+ for (agno = first_agno ; agno < end_agno ; agno ++ ) {
200+ struct xfs_perag * pag = xa_erase (& mp -> m_perags , agno );
201+
199202 ASSERT (pag );
200203 XFS_IS_CORRUPT (pag -> pag_mount , atomic_read (& pag -> pag_ref ) != 0 );
201204 xfs_defer_drain_free (& pag -> pag_intents_drain );
@@ -270,54 +273,37 @@ xfs_agino_range(
270273 return __xfs_agino_range (mp , xfs_ag_block_count (mp , agno ), first , last );
271274}
272275
273- /*
274- * Free perag within the specified AG range, it is only used to free unused
275- * perags under the error handling path.
276- */
277- void
278- xfs_free_unused_perag_range (
276+ int
277+ xfs_update_last_ag_size (
279278 struct xfs_mount * mp ,
280- xfs_agnumber_t agstart ,
281- xfs_agnumber_t agend )
279+ xfs_agnumber_t prev_agcount )
282280{
283- struct xfs_perag * pag ;
284- xfs_agnumber_t index ;
281+ struct xfs_perag * pag = xfs_perag_grab (mp , prev_agcount - 1 );
285282
286- for ( index = agstart ; index < agend ; index ++ ) {
287- pag = xa_erase ( & mp -> m_perags , index ) ;
288- if (! pag )
289- break ;
290- xfs_buf_cache_destroy ( & pag -> pag_bcache );
291- xfs_defer_drain_free ( & pag -> pag_intents_drain );
292- kfree (pag );
293- }
283+ if (! pag )
284+ return - EFSCORRUPTED ;
285+ pag -> block_count = __xfs_ag_block_count ( mp , prev_agcount - 1 ,
286+ mp -> m_sb . sb_agcount , mp -> m_sb . sb_dblocks ) ;
287+ __xfs_agino_range ( mp , pag -> block_count , & pag -> agino_min ,
288+ & pag -> agino_max );
289+ xfs_perag_rele (pag );
290+ return 0 ;
294291}
295292
296293int
297294xfs_initialize_perag (
298295 struct xfs_mount * mp ,
299- xfs_agnumber_t agcount ,
296+ xfs_agnumber_t old_agcount ,
297+ xfs_agnumber_t new_agcount ,
300298 xfs_rfsblock_t dblocks ,
301299 xfs_agnumber_t * maxagi )
302300{
303301 struct xfs_perag * pag ;
304302 xfs_agnumber_t index ;
305- xfs_agnumber_t first_initialised = NULLAGNUMBER ;
306303 int error ;
307304
308- /*
309- * Walk the current per-ag tree so we don't try to initialise AGs
310- * that already exist (growfs case). Allocate and insert all the
311- * AGs we don't find ready for initialisation.
312- */
313- for (index = 0 ; index < agcount ; index ++ ) {
314- pag = xfs_perag_get (mp , index );
315- if (pag ) {
316- xfs_perag_put (pag );
317- continue ;
318- }
319-
320- pag = kzalloc (sizeof (* pag ), GFP_KERNEL | __GFP_RETRY_MAYFAIL );
305+ for (index = old_agcount ; index < new_agcount ; index ++ ) {
306+ pag = kzalloc (sizeof (* pag ), GFP_KERNEL );
321307 if (!pag ) {
322308 error = - ENOMEM ;
323309 goto out_unwind_new_pags ;
@@ -353,21 +339,17 @@ xfs_initialize_perag(
353339 /* Active ref owned by mount indicates AG is online. */
354340 atomic_set (& pag -> pag_active_ref , 1 );
355341
356- /* first new pag is fully initialized */
357- if (first_initialised == NULLAGNUMBER )
358- first_initialised = index ;
359-
360342 /*
361343 * Pre-calculated geometry
362344 */
363- pag -> block_count = __xfs_ag_block_count (mp , index , agcount ,
345+ pag -> block_count = __xfs_ag_block_count (mp , index , new_agcount ,
364346 dblocks );
365347 pag -> min_block = XFS_AGFL_BLOCK (mp );
366348 __xfs_agino_range (mp , pag -> block_count , & pag -> agino_min ,
367349 & pag -> agino_max );
368350 }
369351
370- index = xfs_set_inode_alloc (mp , agcount );
352+ index = xfs_set_inode_alloc (mp , new_agcount );
371353
372354 if (maxagi )
373355 * maxagi = index ;
@@ -381,8 +363,7 @@ xfs_initialize_perag(
381363out_free_pag :
382364 kfree (pag );
383365out_unwind_new_pags :
384- /* unwind any prior newly initialized pags */
385- xfs_free_unused_perag_range (mp , first_initialised , agcount );
366+ xfs_free_perag_range (mp , old_agcount , index );
386367 return error ;
387368}
388369
0 commit comments