@@ -150,6 +150,13 @@ static int setup_temp_super(int fd, struct btrfs_mkfs_config *cfg,
150
150
btrfs_set_super_chunk_root (& super , chunk_bytenr );
151
151
btrfs_set_super_cache_generation (& super , -1 );
152
152
btrfs_set_super_incompat_flags (& super , cfg -> features .incompat_flags );
153
+ /*
154
+ * Do not set fst related flags yet, it will be handled after
155
+ * the fs is converted.
156
+ */
157
+ btrfs_set_super_compat_ro_flags (& super , cfg -> features .compat_ro_flags &
158
+ ~(BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE |
159
+ BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE_VALID ));
153
160
if (cfg -> label )
154
161
strncpy_null (super .label , cfg -> label , BTRFS_LABEL_SIZE );
155
162
@@ -200,6 +207,12 @@ static u32 get_item_offset(const struct extent_buffer *eb,
200
207
return cfg -> leaf_data_size ;
201
208
}
202
209
210
+ static bool btrfs_is_bgt (const struct btrfs_mkfs_config * cfg )
211
+ {
212
+ return cfg -> features .compat_ro_flags &
213
+ BTRFS_FEATURE_COMPAT_RO_BLOCK_GROUP_TREE ;
214
+ }
215
+
203
216
static void insert_temp_root_item (struct extent_buffer * buf ,
204
217
struct btrfs_mkfs_config * cfg ,
205
218
u64 objectid , u64 bytenr )
@@ -260,7 +273,8 @@ static inline int write_temp_extent_buffer(int fd, struct extent_buffer *buf,
260
273
261
274
static int setup_temp_root_tree (int fd , struct btrfs_mkfs_config * cfg ,
262
275
u64 root_bytenr , u64 extent_bytenr ,
263
- u64 dev_bytenr , u64 fs_bytenr , u64 csum_bytenr )
276
+ u64 dev_bytenr , u64 fs_bytenr , u64 csum_bytenr ,
277
+ u64 bgt_bytenr )
264
278
{
265
279
struct extent_buffer * buf = NULL ;
266
280
int ret ;
@@ -270,7 +284,8 @@ static int setup_temp_root_tree(int fd, struct btrfs_mkfs_config *cfg,
270
284
* bad key order.
271
285
*/
272
286
UASSERT (root_bytenr < extent_bytenr && extent_bytenr < dev_bytenr &&
273
- dev_bytenr < fs_bytenr && fs_bytenr < csum_bytenr );
287
+ dev_bytenr < fs_bytenr && fs_bytenr < csum_bytenr &&
288
+ csum_bytenr < bgt_bytenr );
274
289
buf = malloc (sizeof (* buf ) + cfg -> nodesize );
275
290
if (!buf )
276
291
return - ENOMEM ;
@@ -284,6 +299,9 @@ static int setup_temp_root_tree(int fd, struct btrfs_mkfs_config *cfg,
284
299
insert_temp_root_item (buf , cfg , BTRFS_DEV_TREE_OBJECTID , dev_bytenr );
285
300
insert_temp_root_item (buf , cfg , BTRFS_FS_TREE_OBJECTID , fs_bytenr );
286
301
insert_temp_root_item (buf , cfg , BTRFS_CSUM_TREE_OBJECTID , csum_bytenr );
302
+ if (btrfs_is_bgt (cfg ))
303
+ insert_temp_root_item (buf , cfg , BTRFS_BLOCK_GROUP_TREE_OBJECTID ,
304
+ bgt_bytenr );
287
305
288
306
ret = write_temp_extent_buffer (fd , buf , root_bytenr , cfg );
289
307
out :
@@ -658,9 +676,12 @@ static void insert_temp_block_group(struct extent_buffer *buf,
658
676
static int setup_temp_extent_tree (int fd , struct btrfs_mkfs_config * cfg ,
659
677
u64 chunk_bytenr , u64 root_bytenr ,
660
678
u64 extent_bytenr , u64 dev_bytenr ,
661
- u64 fs_bytenr , u64 csum_bytenr )
679
+ u64 fs_bytenr , u64 csum_bytenr ,
680
+ u64 bgt_bytenr )
662
681
{
663
- struct extent_buffer * buf = NULL ;
682
+ struct extent_buffer * extent_buf = NULL ;
683
+ struct extent_buffer * bg_buf = NULL ;
684
+ const bool is_bgt = btrfs_is_bgt (cfg );
664
685
int ret ;
665
686
666
687
/*
@@ -669,55 +690,85 @@ static int setup_temp_extent_tree(int fd, struct btrfs_mkfs_config *cfg,
669
690
*/
670
691
UASSERT (chunk_bytenr < root_bytenr && root_bytenr < extent_bytenr &&
671
692
extent_bytenr < dev_bytenr && dev_bytenr < fs_bytenr &&
672
- fs_bytenr < csum_bytenr );
673
- buf = malloc (sizeof (* buf ) + cfg -> nodesize );
674
- if (!buf )
675
- return - ENOMEM ;
693
+ fs_bytenr < csum_bytenr && csum_bytenr < bgt_bytenr );
694
+ extent_buf = malloc (sizeof (* extent_buf ) + cfg -> nodesize );
695
+ if (!extent_buf ) {
696
+ ret = - ENOMEM ;
697
+ goto out ;
698
+ }
676
699
677
- ret = setup_temp_extent_buffer (buf , cfg , extent_bytenr ,
700
+ ret = setup_temp_extent_buffer (extent_buf , cfg , extent_bytenr ,
678
701
BTRFS_EXTENT_TREE_OBJECTID );
679
702
if (ret < 0 )
680
703
goto out ;
681
704
682
- ret = insert_temp_extent_item (fd , buf , cfg , chunk_bytenr ,
705
+ if (is_bgt ) {
706
+ bg_buf = malloc (sizeof (* bg_buf ) + cfg -> nodesize );
707
+ if (!bg_buf ) {
708
+ ret = - ENOMEM ;
709
+ goto out ;
710
+ }
711
+ ret = setup_temp_extent_buffer (bg_buf , cfg , bgt_bytenr ,
712
+ BTRFS_BLOCK_GROUP_TREE_OBJECTID );
713
+ if (ret < 0 )
714
+ goto out ;
715
+ }
716
+
717
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , chunk_bytenr ,
683
718
BTRFS_CHUNK_TREE_OBJECTID );
684
719
if (ret < 0 )
685
720
goto out ;
686
721
687
- insert_temp_block_group (buf , cfg , chunk_bytenr ,
722
+ insert_temp_block_group (is_bgt ? bg_buf : extent_buf , cfg , chunk_bytenr ,
688
723
BTRFS_MKFS_SYSTEM_GROUP_SIZE , cfg -> nodesize ,
689
724
BTRFS_BLOCK_GROUP_SYSTEM );
690
725
691
- ret = insert_temp_extent_item (fd , buf , cfg , root_bytenr ,
726
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , root_bytenr ,
692
727
BTRFS_ROOT_TREE_OBJECTID );
693
728
if (ret < 0 )
694
729
goto out ;
695
730
696
- /* 5 tree block used, root, extent, dev, fs and csum*/
697
- insert_temp_block_group (buf , cfg , root_bytenr ,
698
- BTRFS_CONVERT_META_GROUP_SIZE , cfg -> nodesize * 5 ,
731
+ /*
732
+ * 5 tree block used, root, extent, dev, fs and csum.
733
+ * Plus bg tree if specified.
734
+ */
735
+ insert_temp_block_group (is_bgt ? bg_buf : extent_buf , cfg , root_bytenr ,
736
+ BTRFS_CONVERT_META_GROUP_SIZE ,
737
+ is_bgt ? cfg -> nodesize * 6 : cfg -> nodesize * 5 ,
699
738
BTRFS_BLOCK_GROUP_METADATA );
700
739
701
- ret = insert_temp_extent_item (fd , buf , cfg , extent_bytenr ,
740
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , extent_bytenr ,
702
741
BTRFS_EXTENT_TREE_OBJECTID );
703
742
if (ret < 0 )
704
743
goto out ;
705
- ret = insert_temp_extent_item (fd , buf , cfg , dev_bytenr ,
744
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , dev_bytenr ,
706
745
BTRFS_DEV_TREE_OBJECTID );
707
746
if (ret < 0 )
708
747
goto out ;
709
- ret = insert_temp_extent_item (fd , buf , cfg , fs_bytenr ,
748
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , fs_bytenr ,
710
749
BTRFS_FS_TREE_OBJECTID );
711
750
if (ret < 0 )
712
751
goto out ;
713
- ret = insert_temp_extent_item (fd , buf , cfg , csum_bytenr ,
752
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , csum_bytenr ,
714
753
BTRFS_CSUM_TREE_OBJECTID );
715
754
if (ret < 0 )
716
755
goto out ;
756
+ if (btrfs_is_bgt (cfg )) {
757
+ ret = insert_temp_extent_item (fd , extent_buf , cfg , bgt_bytenr ,
758
+ BTRFS_BLOCK_GROUP_TREE_OBJECTID );
759
+ if (ret < 0 )
760
+ goto out ;
761
+ }
762
+
763
+ ret = write_temp_extent_buffer (fd , extent_buf , extent_bytenr , cfg );
764
+ if (ret < 0 )
765
+ goto out ;
766
+ if (is_bgt )
767
+ ret = write_temp_extent_buffer (fd , bg_buf , bgt_bytenr , cfg );
717
768
718
- ret = write_temp_extent_buffer (fd , buf , extent_bytenr , cfg );
719
769
out :
720
- free (buf );
770
+ free (extent_buf );
771
+ free (bg_buf );
721
772
return ret ;
722
773
}
723
774
@@ -751,6 +802,7 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
751
802
{
752
803
struct cache_tree * free_space = & cctx -> free_space ;
753
804
struct cache_tree * used_space = & cctx -> used_space ;
805
+ const bool is_bgt = btrfs_is_bgt (cfg );
754
806
u64 sys_chunk_start ;
755
807
u64 meta_chunk_start ;
756
808
/* chunk tree bytenr, in system chunk */
@@ -761,6 +813,7 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
761
813
u64 dev_bytenr ;
762
814
u64 fs_bytenr ;
763
815
u64 csum_bytenr ;
816
+ u64 bgt_bytenr = (u64 )- 1 ;
764
817
int ret ;
765
818
766
819
/* Source filesystem must be opened, checked and analyzed in advance */
@@ -814,6 +867,7 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
814
867
* | +nodesize * 2 | device root |
815
868
* | +nodesize * 3 | fs tree |
816
869
* | +nodesize * 4 | csum tree |
870
+ * | +nodesize * 5 | bg tree | (Optional)
817
871
* -------------------------------------
818
872
* Inside the allocated system chunk, the layout will be:
819
873
* | offset | contents |
@@ -827,13 +881,15 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
827
881
dev_bytenr = meta_chunk_start + cfg -> nodesize * 2 ;
828
882
fs_bytenr = meta_chunk_start + cfg -> nodesize * 3 ;
829
883
csum_bytenr = meta_chunk_start + cfg -> nodesize * 4 ;
884
+ if (is_bgt )
885
+ bgt_bytenr = meta_chunk_start + cfg -> nodesize * 5 ;
830
886
831
887
ret = setup_temp_super (fd , cfg , root_bytenr , chunk_bytenr );
832
888
if (ret < 0 )
833
889
goto out ;
834
890
835
891
ret = setup_temp_root_tree (fd , cfg , root_bytenr , extent_bytenr ,
836
- dev_bytenr , fs_bytenr , csum_bytenr );
892
+ dev_bytenr , fs_bytenr , csum_bytenr , bgt_bytenr );
837
893
if (ret < 0 )
838
894
goto out ;
839
895
ret = setup_temp_chunk_tree (fd , cfg , sys_chunk_start , meta_chunk_start ,
@@ -850,13 +906,19 @@ int make_convert_btrfs(int fd, struct btrfs_mkfs_config *cfg,
850
906
ret = setup_temp_empty_tree (fd , cfg , csum_bytenr , BTRFS_CSUM_TREE_OBJECTID );
851
907
if (ret < 0 )
852
908
goto out ;
909
+ if (is_bgt ) {
910
+ ret = setup_temp_empty_tree (fd , cfg , bgt_bytenr ,
911
+ BTRFS_BLOCK_GROUP_TREE_OBJECTID );
912
+ if (ret < 0 )
913
+ goto out ;
914
+ }
853
915
/*
854
916
* Setup extent tree last, since it may need to read tree block key
855
917
* for non-skinny metadata case.
856
918
*/
857
919
ret = setup_temp_extent_tree (fd , cfg , chunk_bytenr , root_bytenr ,
858
920
extent_bytenr , dev_bytenr , fs_bytenr ,
859
- csum_bytenr );
921
+ csum_bytenr , bgt_bytenr );
860
922
out :
861
923
return ret ;
862
924
}
0 commit comments