@@ -766,6 +766,31 @@ xfs_growfs_rt_alloc_fake_mount(
766766 return nmp ;
767767}
768768
769+ /* Free all the new space and return the number of extents actually freed. */
770+ static int
771+ xfs_growfs_rt_free_new (
772+ struct xfs_rtgroup * rtg ,
773+ struct xfs_rtalloc_args * nargs ,
774+ xfs_rtbxlen_t * freed_rtx )
775+ {
776+ struct xfs_mount * mp = rtg_mount (rtg );
777+ xfs_rgnumber_t rgno = rtg_rgno (rtg );
778+ xfs_rtxnum_t start_rtx = 0 , end_rtx ;
779+
780+ if (rgno < mp -> m_sb .sb_rgcount )
781+ start_rtx = xfs_rtgroup_extents (mp , rgno );
782+ end_rtx = xfs_rtgroup_extents (nargs -> mp , rgno );
783+
784+ /*
785+ * Compute the first new extent that we want to free, being careful to
786+ * skip past a realtime superblock at the start of the realtime volume.
787+ */
788+ if (xfs_has_rtsb (nargs -> mp ) && rgno == 0 && start_rtx == 0 )
789+ start_rtx ++ ;
790+ * freed_rtx = end_rtx - start_rtx ;
791+ return xfs_rtfree_range (nargs , start_rtx , * freed_rtx );
792+ }
793+
769794static xfs_rfsblock_t
770795xfs_growfs_rt_nrblocks (
771796 struct xfs_rtgroup * rtg ,
@@ -786,6 +811,43 @@ xfs_growfs_rt_nrblocks(
786811 return min (nrblocks , step );
787812}
788813
814+ /*
815+ * If the post-grow filesystem will have an rtsb; we're initializing the first
816+ * rtgroup; and the filesystem didn't have a realtime section, write the rtsb
817+ * now, and attach the rtsb buffer to the real mount.
818+ */
819+ static int
820+ xfs_growfs_rt_init_rtsb (
821+ const struct xfs_rtalloc_args * nargs ,
822+ const struct xfs_rtgroup * rtg ,
823+ const struct xfs_rtalloc_args * args )
824+ {
825+ struct xfs_mount * mp = args -> mp ;
826+ struct xfs_buf * rtsb_bp ;
827+ int error ;
828+
829+ if (!xfs_has_rtsb (nargs -> mp ))
830+ return 0 ;
831+ if (rtg_rgno (rtg ) > 0 )
832+ return 0 ;
833+ if (mp -> m_sb .sb_rblocks )
834+ return 0 ;
835+
836+ error = xfs_buf_get_uncached (mp -> m_rtdev_targp , XFS_FSB_TO_BB (mp , 1 ),
837+ 0 , & rtsb_bp );
838+ if (error )
839+ return error ;
840+
841+ rtsb_bp -> b_maps [0 ].bm_bn = XFS_RTSB_DADDR ;
842+ rtsb_bp -> b_ops = & xfs_rtsb_buf_ops ;
843+
844+ xfs_update_rtsb (rtsb_bp , mp -> m_sb_bp );
845+ mp -> m_rtsb_bp = rtsb_bp ;
846+ error = xfs_bwrite (rtsb_bp );
847+ xfs_buf_unlock (rtsb_bp );
848+ return error ;
849+ }
850+
789851static int
790852xfs_growfs_rt_bmblock (
791853 struct xfs_rtgroup * rtg ,
@@ -808,7 +870,8 @@ xfs_growfs_rt_bmblock(
808870 int error ;
809871
810872 /*
811- * Calculate new sb and mount fields for this round.
873+ * Calculate new sb and mount fields for this round. Also ensure the
874+ * rtg_extents value is uptodate as the rtbitmap code relies on it.
812875 */
813876 nmp = nargs .mp = xfs_growfs_rt_alloc_fake_mount (mp ,
814877 xfs_growfs_rt_nrblocks (rtg , nrblocks , rextsize , bmbno ),
@@ -861,6 +924,10 @@ xfs_growfs_rt_bmblock(
861924 goto out_cancel ;
862925 }
863926
927+ error = xfs_growfs_rt_init_rtsb (& nargs , rtg , & args );
928+ if (error )
929+ goto out_cancel ;
930+
864931 /*
865932 * Update superblock fields.
866933 */
@@ -879,12 +946,14 @@ xfs_growfs_rt_bmblock(
879946 if (nmp -> m_sb .sb_rextslog != mp -> m_sb .sb_rextslog )
880947 xfs_trans_mod_sb (args .tp , XFS_TRANS_SB_REXTSLOG ,
881948 nmp -> m_sb .sb_rextslog - mp -> m_sb .sb_rextslog );
949+ if (nmp -> m_sb .sb_rgcount != mp -> m_sb .sb_rgcount )
950+ xfs_trans_mod_sb (args .tp , XFS_TRANS_SB_RGCOUNT ,
951+ nmp -> m_sb .sb_rgcount - mp -> m_sb .sb_rgcount );
882952
883953 /*
884954 * Free the new extent.
885955 */
886- freed_rtx = nmp -> m_sb .sb_rextents - mp -> m_sb .sb_rextents ;
887- error = xfs_rtfree_range (& nargs , mp -> m_sb .sb_rextents , freed_rtx );
956+ error = xfs_growfs_rt_free_new (rtg , & nargs , & freed_rtx );
888957 xfs_rtbuf_cache_relse (& nargs );
889958 if (error )
890959 goto out_cancel ;
@@ -925,6 +994,15 @@ xfs_growfs_rt_bmblock(
925994 return error ;
926995}
927996
997+ static xfs_rtxnum_t
998+ xfs_last_rtgroup_extents (
999+ struct xfs_mount * mp )
1000+ {
1001+ return mp -> m_sb .sb_rextents -
1002+ ((xfs_rtxnum_t )(mp -> m_sb .sb_rgcount - 1 ) *
1003+ mp -> m_sb .sb_rgextents );
1004+ }
1005+
9281006/*
9291007 * Calculate the last rbmblock currently used.
9301008 *
@@ -935,11 +1013,20 @@ xfs_last_rt_bmblock(
9351013 struct xfs_rtgroup * rtg )
9361014{
9371015 struct xfs_mount * mp = rtg_mount (rtg );
938- xfs_fileoff_t bmbno = mp -> m_sb .sb_rbmblocks ;
1016+ xfs_rgnumber_t rgno = rtg_rgno (rtg );
1017+ xfs_fileoff_t bmbno = 0 ;
1018+
1019+ ASSERT (!mp -> m_sb .sb_rgcount || rgno >= mp -> m_sb .sb_rgcount - 1 );
1020+
1021+ if (mp -> m_sb .sb_rgcount && rgno == mp -> m_sb .sb_rgcount - 1 ) {
1022+ xfs_rtxnum_t nrext = xfs_last_rtgroup_extents (mp );
1023+
1024+ /* Also fill up the previous block if not entirely full. */
1025+ bmbno = xfs_rtbitmap_blockcount_len (mp , nrext );
1026+ if (xfs_rtx_to_rbmword (mp , nrext ) != 0 )
1027+ bmbno -- ;
1028+ }
9391029
940- /* Skip the current block if it is exactly full. */
941- if (xfs_rtx_to_rbmword (mp , mp -> m_sb .sb_rextents ) != 0 )
942- bmbno -- ;
9431030 return bmbno ;
9441031}
9451032
@@ -956,38 +1043,56 @@ xfs_growfs_rt_alloc_blocks(
9561043 struct xfs_mount * mp = rtg_mount (rtg );
9571044 struct xfs_inode * rbmip = rtg -> rtg_inodes [XFS_RTGI_BITMAP ];
9581045 struct xfs_inode * rsumip = rtg -> rtg_inodes [XFS_RTGI_SUMMARY ];
959- xfs_extlen_t orbmblocks ;
960- xfs_extlen_t orsumblocks ;
961- xfs_extlen_t nrsumblocks ;
1046+ xfs_extlen_t orbmblocks = 0 ;
1047+ xfs_extlen_t orsumblocks = 0 ;
9621048 struct xfs_mount * nmp ;
963- int error ;
964-
965- /*
966- * Get the old block counts for bitmap and summary inodes.
967- * These can't change since other growfs callers are locked out.
968- */
969- orbmblocks = XFS_B_TO_FSB (mp , rbmip -> i_disk_size );
970- orsumblocks = XFS_B_TO_FSB (mp , rsumip -> i_disk_size );
1049+ int error = 0 ;
9711050
9721051 nmp = xfs_growfs_rt_alloc_fake_mount (mp , nrblocks , rextsize );
9731052 if (!nmp )
9741053 return - ENOMEM ;
975-
9761054 * nrbmblocks = nmp -> m_sb .sb_rbmblocks ;
977- nrsumblocks = nmp -> m_rsumblocks ;
978- kfree (nmp );
1055+
1056+ if (xfs_has_rtgroups (mp )) {
1057+ /*
1058+ * For file systems with the rtgroups feature, the RT bitmap and
1059+ * summary are always fully allocated, which means that we never
1060+ * need to grow the existing files.
1061+ *
1062+ * But we have to be careful to only fill the bitmap until the
1063+ * end of the actually used range.
1064+ */
1065+ if (rtg_rgno (rtg ) == nmp -> m_sb .sb_rgcount - 1 )
1066+ * nrbmblocks = xfs_rtbitmap_blockcount_len (nmp ,
1067+ xfs_last_rtgroup_extents (nmp ));
1068+
1069+ if (mp -> m_sb .sb_rgcount &&
1070+ rtg_rgno (rtg ) == mp -> m_sb .sb_rgcount - 1 )
1071+ goto out_free ;
1072+ } else {
1073+ /*
1074+ * Get the old block counts for bitmap and summary inodes.
1075+ * These can't change since other growfs callers are locked out.
1076+ */
1077+ orbmblocks = XFS_B_TO_FSB (mp , rbmip -> i_disk_size );
1078+ orsumblocks = XFS_B_TO_FSB (mp , rsumip -> i_disk_size );
1079+ }
9791080
9801081 error = xfs_rtfile_initialize_blocks (rtg , XFS_RTGI_BITMAP , orbmblocks ,
981- * nrbmblocks , NULL );
1082+ nmp -> m_sb . sb_rbmblocks , NULL );
9821083 if (error )
983- return error ;
984- return xfs_rtfile_initialize_blocks (rtg , XFS_RTGI_SUMMARY , orsumblocks ,
985- nrsumblocks , NULL );
1084+ goto out_free ;
1085+ error = xfs_rtfile_initialize_blocks (rtg , XFS_RTGI_SUMMARY , orsumblocks ,
1086+ nmp -> m_rsumblocks , NULL );
1087+ out_free :
1088+ kfree (nmp );
1089+ return error ;
9861090}
9871091
9881092static int
9891093xfs_growfs_rtg (
9901094 struct xfs_mount * mp ,
1095+ xfs_rgnumber_t rgno ,
9911096 xfs_rfsblock_t nrblocks ,
9921097 xfs_agblock_t rextsize )
9931098{
@@ -998,7 +1103,7 @@ xfs_growfs_rtg(
9981103 unsigned int i ;
9991104 int error ;
10001105
1001- rtg = xfs_rtgroup_grab (mp , 0 );
1106+ rtg = xfs_rtgroup_grab (mp , rgno );
10021107 if (!rtg )
10031108 return - EINVAL ;
10041109
@@ -1069,14 +1174,67 @@ xfs_growfs_check_rtgeom(
10691174 return error ;
10701175}
10711176
1177+ /*
1178+ * Compute the new number of rt groups and ensure that /rtgroups exists.
1179+ *
1180+ * Changing the rtgroup size is not allowed (even if the rt volume hasn't yet
1181+ * been initialized) because the userspace ABI doesn't support it.
1182+ */
1183+ static int
1184+ xfs_growfs_rt_prep_groups (
1185+ struct xfs_mount * mp ,
1186+ xfs_rfsblock_t rblocks ,
1187+ xfs_extlen_t rextsize ,
1188+ xfs_rgnumber_t * new_rgcount )
1189+ {
1190+ int error ;
1191+
1192+ * new_rgcount = howmany_64 (rblocks , mp -> m_sb .sb_rgextents * rextsize );
1193+ if (* new_rgcount > XFS_MAX_RGNUMBER )
1194+ return - EINVAL ;
1195+
1196+ /* Make sure the /rtgroups dir has been created */
1197+ if (!mp -> m_rtdirip ) {
1198+ struct xfs_trans * tp ;
1199+
1200+ error = xfs_trans_alloc_empty (mp , & tp );
1201+ if (error )
1202+ return error ;
1203+ error = xfs_rtginode_load_parent (tp );
1204+ xfs_trans_cancel (tp );
1205+
1206+ if (error == - ENOENT )
1207+ error = xfs_rtginode_mkdir_parent (mp );
1208+ if (error )
1209+ return error ;
1210+ }
1211+
1212+ return 0 ;
1213+ }
1214+
1215+ static bool
1216+ xfs_grow_last_rtg (
1217+ struct xfs_mount * mp )
1218+ {
1219+ if (!xfs_has_rtgroups (mp ))
1220+ return true;
1221+ if (mp -> m_sb .sb_rgcount == 0 )
1222+ return false;
1223+ return xfs_rtgroup_extents (mp , mp -> m_sb .sb_rgcount - 1 ) <=
1224+ mp -> m_sb .sb_rgextents ;
1225+ }
1226+
10721227/*
10731228 * Grow the realtime area of the filesystem.
10741229 */
10751230int
10761231xfs_growfs_rt (
1077- xfs_mount_t * mp , /* mount point for filesystem */
1078- xfs_growfs_rt_t * in ) /* growfs rt input struct */
1232+ struct xfs_mount * mp ,
1233+ struct xfs_growfs_rt * in )
10791234{
1235+ xfs_rgnumber_t old_rgcount = mp -> m_sb .sb_rgcount ;
1236+ xfs_rgnumber_t new_rgcount = 1 ;
1237+ xfs_rgnumber_t rgno ;
10801238 struct xfs_buf * bp ;
10811239 xfs_agblock_t old_rextsize = mp -> m_sb .sb_rextsize ;
10821240 int error ;
@@ -1134,18 +1292,56 @@ xfs_growfs_rt(
11341292 if (error )
11351293 goto out_unlock ;
11361294
1137- error = xfs_growfs_rtg (mp , in -> newblocks , in -> extsize );
1138- if (error )
1139- goto out_unlock ;
1295+ if (xfs_has_rtgroups (mp )) {
1296+ error = xfs_growfs_rt_prep_groups (mp , in -> newblocks ,
1297+ in -> extsize , & new_rgcount );
1298+ if (error )
1299+ goto out_unlock ;
1300+ }
11401301
1141- if (old_rextsize != in -> extsize ) {
1142- error = xfs_growfs_rt_fixup_extsize (mp );
1302+ if (xfs_grow_last_rtg (mp )) {
1303+ error = xfs_growfs_rtg (mp , old_rgcount - 1 , in -> newblocks ,
1304+ in -> extsize );
1305+ if (error )
1306+ goto out_unlock ;
1307+ }
1308+
1309+ for (rgno = old_rgcount ; rgno < new_rgcount ; rgno ++ ) {
1310+ xfs_rtbxlen_t rextents = div_u64 (in -> newblocks , in -> extsize );
1311+
1312+ error = xfs_rtgroup_alloc (mp , rgno , new_rgcount , rextents );
11431313 if (error )
11441314 goto out_unlock ;
1315+
1316+ error = xfs_growfs_rtg (mp , rgno , in -> newblocks , in -> extsize );
1317+ if (error ) {
1318+ struct xfs_rtgroup * rtg ;
1319+
1320+ rtg = xfs_rtgroup_grab (mp , rgno );
1321+ if (!WARN_ON_ONCE (!rtg )) {
1322+ xfs_rtunmount_rtg (rtg );
1323+ xfs_rtgroup_rele (rtg );
1324+ xfs_rtgroup_free (mp , rgno );
1325+ }
1326+ break ;
1327+ }
11451328 }
11461329
1147- /* Update secondary superblocks now the physical grow has completed */
1148- error = xfs_update_secondary_sbs (mp );
1330+ if (!error && old_rextsize != in -> extsize )
1331+ error = xfs_growfs_rt_fixup_extsize (mp );
1332+
1333+ /*
1334+ * Update secondary superblocks now the physical grow has completed.
1335+ *
1336+ * Also do this in case of an error as we might have already
1337+ * successfully updated one or more RTGs and incremented sb_rgcount.
1338+ */
1339+ if (!xfs_is_shutdown (mp )) {
1340+ int error2 = xfs_update_secondary_sbs (mp );
1341+
1342+ if (!error )
1343+ error = error2 ;
1344+ }
11491345
11501346out_unlock :
11511347 mutex_unlock (& mp -> m_growlock );
0 commit comments