@@ -1021,8 +1021,8 @@ struct journal_buf *bch2_next_write_buffer_flush_journal_buf(struct journal *j,
10211021
10221022/* allocate journal on a device: */
10231023
1024- static int __bch2_set_nr_journal_buckets (struct bch_dev * ca , unsigned nr ,
1025- bool new_fs , struct closure * cl )
1024+ static int bch2_set_nr_journal_buckets_iter (struct bch_dev * ca , unsigned nr ,
1025+ bool new_fs , struct closure * cl )
10261026{
10271027 struct bch_fs * c = ca -> fs ;
10281028 struct journal_device * ja = & ca -> journal ;
@@ -1150,26 +1150,20 @@ static int __bch2_set_nr_journal_buckets(struct bch_dev *ca, unsigned nr,
11501150 return ret ;
11511151}
11521152
1153- /*
1154- * Allocate more journal space at runtime - not currently making use if it, but
1155- * the code works:
1156- */
1157- int bch2_set_nr_journal_buckets (struct bch_fs * c , struct bch_dev * ca ,
1158- unsigned nr )
1153+ static int bch2_set_nr_journal_buckets_loop (struct bch_fs * c , struct bch_dev * ca ,
1154+ unsigned nr , bool new_fs )
11591155{
11601156 struct journal_device * ja = & ca -> journal ;
1161- struct closure cl ;
11621157 int ret = 0 ;
11631158
1159+ struct closure cl ;
11641160 closure_init_stack (& cl );
11651161
1166- down_write (& c -> state_lock );
1167-
11681162 /* don't handle reducing nr of buckets yet: */
11691163 if (nr < ja -> nr )
1170- goto unlock ;
1164+ return 0 ;
11711165
1172- while (ja -> nr < nr ) {
1166+ while (! ret && ja -> nr < nr ) {
11731167 struct disk_reservation disk_res = { 0 , 0 , 0 };
11741168
11751169 /*
@@ -1182,27 +1176,38 @@ int bch2_set_nr_journal_buckets(struct bch_fs *c, struct bch_dev *ca,
11821176 * filesystem-wide allocation will succeed, this is a device
11831177 * specific allocation - we can hang here:
11841178 */
1179+ if (!new_fs ) {
1180+ ret = bch2_disk_reservation_get (c , & disk_res ,
1181+ bucket_to_sector (ca , nr - ja -> nr ), 1 , 0 );
1182+ if (ret )
1183+ break ;
1184+ }
11851185
1186- ret = bch2_disk_reservation_get (c , & disk_res ,
1187- bucket_to_sector (ca , nr - ja -> nr ), 1 , 0 );
1188- if (ret )
1189- break ;
1186+ ret = bch2_set_nr_journal_buckets_iter (ca , nr , new_fs , & cl );
11901187
1191- ret = __bch2_set_nr_journal_buckets (ca , nr , false, & cl );
1188+ if (ret == - BCH_ERR_bucket_alloc_blocked ||
1189+ ret == - BCH_ERR_open_buckets_empty )
1190+ ret = 0 ; /* wait and retry */
11921191
11931192 bch2_disk_reservation_put (c , & disk_res );
1194-
11951193 closure_sync (& cl );
1196-
1197- if (ret &&
1198- ret != - BCH_ERR_bucket_alloc_blocked &&
1199- ret != - BCH_ERR_open_buckets_empty )
1200- break ;
12011194 }
12021195
1203- bch_err_fn (c , ret );
1204- unlock :
1196+ return ret ;
1197+ }
1198+
1199+ /*
1200+ * Allocate more journal space at runtime - not currently making use if it, but
1201+ * the code works:
1202+ */
1203+ int bch2_set_nr_journal_buckets (struct bch_fs * c , struct bch_dev * ca ,
1204+ unsigned nr )
1205+ {
1206+ down_write (& c -> state_lock );
1207+ int ret = bch2_set_nr_journal_buckets_loop (c , ca , nr , false);
12051208 up_write (& c -> state_lock );
1209+
1210+ bch_err_fn (c , ret );
12061211 return ret ;
12071212}
12081213
@@ -1228,7 +1233,7 @@ int bch2_dev_journal_alloc(struct bch_dev *ca, bool new_fs)
12281233 min (1 << 13 ,
12291234 (1 << 24 ) / ca -> mi .bucket_size ));
12301235
1231- ret = __bch2_set_nr_journal_buckets (ca , nr , new_fs , NULL );
1236+ ret = bch2_set_nr_journal_buckets_loop (ca -> fs , ca , nr , new_fs );
12321237err :
12331238 bch_err_fn (ca , ret );
12341239 return ret ;
0 commit comments