@@ -39,9 +39,9 @@ pub enum PlanError {
3939#[ derive( Debug , Clone ) ]
4040pub enum Change {
4141 /// Add a new partition
42- AddPartition { start : u64 , end : u64 } ,
42+ AddPartition { start : u64 , end : u64 , partition_id : u32 } ,
4343 /// Delete an existing partition
44- DeletePartition { original_index : usize } ,
44+ DeletePartition { original_index : usize , partition_id : u32 } ,
4545}
4646
4747/// A disk partitioning planner.
@@ -55,6 +55,12 @@ pub struct Planner {
5555 changes : VecDeque < Change > ,
5656 /// Original partition layout for reference
5757 original_regions : Vec < Region > ,
58+ /// Track original partition IDs
59+ original_partition_ids : Vec < u32 > ,
60+ /// Next available partition ID for new partitions
61+ next_partition_id : u32 ,
62+
63+ wipe_disk : bool ,
5864}
5965
6066/// A contiguous region of disk space defined by absolute start and end positions
@@ -189,16 +195,24 @@ impl Change {
189195 /// Get a human readable description of this change
190196 pub fn describe ( & self , disk_size : u64 ) -> String {
191197 match self {
192- Change :: AddPartition { start, end } => {
198+ Change :: AddPartition {
199+ start,
200+ end,
201+ partition_id,
202+ } => {
193203 format ! (
194- "Add new partition: {} ({} at {})" ,
204+ "Add new partition #{}: {} ({} at {})" ,
205+ partition_id,
195206 format_size( end - start) ,
196207 Region :: new( * start, * end) . describe( disk_size) ,
197208 format_position( * start, disk_size)
198209 )
199210 }
200- Change :: DeletePartition { original_index } => {
201- format ! ( "Delete partition #{}" , original_index + 1 )
211+ Change :: DeletePartition {
212+ original_index,
213+ partition_id,
214+ } => {
215+ format ! ( "Delete partition #{} (index {})" , partition_id, original_index + 1 )
202216 }
203217 }
204218 }
@@ -209,18 +223,25 @@ impl Planner {
209223 pub fn new ( device : & BlockDevice ) -> Self {
210224 debug ! ( "Creating new partition planner for device of size {}" , device. size( ) ) ;
211225
212- // Extract original regions from device
213- let original_regions = device
214- . partitions ( )
215- . iter ( )
216- . map ( |p| Region :: new ( p. start , p. end ) )
217- . collect ( ) ;
226+ // Extract original regions and partition IDs from device
227+ let mut original_regions = Vec :: new ( ) ;
228+ let mut original_partition_ids = Vec :: new ( ) ;
229+ let mut max_id = 0u32 ;
230+
231+ for part in device. partitions ( ) {
232+ original_regions. push ( Region :: new ( part. start , part. end ) ) ;
233+ original_partition_ids. push ( part. number ) ;
234+ max_id = max_id. max ( part. number ) ;
235+ }
218236
219237 Self {
220238 usable_start : 0 ,
221239 usable_end : device. size ( ) ,
222240 changes : VecDeque :: new ( ) ,
223241 original_regions,
242+ original_partition_ids,
243+ next_partition_id : max_id + 1 ,
244+ wipe_disk : false ,
224245 }
225246 }
226247
@@ -262,7 +283,11 @@ impl Planner {
262283
263284 // First pass: collect indices to delete
264285 for change in & self . changes {
265- if let Change :: DeletePartition { original_index } = change {
286+ if let Change :: DeletePartition {
287+ original_index,
288+ partition_id : _,
289+ } = change
290+ {
266291 deleted_indices. push ( * original_index) ;
267292 }
268293 }
@@ -276,8 +301,13 @@ impl Planner {
276301
277302 // Second pass: add new partitions
278303 for change in & self . changes {
279- if let Change :: AddPartition { start, end } = change {
280- debug ! ( "Adding partition {}..{}" , start, end) ;
304+ if let Change :: AddPartition {
305+ start,
306+ end,
307+ partition_id,
308+ } = change
309+ {
310+ debug ! ( "Adding partition {}..{} (ID: {})" , start, end, partition_id) ;
281311 layout. push ( Region {
282312 start : * start,
283313 end : * end,
@@ -358,10 +388,12 @@ impl Planner {
358388 }
359389 }
360390
361- debug ! ( "Adding new partition to change queue" ) ;
391+ let partition_id = self . allocate_partition_id ( ) ;
392+ debug ! ( "Adding new partition with ID {} to change queue" , partition_id) ;
362393 self . changes . push_back ( Change :: AddPartition {
363394 start : aligned_start,
364395 end : aligned_end,
396+ partition_id,
365397 } ) ;
366398 Ok ( ( ) )
367399 }
@@ -378,9 +410,18 @@ impl Planner {
378410 } ) ;
379411 }
380412
381- debug ! ( "Adding partition deletion to change queue" ) ;
382- self . changes
383- . push_back ( Change :: DeletePartition { original_index : index } ) ;
413+ let partition_id = self
414+ . get_original_partition_id ( index)
415+ . ok_or ( PlanError :: RegionOutOfBounds {
416+ start : self . usable_start ,
417+ end : self . usable_size ( ) ,
418+ } ) ?;
419+
420+ debug ! ( "Adding deletion of partition ID {} to change queue" , partition_id) ;
421+ self . changes . push_back ( Change :: DeletePartition {
422+ original_index : index,
423+ partition_id,
424+ } ) ;
384425 Ok ( ( ) )
385426 }
386427
@@ -425,8 +466,24 @@ impl Planner {
425466 debug ! ( "Planning to create new GPT partition table" ) ;
426467 self . changes . clear ( ) ; // Clear any existing changes
427468 self . original_regions . clear ( ) ; // Clear original partitions
469+ self . wipe_disk = true ;
428470 Ok ( ( ) )
429471 }
472+
473+ pub fn wipe_disk ( & self ) -> bool {
474+ self . wipe_disk
475+ }
476+ /// Get the next available partition ID and increment the counter
477+ pub fn allocate_partition_id ( & mut self ) -> u32 {
478+ let id = self . next_partition_id ;
479+ self . next_partition_id += 1 ;
480+ id
481+ }
482+
483+ /// Get the original partition ID for a given index
484+ pub fn get_original_partition_id ( & self , index : usize ) -> Option < u32 > {
485+ self . original_partition_ids . get ( index) . copied ( )
486+ }
430487}
431488
432489#[ cfg( test) ]
0 commit comments