@@ -1885,9 +1885,9 @@ struct bch_dev *bch2_dev_lookup(struct bch_fs *c, const char *name)
18851885struct bch_fs * bch2_fs_open (char * const * devices , unsigned nr_devices ,
18861886 struct bch_opts opts )
18871887{
1888- struct bch_sb_handle * sb = NULL ;
1888+ DARRAY ( struct bch_sb_handle ) sbs = { 0 } ;
18891889 struct bch_fs * c = NULL ;
1890- unsigned i , best_sb = 0 ;
1890+ struct bch_sb_handle * sb , * best = NULL ;
18911891 struct printbuf errbuf = PRINTBUF ;
18921892 int ret = 0 ;
18931893
@@ -1899,49 +1899,46 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
18991899 goto err ;
19001900 }
19011901
1902- sb = kcalloc (nr_devices , sizeof (* sb ), GFP_KERNEL );
1903- if (!sb ) {
1904- ret = - ENOMEM ;
1902+ ret = darray_make_room (& sbs , nr_devices );
1903+ if (ret )
19051904 goto err ;
1906- }
19071905
1908- for (i = 0 ; i < nr_devices ; i ++ ) {
1909- ret = bch2_read_super (devices [i ], & opts , & sb [i ]);
1906+ for (unsigned i = 0 ; i < nr_devices ; i ++ ) {
1907+ struct bch_sb_handle sb = { NULL };
1908+
1909+ ret = bch2_read_super (devices [i ], & opts , & sb );
19101910 if (ret )
19111911 goto err ;
19121912
1913+ BUG_ON (darray_push (& sbs , sb ));
19131914 }
19141915
1915- for (i = 1 ; i < nr_devices ; i ++ )
1916- if (le64_to_cpu (sb [i ].sb -> seq ) >
1917- le64_to_cpu (sb [best_sb ].sb -> seq ))
1918- best_sb = i ;
1919-
1920- i = 0 ;
1921- while (i < nr_devices ) {
1922- if (i != best_sb &&
1923- !bch2_dev_exists (sb [best_sb ].sb , sb [i ].sb -> dev_idx )) {
1924- pr_info ("%pg has been removed, skipping" , sb [i ].bdev );
1925- bch2_free_super (& sb [i ]);
1926- array_remove_item (sb , nr_devices , i );
1916+ darray_for_each (sbs , sb )
1917+ if (!best || le64_to_cpu (sb -> sb -> seq ) > le64_to_cpu (best -> sb -> seq ))
1918+ best = sb ;
1919+
1920+ darray_for_each_reverse (sbs , sb ) {
1921+ if (sb != best && !bch2_dev_exists (best -> sb , sb -> sb -> dev_idx )) {
1922+ pr_info ("%pg has been removed, skipping" , sb -> bdev );
1923+ bch2_free_super (sb );
1924+ darray_remove_item (& sbs , sb );
1925+ best -= best > sb ;
19271926 continue ;
19281927 }
19291928
1930- ret = bch2_dev_in_fs (sb [ best_sb ]. sb , sb [ i ]. sb );
1929+ ret = bch2_dev_in_fs (best -> sb , sb -> sb );
19311930 if (ret )
19321931 goto err_print ;
1933- i ++ ;
19341932 }
19351933
1936- c = bch2_fs_alloc (sb [ best_sb ]. sb , opts );
1937- if ( IS_ERR ( c )) {
1938- ret = PTR_ERR ( c );
1934+ c = bch2_fs_alloc (best -> sb , opts );
1935+ ret = PTR_ERR_OR_ZERO ( c );
1936+ if ( ret )
19391937 goto err ;
1940- }
19411938
19421939 down_write (& c -> state_lock );
1943- for ( i = 0 ; i < nr_devices ; i ++ ) {
1944- ret = bch2_dev_attach_bdev (c , & sb [ i ] );
1940+ darray_for_each ( sbs , sb ) {
1941+ ret = bch2_dev_attach_bdev (c , sb );
19451942 if (ret ) {
19461943 up_write (& c -> state_lock );
19471944 goto err ;
@@ -1960,7 +1957,9 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
19601957 goto err ;
19611958 }
19621959out :
1963- kfree (sb );
1960+ darray_for_each (sbs , sb )
1961+ bch2_free_super (sb );
1962+ darray_exit (& sbs );
19641963 printbuf_exit (& errbuf );
19651964 module_put (THIS_MODULE );
19661965 return c ;
@@ -1970,9 +1969,6 @@ struct bch_fs *bch2_fs_open(char * const *devices, unsigned nr_devices,
19701969err :
19711970 if (!IS_ERR_OR_NULL (c ))
19721971 bch2_fs_stop (c );
1973- if (sb )
1974- for (i = 0 ; i < nr_devices ; i ++ )
1975- bch2_free_super (& sb [i ]);
19761972 c = ERR_PTR (ret );
19771973 goto out ;
19781974}
0 commit comments