@@ -923,6 +923,7 @@ int bch2_write_super(struct bch_fs *c)
923923 struct bch_devs_mask sb_written ;
924924 bool wrote , can_mount_without_written , can_mount_with_written ;
925925 unsigned degraded_flags = BCH_FORCE_IF_DEGRADED ;
926+ DARRAY (struct bch_dev * ) online_devices = {};
926927 int ret = 0 ;
927928
928929 trace_and_count (c , write_super , c , _RET_IP_ );
@@ -935,15 +936,24 @@ int bch2_write_super(struct bch_fs *c)
935936 closure_init_stack (cl );
936937 memset (& sb_written , 0 , sizeof (sb_written ));
937938
939+ for_each_online_member (c , ca ) {
940+ ret = darray_push (& online_devices , ca );
941+ if (bch2_fs_fatal_err_on (ret , c , "%s: error allocating online devices" , __func__ )) {
942+ percpu_ref_put (& ca -> io_ref );
943+ goto out ;
944+ }
945+ percpu_ref_get (& ca -> io_ref );
946+ }
947+
938948 /* Make sure we're using the new magic numbers: */
939949 c -> disk_sb .sb -> magic = BCHFS_MAGIC ;
940950 c -> disk_sb .sb -> layout .magic = BCHFS_MAGIC ;
941951
942952 le64_add_cpu (& c -> disk_sb .sb -> seq , 1 );
943953
944954 struct bch_sb_field_members_v2 * mi = bch2_sb_field_get (c -> disk_sb .sb , members_v2 );
945- for_each_online_member ( c , ca )
946- __bch2_members_v2_get_mut (mi , ca -> dev_idx )-> seq = c -> disk_sb .sb -> seq ;
955+ darray_for_each ( online_devices , ca )
956+ __bch2_members_v2_get_mut (mi , ( * ca ) -> dev_idx )-> seq = c -> disk_sb .sb -> seq ;
947957 c -> disk_sb .sb -> write_time = cpu_to_le64 (ktime_get_real_seconds ());
948958
949959 if (test_bit (BCH_FS_error , & c -> flags ))
@@ -959,16 +969,15 @@ int bch2_write_super(struct bch_fs *c)
959969 bch2_sb_errors_from_cpu (c );
960970 bch2_sb_downgrade_update (c );
961971
962- for_each_online_member ( c , ca )
963- bch2_sb_from_fs (c , ca );
972+ darray_for_each ( online_devices , ca )
973+ bch2_sb_from_fs (c , ( * ca ) );
964974
965- for_each_online_member ( c , ca ) {
975+ darray_for_each ( online_devices , ca ) {
966976 printbuf_reset (& err );
967977
968- ret = bch2_sb_validate (& ca -> disk_sb , & err , WRITE );
978+ ret = bch2_sb_validate (& ( * ca ) -> disk_sb , & err , WRITE );
969979 if (ret ) {
970980 bch2_fs_inconsistent (c , "sb invalid before write: %s" , err .buf );
971- percpu_ref_put (& ca -> io_ref );
972981 goto out ;
973982 }
974983 }
@@ -995,16 +1004,18 @@ int bch2_write_super(struct bch_fs *c)
9951004 return - BCH_ERR_sb_not_downgraded ;
9961005 }
9971006
998- for_each_online_member ( c , ca ) {
999- __set_bit (ca -> dev_idx , sb_written .d );
1000- ca -> sb_write_error = 0 ;
1007+ darray_for_each ( online_devices , ca ) {
1008+ __set_bit (( * ca ) -> dev_idx , sb_written .d );
1009+ ( * ca ) -> sb_write_error = 0 ;
10011010 }
10021011
1003- for_each_online_member ( c , ca )
1004- read_back_super (c , ca );
1012+ darray_for_each ( online_devices , ca )
1013+ read_back_super (c , * ca );
10051014 closure_sync (cl );
10061015
1007- for_each_online_member (c , ca ) {
1016+ darray_for_each (online_devices , cap ) {
1017+ struct bch_dev * ca = * cap ;
1018+
10081019 if (ca -> sb_write_error )
10091020 continue ;
10101021
@@ -1031,17 +1042,20 @@ int bch2_write_super(struct bch_fs *c)
10311042
10321043 do {
10331044 wrote = false;
1034- for_each_online_member (c , ca )
1045+ darray_for_each (online_devices , cap ) {
1046+ struct bch_dev * ca = * cap ;
10351047 if (!ca -> sb_write_error &&
10361048 sb < ca -> disk_sb .sb -> layout .nr_superblocks ) {
10371049 write_one_super (c , ca , sb );
10381050 wrote = true;
10391051 }
1052+ }
10401053 closure_sync (cl );
10411054 sb ++ ;
10421055 } while (wrote );
10431056
1044- for_each_online_member (c , ca ) {
1057+ darray_for_each (online_devices , cap ) {
1058+ struct bch_dev * ca = * cap ;
10451059 if (ca -> sb_write_error )
10461060 __clear_bit (ca -> dev_idx , sb_written .d );
10471061 else
@@ -1077,6 +1091,9 @@ int bch2_write_super(struct bch_fs *c)
10771091out :
10781092 /* Make new options visible after they're persistent: */
10791093 bch2_sb_update (c );
1094+ darray_for_each (online_devices , ca )
1095+ percpu_ref_put (& (* ca )-> io_ref );
1096+ darray_exit (& online_devices );
10801097 printbuf_exit (& err );
10811098 return ret ;
10821099}
0 commit comments