@@ -272,6 +272,10 @@ xfs_agino_range(
272
272
return __xfs_agino_range (mp , xfs_ag_block_count (mp , agno ), first , last );
273
273
}
274
274
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
+ */
275
279
int
276
280
xfs_update_last_ag_size (
277
281
struct xfs_mount * mp ,
@@ -289,78 +293,93 @@ xfs_update_last_ag_size(
289
293
return 0 ;
290
294
}
291
295
292
- int
293
- xfs_initialize_perag (
296
+ static int
297
+ xfs_perag_alloc (
294
298
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 )
299
302
{
300
303
struct xfs_perag * pag ;
301
- xfs_agnumber_t index ;
302
304
int error ;
303
305
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 ;
312
309
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
+ }
318
318
319
319
#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 );
330
330
#endif /* __KERNEL__ */
331
331
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 ;
348
335
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 );
350
338
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 );
353
346
354
- mp -> m_ag_prealloc_blocks = xfs_prealloc_blocks (mp );
355
347
return 0 ;
356
348
357
349
out_remove_pag :
358
350
xfs_defer_drain_free (& pag -> pag_intents_drain );
359
351
pag = xa_erase (& mp -> m_perags , index );
360
352
out_free_pag :
361
353
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
+
362
381
out_unwind_new_pags :
363
- xfs_free_perag_range (mp , old_agcount , index );
382
+ xfs_free_perag_range (mp , orig_agcount , index );
364
383
return error ;
365
384
}
366
385
0 commit comments