@@ -17,6 +17,7 @@ use crate::{
17
17
planner:: { Change , Planner } ,
18
18
GptAttributes ,
19
19
} ;
20
+ const SECTOR_SIZE : u64 = 512 ;
20
21
21
22
/// Errors that can occur when writing changes to disk
22
23
#[ derive( Debug , Error ) ]
@@ -50,21 +51,36 @@ pub struct DiskWriter<'a> {
50
51
pub planner : & ' a Planner ,
51
52
}
52
53
53
- /// Zero out up to 2MiB of a region by writing 32 * 64KiB blocks
54
- fn zero_prefix_n < W : Write + Seek > ( writer : & mut W , offset : u64 , size : u64 ) -> io:: Result < ( ) > {
54
+ /// Zero out a specific region of the disk
55
+ fn zero_region < W : Write + Seek > ( writer : & mut W , offset : u64 , size : u64 ) -> io:: Result < ( ) > {
55
56
let zeros = [ 0u8 ; 65_536 ] ;
56
57
writer. seek ( std:: io:: SeekFrom :: Start ( offset) ) ?;
57
- // Write up to 32 blocks or until we hit the partition size
58
- for _ in 0 ..32 {
59
- if offset + ( 65_536 * ( 32 + 1 ) ) as u64 > size {
60
- break ;
61
- }
58
+ let chunks = ( size / 65_536 ) as usize ;
59
+ for _ in 0 ..chunks {
62
60
writer. write_all ( & zeros) ?;
63
61
}
62
+ // Handle any remaining bytes
63
+ let remainder = size % 65_536 ;
64
+ if remainder > 0 {
65
+ writer. write_all ( & zeros[ ..remainder as usize ] ) ?;
66
+ }
64
67
writer. flush ( ) ?;
65
68
Ok ( ( ) )
66
69
}
67
70
71
+ /// Zero out disk headers by wiping first 2MiB of the disk
72
+ fn zero_disk_headers < W : Write + Seek > ( writer : & mut W ) -> io:: Result < ( ) > {
73
+ // Clear first 2MiB to wipe all common boot structures
74
+ zero_region ( writer, 0 , 2 * 1024 * 1024 )
75
+ }
76
+
77
+ /// Zero out up to 2MiB of a partition by writing 32 * 64KiB blocks
78
+ /// Zero out up to 2MiB of a region by writing 32 * 64KiB blocks
79
+ fn zero_partition_prefix < W : Write + Seek > ( writer : & mut W , offset : u64 , size : u64 ) -> io:: Result < ( ) > {
80
+ let to_zero = std:: cmp:: min ( size, 2 * 1024 * 1024 ) ; // 2MiB max
81
+ zero_region ( writer, offset, to_zero)
82
+ }
83
+
68
84
impl < ' a > DiskWriter < ' a > {
69
85
/// Create a new DiskWriter.
70
86
pub fn new ( device : & ' a BlockDevice , planner : & ' a Planner ) -> Self {
@@ -130,11 +146,13 @@ impl<'a> DiskWriter<'a> {
130
146
131
147
let mut gpt_table = if self . planner . wipe_disk ( ) {
132
148
if writable {
133
- // Zero out the first MiB to clear any old partition tables and boot sectors
134
- zero_prefix_n ( device, 0 , 1_048_576 ) ?;
149
+ // Zero out headers including potential ISO structures
150
+ zero_disk_headers ( device) ?;
135
151
152
+ // Convert total bytes to LBA sectors, subtract 1 as per GPT spec
153
+ let total_lba = self . device . size ( ) / SECTOR_SIZE ;
136
154
let mbr = mbr:: ProtectiveMBR :: with_lb_size (
137
- u32:: try_from ( ( self . device . size ( ) / 512 ) - 1 ) . unwrap_or ( 0xFF_FF_FF_FF ) ,
155
+ u32:: try_from ( total_lba . saturating_sub ( 1 ) ) . unwrap_or ( 0xFF_FF_FF_FF ) ,
138
156
) ;
139
157
eprintln ! ( "size is {}" , self . device. size( ) ) ;
140
158
mbr. overwrite_lba0 ( device) ?;
@@ -177,15 +195,24 @@ impl<'a> DiskWriter<'a> {
177
195
partition_id,
178
196
attributes,
179
197
} => {
180
- let start_lba = * start / 512 ;
181
- let size_lba = ( * end - * start) / 512 ;
198
+ // Convert byte offsets to LBA sectors
199
+ let start_lba = * start / SECTOR_SIZE ;
200
+ let size_bytes = * end - * start;
201
+ let size_lba = size_bytes / SECTOR_SIZE ;
182
202
let ( part_type, part_name) = match attributes. as_ref ( ) . and_then ( |a| a. table . as_gpt ( ) ) {
183
203
Some ( GptAttributes { type_guid, name, .. } ) => {
184
204
( type_guid. clone ( ) , name. clone ( ) . unwrap_or_default ( ) )
185
205
}
186
206
None => ( partition_types:: BASIC , "" . to_string ( ) ) ,
187
207
} ;
188
208
209
+ eprintln ! (
210
+ "Converting partition: bytes {}..{} to LBA {}..{}" ,
211
+ start,
212
+ end,
213
+ start_lba,
214
+ start_lba + size_lba
215
+ ) ;
189
216
let id =
190
217
gpt_table. add_partition_at ( & part_name, * partition_id, start_lba, size_lba, part_type, 0 ) ?;
191
218
println ! ( "Added partition {}: {:?}" , partition_id, id) ;
@@ -212,7 +239,7 @@ impl<'a> DiskWriter<'a> {
212
239
original. sync_all ( ) ?;
213
240
214
241
for ( start, end) in zero_regions {
215
- zero_prefix_n ( original, start, end - start) ?;
242
+ zero_partition_prefix ( original, start, end - start) ?;
216
243
}
217
244
218
245
blkpg:: create_kernel_partitions ( self . device . device ( ) ) ?;
0 commit comments