33//
44// SPDX-License-Identifier: MPL-2.0
55
6- use std:: fs ;
6+ use std:: { fs , io :: Write } ;
77
88use disks:: BlockDevice ;
99use gpt:: { mbr, partition_types, GptConfig } ;
@@ -14,10 +14,6 @@ use crate::planner::{Change, Planner};
1414/// Errors that can occur when writing changes to disk
1515#[ derive( Debug , Error ) ]
1616pub enum WriteError {
17- /// Device size has changed since the plan was created
18- #[ error( "Device size changed since planning" ) ]
19- DeviceSizeChanged ,
20-
2117 /// A partition ID was used multiple times
2218 #[ error( "Duplicate partition ID: {0}" ) ]
2319 DuplicatePartitionId ( u32 ) ,
@@ -55,7 +51,7 @@ impl<'a> DiskWriter<'a> {
5551 . read ( true )
5652 . write ( false )
5753 . open ( self . device . device ( ) ) ?;
58- self . validate_changes ( & device ) ?;
54+ self . validate_changes ( ) ?;
5955 self . apply_changes ( & mut device, false ) ?;
6056 Ok ( ( ) )
6157 }
@@ -67,21 +63,16 @@ impl<'a> DiskWriter<'a> {
6763 . write ( true )
6864 . open ( self . device . device ( ) ) ?;
6965
70- self . validate_changes ( & device ) ?;
66+ self . validate_changes ( ) ?;
7167 self . apply_changes ( & mut device, true ) ?;
68+ device. flush ( ) ?;
7269 Ok ( ( ) )
7370 }
7471
7572 /// Validate all planned changes before applying them by checking:
7673 /// - Device size matches the planned size
7774 /// - No duplicate partition IDs exist
78- fn validate_changes ( & self , device : & fs:: File ) -> Result < ( ) , WriteError > {
79- // Verify device size matches what we planned for
80- let metadata = device. metadata ( ) ?;
81- if metadata. len ( ) != self . device . size ( ) {
82- return Err ( WriteError :: DeviceSizeChanged ) ;
83- }
84-
75+ fn validate_changes ( & self ) -> Result < ( ) , WriteError > {
8576 // Verify partition IDs don't conflict
8677 let mut used_ids = std:: collections:: HashSet :: new ( ) ;
8778 for change in self . planner . changes ( ) {
@@ -109,20 +100,28 @@ impl<'a> DiskWriter<'a> {
109100 let mbr = mbr:: ProtectiveMBR :: with_lb_size (
110101 u32:: try_from ( ( self . device . size ( ) / 512 ) - 1 ) . unwrap_or ( 0xFF_FF_FF_FF ) ,
111102 ) ;
103+ eprintln ! ( "size is {}" , self . device. size( ) ) ;
112104 mbr. overwrite_lba0 ( device) ?;
113105 }
114106
115- GptConfig :: default ( )
107+ let mut c = GptConfig :: default ( )
116108 . writable ( writable)
117109 . logical_block_size ( gpt:: disk:: LogicalBlockSize :: Lb512 )
118- . create_from_device ( device, None ) ?
110+ . create_from_device ( device, None ) ?;
111+
112+ if writable {
113+ c. write_inplace ( ) ?;
114+ }
115+ c
119116 } else {
120117 GptConfig :: default ( ) . writable ( writable) . open_from_device ( device) ?
121118 } ;
122119
123120 let layout = self . planner . current_layout ( ) ;
124121 let changes = self . planner . changes ( ) ;
125122
123+ eprintln ! ( "Changes: {:?}" , changes) ;
124+
126125 for change in changes {
127126 match change {
128127 Change :: DeletePartition {
@@ -151,7 +150,7 @@ impl<'a> DiskWriter<'a> {
151150 }
152151 }
153152
154- eprintln ! ( "GPT is now: {gpt_table:?}" ) ;
153+ eprintln ! ( "### GPT is now: {gpt_table:?}" ) ;
155154
156155 for region in layout. iter ( ) {
157156 eprintln ! (
@@ -160,6 +159,10 @@ impl<'a> DiskWriter<'a> {
160159 ) ;
161160 }
162161
162+ if writable {
163+ gpt_table. write_inplace ( ) ?;
164+ }
165+
163166 Ok ( ( ) )
164167 }
165168}
0 commit comments