@@ -120,18 +120,18 @@ xfs_initialize_perag_data(
120120
121121 for (index = 0 ; index < agcount ; index ++ ) {
122122 /*
123- * read the agf, then the agi. This gets us
124- * all the information we need and populates the
125- * per-ag structures for us.
123+ * Read the AGF and AGI buffers to populate the per-ag
124+ * structures for us.
126125 */
127- error = xfs_alloc_pagf_init (mp , NULL , index , 0 );
128- if (error )
126+ pag = xfs_perag_get (mp , index );
127+ error = xfs_alloc_read_agf (pag , NULL , 0 , NULL );
128+ if (!error )
129+ error = xfs_ialloc_read_agi (pag , NULL , NULL );
130+ if (error ) {
131+ xfs_perag_put (pag );
129132 return error ;
133+ }
130134
131- error = xfs_ialloc_pagi_init (mp , NULL , index );
132- if (error )
133- return error ;
134- pag = xfs_perag_get (mp , index );
135135 ifree += pag -> pagi_freecount ;
136136 ialloc += pag -> pagi_count ;
137137 bfree += pag -> pagf_freeblks ;
@@ -201,10 +201,70 @@ xfs_free_perag(
201201 }
202202}
203203
204+ /* Find the size of the AG, in blocks. */
205+ static xfs_agblock_t
206+ __xfs_ag_block_count (
207+ struct xfs_mount * mp ,
208+ xfs_agnumber_t agno ,
209+ xfs_agnumber_t agcount ,
210+ xfs_rfsblock_t dblocks )
211+ {
212+ ASSERT (agno < agcount );
213+
214+ if (agno < agcount - 1 )
215+ return mp -> m_sb .sb_agblocks ;
216+ return dblocks - (agno * mp -> m_sb .sb_agblocks );
217+ }
218+
219+ xfs_agblock_t
220+ xfs_ag_block_count (
221+ struct xfs_mount * mp ,
222+ xfs_agnumber_t agno )
223+ {
224+ return __xfs_ag_block_count (mp , agno , mp -> m_sb .sb_agcount ,
225+ mp -> m_sb .sb_dblocks );
226+ }
227+
228+ /* Calculate the first and last possible inode number in an AG. */
229+ static void
230+ __xfs_agino_range (
231+ struct xfs_mount * mp ,
232+ xfs_agblock_t eoag ,
233+ xfs_agino_t * first ,
234+ xfs_agino_t * last )
235+ {
236+ xfs_agblock_t bno ;
237+
238+ /*
239+ * Calculate the first inode, which will be in the first
240+ * cluster-aligned block after the AGFL.
241+ */
242+ bno = round_up (XFS_AGFL_BLOCK (mp ) + 1 , M_IGEO (mp )-> cluster_align );
243+ * first = XFS_AGB_TO_AGINO (mp , bno );
244+
245+ /*
246+ * Calculate the last inode, which will be at the end of the
247+ * last (aligned) cluster that can be allocated in the AG.
248+ */
249+ bno = round_down (eoag , M_IGEO (mp )-> cluster_align );
250+ * last = XFS_AGB_TO_AGINO (mp , bno ) - 1 ;
251+ }
252+
253+ void
254+ xfs_agino_range (
255+ struct xfs_mount * mp ,
256+ xfs_agnumber_t agno ,
257+ xfs_agino_t * first ,
258+ xfs_agino_t * last )
259+ {
260+ return __xfs_agino_range (mp , xfs_ag_block_count (mp , agno ), first , last );
261+ }
262+
204263int
205264xfs_initialize_perag (
206265 struct xfs_mount * mp ,
207266 xfs_agnumber_t agcount ,
267+ xfs_rfsblock_t dblocks ,
208268 xfs_agnumber_t * maxagi )
209269{
210270 struct xfs_perag * pag ;
@@ -270,6 +330,15 @@ xfs_initialize_perag(
270330 /* first new pag is fully initialized */
271331 if (first_initialised == NULLAGNUMBER )
272332 first_initialised = index ;
333+
334+ /*
335+ * Pre-calculated geometry
336+ */
337+ pag -> block_count = __xfs_ag_block_count (mp , index , agcount ,
338+ dblocks );
339+ pag -> min_block = XFS_AGFL_BLOCK (mp );
340+ __xfs_agino_range (mp , pag -> block_count , & pag -> agino_min ,
341+ & pag -> agino_max );
273342 }
274343
275344 index = xfs_set_inode_alloc (mp , agcount );
@@ -321,12 +390,6 @@ xfs_get_aghdr_buf(
321390 return 0 ;
322391}
323392
324- static inline bool is_log_ag (struct xfs_mount * mp , struct aghdr_init_data * id )
325- {
326- return mp -> m_sb .sb_logstart > 0 &&
327- id -> agno == XFS_FSB_TO_AGNO (mp , mp -> m_sb .sb_logstart );
328- }
329-
330393/*
331394 * Generic btree root block init function
332395 */
@@ -352,7 +415,7 @@ xfs_freesp_init_recs(
352415 arec = XFS_ALLOC_REC_ADDR (mp , XFS_BUF_TO_BLOCK (bp ), 1 );
353416 arec -> ar_startblock = cpu_to_be32 (mp -> m_ag_prealloc_blocks );
354417
355- if (is_log_ag (mp , id )) {
418+ if (xfs_ag_contains_log (mp , id -> agno )) {
356419 struct xfs_alloc_rec * nrec ;
357420 xfs_agblock_t start = XFS_FSB_TO_AGBNO (mp ,
358421 mp -> m_sb .sb_logstart );
@@ -479,7 +542,7 @@ xfs_rmaproot_init(
479542 }
480543
481544 /* account for the log space */
482- if (is_log_ag (mp , id )) {
545+ if (xfs_ag_contains_log (mp , id -> agno )) {
483546 rrec = XFS_RMAP_REC_ADDR (block ,
484547 be16_to_cpu (block -> bb_numrecs ) + 1 );
485548 rrec -> rm_startblock = cpu_to_be32 (
@@ -550,7 +613,7 @@ xfs_agfblock_init(
550613 agf -> agf_refcount_blocks = cpu_to_be32 (1 );
551614 }
552615
553- if (is_log_ag (mp , id )) {
616+ if (xfs_ag_contains_log (mp , id -> agno )) {
554617 int64_t logblocks = mp -> m_sb .sb_logblocks ;
555618
556619 be32_add_cpu (& agf -> agf_freeblks , - logblocks );
@@ -761,11 +824,11 @@ xfs_ag_init_headers(
761824
762825int
763826xfs_ag_shrink_space (
764- struct xfs_mount * mp ,
827+ struct xfs_perag * pag ,
765828 struct xfs_trans * * tpp ,
766- xfs_agnumber_t agno ,
767829 xfs_extlen_t delta )
768830{
831+ struct xfs_mount * mp = pag -> pag_mount ;
769832 struct xfs_alloc_arg args = {
770833 .tp = * tpp ,
771834 .mp = mp ,
@@ -782,14 +845,14 @@ xfs_ag_shrink_space(
782845 xfs_agblock_t aglen ;
783846 int error , err2 ;
784847
785- ASSERT (agno == mp -> m_sb .sb_agcount - 1 );
786- error = xfs_ialloc_read_agi (mp , * tpp , agno , & agibp );
848+ ASSERT (pag -> pag_agno == mp -> m_sb .sb_agcount - 1 );
849+ error = xfs_ialloc_read_agi (pag , * tpp , & agibp );
787850 if (error )
788851 return error ;
789852
790853 agi = agibp -> b_addr ;
791854
792- error = xfs_alloc_read_agf (mp , * tpp , agno , 0 , & agfbp );
855+ error = xfs_alloc_read_agf (pag , * tpp , 0 , & agfbp );
793856 if (error )
794857 return error ;
795858
@@ -801,21 +864,22 @@ xfs_ag_shrink_space(
801864 if (delta >= aglen )
802865 return - EINVAL ;
803866
804- args .fsbno = XFS_AGB_TO_FSB (mp , agno , aglen - delta );
867+ args .fsbno = XFS_AGB_TO_FSB (mp , pag -> pag_agno , aglen - delta );
805868
806869 /*
807870 * Make sure that the last inode cluster cannot overlap with the new
808871 * end of the AG, even if it's sparse.
809872 */
810- error = xfs_ialloc_check_shrink (* tpp , agno , agibp , aglen - delta );
873+ error = xfs_ialloc_check_shrink (* tpp , pag -> pag_agno , agibp ,
874+ aglen - delta );
811875 if (error )
812876 return error ;
813877
814878 /*
815879 * Disable perag reservations so it doesn't cause the allocation request
816880 * to fail. We'll reestablish reservation before we return.
817881 */
818- error = xfs_ag_resv_free (agibp -> b_pag );
882+ error = xfs_ag_resv_free (pag );
819883 if (error )
820884 return error ;
821885
@@ -844,7 +908,7 @@ xfs_ag_shrink_space(
844908 be32_add_cpu (& agi -> agi_length , - delta );
845909 be32_add_cpu (& agf -> agf_length , - delta );
846910
847- err2 = xfs_ag_resv_init (agibp -> b_pag , * tpp );
911+ err2 = xfs_ag_resv_init (pag , * tpp );
848912 if (err2 ) {
849913 be32_add_cpu (& agi -> agi_length , delta );
850914 be32_add_cpu (& agf -> agf_length , delta );
@@ -868,8 +932,9 @@ xfs_ag_shrink_space(
868932 xfs_ialloc_log_agi (* tpp , agibp , XFS_AGI_LENGTH );
869933 xfs_alloc_log_agf (* tpp , agfbp , XFS_AGF_LENGTH );
870934 return 0 ;
935+
871936resv_init_out :
872- err2 = xfs_ag_resv_init (agibp -> b_pag , * tpp );
937+ err2 = xfs_ag_resv_init (pag , * tpp );
873938 if (!err2 )
874939 return error ;
875940resv_err :
@@ -883,33 +948,29 @@ xfs_ag_shrink_space(
883948 */
884949int
885950xfs_ag_extend_space (
886- struct xfs_mount * mp ,
951+ struct xfs_perag * pag ,
887952 struct xfs_trans * tp ,
888- struct aghdr_init_data * id ,
889953 xfs_extlen_t len )
890954{
891955 struct xfs_buf * bp ;
892956 struct xfs_agi * agi ;
893957 struct xfs_agf * agf ;
894958 int error ;
895959
896- /*
897- * Change the agi length.
898- */
899- error = xfs_ialloc_read_agi (mp , tp , id -> agno , & bp );
960+ ASSERT (pag -> pag_agno == pag -> pag_mount -> m_sb .sb_agcount - 1 );
961+
962+ error = xfs_ialloc_read_agi (pag , tp , & bp );
900963 if (error )
901964 return error ;
902965
903966 agi = bp -> b_addr ;
904967 be32_add_cpu (& agi -> agi_length , len );
905- ASSERT (id -> agno == mp -> m_sb .sb_agcount - 1 ||
906- be32_to_cpu (agi -> agi_length ) == mp -> m_sb .sb_agblocks );
907968 xfs_ialloc_log_agi (tp , bp , XFS_AGI_LENGTH );
908969
909970 /*
910971 * Change agf length.
911972 */
912- error = xfs_alloc_read_agf (mp , tp , id -> agno , 0 , & bp );
973+ error = xfs_alloc_read_agf (pag , tp , 0 , & bp );
913974 if (error )
914975 return error ;
915976
@@ -924,49 +985,49 @@ xfs_ag_extend_space(
924985 * XFS_RMAP_OINFO_SKIP_UPDATE is used here to tell the rmap btree that
925986 * this doesn't actually exist in the rmap btree.
926987 */
927- error = xfs_rmap_free (tp , bp , bp -> b_pag ,
928- be32_to_cpu (agf -> agf_length ) - len ,
988+ error = xfs_rmap_free (tp , bp , pag , be32_to_cpu (agf -> agf_length ) - len ,
929989 len , & XFS_RMAP_OINFO_SKIP_UPDATE );
930990 if (error )
931991 return error ;
932992
933- return xfs_free_extent (tp , XFS_AGB_TO_FSB (mp , id -> agno ,
993+ error = xfs_free_extent (tp , XFS_AGB_TO_FSB (pag -> pag_mount , pag -> pag_agno ,
934994 be32_to_cpu (agf -> agf_length ) - len ),
935995 len , & XFS_RMAP_OINFO_SKIP_UPDATE ,
936996 XFS_AG_RESV_NONE );
997+ if (error )
998+ return error ;
999+
1000+ /* Update perag geometry */
1001+ pag -> block_count = be32_to_cpu (agf -> agf_length );
1002+ __xfs_agino_range (pag -> pag_mount , pag -> block_count , & pag -> agino_min ,
1003+ & pag -> agino_max );
1004+ return 0 ;
9371005}
9381006
9391007/* Retrieve AG geometry. */
9401008int
9411009xfs_ag_get_geometry (
942- struct xfs_mount * mp ,
943- xfs_agnumber_t agno ,
1010+ struct xfs_perag * pag ,
9441011 struct xfs_ag_geometry * ageo )
9451012{
9461013 struct xfs_buf * agi_bp ;
9471014 struct xfs_buf * agf_bp ;
9481015 struct xfs_agi * agi ;
9491016 struct xfs_agf * agf ;
950- struct xfs_perag * pag ;
9511017 unsigned int freeblks ;
9521018 int error ;
9531019
954- if (agno >= mp -> m_sb .sb_agcount )
955- return - EINVAL ;
956-
9571020 /* Lock the AG headers. */
958- error = xfs_ialloc_read_agi (mp , NULL , agno , & agi_bp );
1021+ error = xfs_ialloc_read_agi (pag , NULL , & agi_bp );
9591022 if (error )
9601023 return error ;
961- error = xfs_alloc_read_agf (mp , NULL , agno , 0 , & agf_bp );
1024+ error = xfs_alloc_read_agf (pag , NULL , 0 , & agf_bp );
9621025 if (error )
9631026 goto out_agi ;
9641027
965- pag = agi_bp -> b_pag ;
966-
9671028 /* Fill out form. */
9681029 memset (ageo , 0 , sizeof (* ageo ));
969- ageo -> ag_number = agno ;
1030+ ageo -> ag_number = pag -> pag_agno ;
9701031
9711032 agi = agi_bp -> b_addr ;
9721033 ageo -> ag_icount = be32_to_cpu (agi -> agi_count );
0 commit comments