@@ -68,6 +68,33 @@ void bch2_replicas_entry_to_text(struct printbuf *out,
6868 prt_printf (out , "]" );
6969}
7070
71+ int bch2_replicas_entry_validate (struct bch_replicas_entry * r ,
72+ struct bch_sb * sb ,
73+ struct printbuf * err )
74+ {
75+ if (!r -> nr_devs ) {
76+ prt_printf (err , "no devices in entry " );
77+ goto bad ;
78+ }
79+
80+ if (r -> nr_required > 1 &&
81+ r -> nr_required >= r -> nr_devs ) {
82+ prt_printf (err , "bad nr_required in entry " );
83+ goto bad ;
84+ }
85+
86+ for (unsigned i = 0 ; i < r -> nr_devs ; i ++ )
87+ if (!bch2_dev_exists (sb , r -> devs [i ])) {
88+ prt_printf (err , "invalid device %u in entry " , r -> devs [i ]);
89+ goto bad ;
90+ }
91+
92+ return 0 ;
93+ bad :
94+ bch2_replicas_entry_to_text (err , r );
95+ return - BCH_ERR_invalid_replicas_entry ;
96+ }
97+
7198void bch2_cpu_replicas_to_text (struct printbuf * out ,
7299 struct bch_replicas_cpu * r )
73100{
@@ -163,7 +190,8 @@ void bch2_devlist_to_replicas(struct bch_replicas_entry *e,
163190}
164191
165192static struct bch_replicas_cpu
166- cpu_replicas_add_entry (struct bch_replicas_cpu * old ,
193+ cpu_replicas_add_entry (struct bch_fs * c ,
194+ struct bch_replicas_cpu * old ,
167195 struct bch_replicas_entry * new_entry )
168196{
169197 unsigned i ;
@@ -173,6 +201,9 @@ cpu_replicas_add_entry(struct bch_replicas_cpu *old,
173201 replicas_entry_bytes (new_entry )),
174202 };
175203
204+ for (i = 0 ; i < new_entry -> nr_devs ; i ++ )
205+ BUG_ON (!bch2_dev_exists2 (c , new_entry -> devs [i ]));
206+
176207 BUG_ON (!new_entry -> data_type );
177208 verify_replicas_entry (new_entry );
178209
@@ -382,15 +413,15 @@ static int bch2_mark_replicas_slowpath(struct bch_fs *c,
382413
383414 if (c -> replicas_gc .entries &&
384415 !__replicas_has_entry (& c -> replicas_gc , new_entry )) {
385- new_gc = cpu_replicas_add_entry (& c -> replicas_gc , new_entry );
416+ new_gc = cpu_replicas_add_entry (c , & c -> replicas_gc , new_entry );
386417 if (!new_gc .entries ) {
387418 ret = - BCH_ERR_ENOMEM_cpu_replicas ;
388419 goto err ;
389420 }
390421 }
391422
392423 if (!__replicas_has_entry (& c -> replicas , new_entry )) {
393- new_r = cpu_replicas_add_entry (& c -> replicas , new_entry );
424+ new_r = cpu_replicas_add_entry (c , & c -> replicas , new_entry );
394425 if (!new_r .entries ) {
395426 ret = - BCH_ERR_ENOMEM_cpu_replicas ;
396427 goto err ;
@@ -598,7 +629,7 @@ int bch2_replicas_set_usage(struct bch_fs *c,
598629 if (idx < 0 ) {
599630 struct bch_replicas_cpu n ;
600631
601- n = cpu_replicas_add_entry (& c -> replicas , r );
632+ n = cpu_replicas_add_entry (c , & c -> replicas , r );
602633 if (!n .entries )
603634 return - BCH_ERR_ENOMEM_cpu_replicas ;
604635
@@ -797,7 +828,7 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
797828 struct bch_sb * sb ,
798829 struct printbuf * err )
799830{
800- unsigned i , j ;
831+ unsigned i ;
801832
802833 sort_cmp_size (cpu_r -> entries ,
803834 cpu_r -> nr ,
@@ -808,31 +839,9 @@ static int bch2_cpu_replicas_validate(struct bch_replicas_cpu *cpu_r,
808839 struct bch_replicas_entry * e =
809840 cpu_replicas_entry (cpu_r , i );
810841
811- if (e -> data_type >= BCH_DATA_NR ) {
812- prt_printf (err , "invalid data type in entry " );
813- bch2_replicas_entry_to_text (err , e );
814- return - BCH_ERR_invalid_sb_replicas ;
815- }
816-
817- if (!e -> nr_devs ) {
818- prt_printf (err , "no devices in entry " );
819- bch2_replicas_entry_to_text (err , e );
820- return - BCH_ERR_invalid_sb_replicas ;
821- }
822-
823- if (e -> nr_required > 1 &&
824- e -> nr_required >= e -> nr_devs ) {
825- prt_printf (err , "bad nr_required in entry " );
826- bch2_replicas_entry_to_text (err , e );
827- return - BCH_ERR_invalid_sb_replicas ;
828- }
829-
830- for (j = 0 ; j < e -> nr_devs ; j ++ )
831- if (!bch2_dev_exists (sb , e -> devs [j ])) {
832- prt_printf (err , "invalid device %u in entry " , e -> devs [j ]);
833- bch2_replicas_entry_to_text (err , e );
834- return - BCH_ERR_invalid_sb_replicas ;
835- }
842+ int ret = bch2_replicas_entry_validate (e , sb , err );
843+ if (ret )
844+ return ret ;
836845
837846 if (i + 1 < cpu_r -> nr ) {
838847 struct bch_replicas_entry * n =
0 commit comments