@@ -705,6 +705,92 @@ int gpt_verify_headers(struct blk_desc *dev_desc, gpt_header *gpt_head,
705
705
return 0 ;
706
706
}
707
707
708
+ static void restore_primary_gpt_header (gpt_header * gpt_h , struct blk_desc * dev_desc )
709
+ {
710
+ u32 calc_crc32 ;
711
+ u64 val ;
712
+
713
+ /* recalculate the values for the Primary GPT Header */
714
+ val = le64_to_cpu (gpt_h -> my_lba );
715
+ gpt_h -> my_lba = gpt_h -> alternate_lba ;
716
+ gpt_h -> alternate_lba = cpu_to_le64 (val );
717
+ gpt_h -> partition_entry_lba = cpu_to_le64 (partition_entries_offset (dev_desc ));
718
+
719
+ gpt_h -> header_crc32 = 0 ;
720
+
721
+ calc_crc32 = efi_crc32 ((const unsigned char * )gpt_h ,
722
+ le32_to_cpu (gpt_h -> header_size ));
723
+ gpt_h -> header_crc32 = cpu_to_le32 (calc_crc32 );
724
+ }
725
+
726
+ static int write_one_gpt_table (struct blk_desc * dev_desc ,
727
+ gpt_header * gpt_h , gpt_entry * gpt_e )
728
+ {
729
+ const int pte_blk_cnt = BLOCK_CNT ((gpt_h -> num_partition_entries
730
+ * sizeof (gpt_entry )), dev_desc );
731
+ lbaint_t start ;
732
+ int ret = 0 ;
733
+
734
+ start = le64_to_cpu (gpt_h -> my_lba );
735
+ if (blk_dwrite (dev_desc , start , 1 , gpt_h ) != 1 ) {
736
+ ret = -1 ;
737
+ goto out ;
738
+ }
739
+
740
+ start = le64_to_cpu (gpt_h -> partition_entry_lba );
741
+ if (blk_dwrite (dev_desc , start , pte_blk_cnt , gpt_e ) != pte_blk_cnt ) {
742
+ ret = -1 ;
743
+ goto out ;
744
+ }
745
+
746
+ out :
747
+ return ret ;
748
+ }
749
+
750
+ int gpt_repair_headers (struct blk_desc * dev_desc )
751
+ {
752
+ ALLOC_CACHE_ALIGN_BUFFER_PAD (gpt_header , gpt_h1 , 1 , dev_desc -> blksz );
753
+ ALLOC_CACHE_ALIGN_BUFFER_PAD (gpt_header , gpt_h2 , 1 , dev_desc -> blksz );
754
+ gpt_entry * gpt_e1 = NULL , * gpt_e2 = NULL ;
755
+ int is_gpt1_valid , is_gpt2_valid ;
756
+ int ret = -1 ;
757
+
758
+ is_gpt1_valid = is_gpt_valid (dev_desc , GPT_PRIMARY_PARTITION_TABLE_LBA ,
759
+ gpt_h1 , & gpt_e1 );
760
+ is_gpt2_valid = is_gpt_valid (dev_desc , dev_desc -> lba - 1 ,
761
+ gpt_h2 , & gpt_e2 );
762
+
763
+ if (is_gpt1_valid && is_gpt2_valid ) {
764
+ ret = 0 ;
765
+ goto out ;
766
+ }
767
+
768
+ if (is_gpt1_valid && !is_gpt2_valid ) {
769
+ prepare_backup_gpt_header (gpt_h1 );
770
+ ret = write_one_gpt_table (dev_desc , gpt_h1 , gpt_e1 );
771
+ goto out ;
772
+ }
773
+
774
+ if (!is_gpt1_valid && is_gpt2_valid ) {
775
+ restore_primary_gpt_header (gpt_h2 , dev_desc );
776
+ ret = write_one_gpt_table (dev_desc , gpt_h2 , gpt_e2 );
777
+ goto out ;
778
+ }
779
+
780
+ if (!is_gpt1_valid && !is_gpt2_valid ) {
781
+ ret = -1 ;
782
+ goto out ;
783
+ }
784
+
785
+ out :
786
+ if (is_gpt1_valid )
787
+ free (gpt_e1 );
788
+ if (is_gpt2_valid )
789
+ free (gpt_e2 );
790
+
791
+ return ret ;
792
+ }
793
+
708
794
int gpt_verify_partitions (struct blk_desc * dev_desc ,
709
795
struct disk_partition * partitions , int parts ,
710
796
gpt_header * gpt_head , gpt_entry * * gpt_pte )
0 commit comments