@@ -166,6 +166,11 @@ impl TapeOperations {
166166 // Locate to write position
167167 let _write_state = self . locate_to_write_position ( ) . await ?;
168168
169+ // Explicitly set block size (and Buffered Mode) before writing
170+ // This corresponds to LTFSCopyGUI: TapeUtils.SetBlockSize(driveHandle, plabel.blocksize)
171+ info ! ( "Setting drive block size to {} (Buffered Mode enabled)" , self . block_size) ;
172+ self . scsi . set_block_size ( self . block_size ) ?;
173+
169174 // Get write start position
170175 let write_start_position = self . scsi . read_position ( ) ?;
171176
@@ -192,6 +197,8 @@ impl TapeOperations {
192197 let mut total_blocks_written = 0u32 ;
193198 let mut total_bytes_written = 0u64 ;
194199 let write_start_time = std:: time:: Instant :: now ( ) ;
200+ let mut last_progress_bytes = 0u64 ;
201+ let mut last_progress_time = std:: time:: Instant :: now ( ) ;
195202
196203 // Choose processing strategy based on file size
197204 if file_size <= self . block_size as u64 {
@@ -240,24 +247,22 @@ impl TapeOperations {
240247 self . write_progress . files_written += 1 ;
241248 self . write_progress . bytes_written += bytes_read as u64 ;
242249 } else {
243- // Large file: block-wise streaming processing
250+ // Large file: block-wise streaming (same as LTFSCopyGUI)
251+ // Windows SCSI pass-through doesn't support multi-block batch writes
244252 info ! (
245253 "Processing large file ({} bytes), using block-wise streaming" ,
246254 file_size
247255 ) ;
248256
249257 let mut buffer = vec ! [ 0u8 ; self . block_size as usize ] ;
250258 let mut remaining_bytes = file_size;
259+
260+ info ! ( "Starting write loop (Block size: {})" , self . block_size) ;
251261
252262 while remaining_bytes > 0 {
253-
254-
255263 // Calculate bytes to read for current block
256264 let bytes_to_read = std:: cmp:: min ( remaining_bytes, self . block_size as u64 ) as usize ;
257265
258- // Clear buffer (for last block, this ensures zero padding)
259- buffer. fill ( 0 ) ;
260-
261266 // Read data from file
262267 let bytes_read = buf_reader
263268 . read ( & mut buffer[ ..bytes_to_read] )
@@ -275,10 +280,7 @@ impl TapeOperations {
275280 calc. propagate ( & buffer[ ..bytes_read] ) ;
276281 }
277282
278-
279-
280-
281- // Write block to tape (use variable-length buffer slice to avoid ILI)
283+ // Write single block to tape (like LTFSCopyGUI)
282284 let blocks_written = self . scsi . write_blocks ( 1 , & buffer[ ..bytes_read] ) ?;
283285
284286 if blocks_written != 1 {
@@ -295,10 +297,38 @@ impl TapeOperations {
295297 // Update progress
296298 self . write_progress . current_bytes_processed += bytes_read as u64 ;
297299
298- debug ! (
299- "Written {} blocks, {} bytes, remaining {} bytes" ,
300- total_blocks_written, total_bytes_written, remaining_bytes
301- ) ;
300+ // Log progress every 100MB
301+ let bytes_since_last_log = total_bytes_written - last_progress_bytes;
302+ if bytes_since_last_log >= 100 * 1024 * 1024 {
303+ let elapsed = write_start_time. elapsed ( ) ;
304+ let elapsed_secs = elapsed. as_secs_f64 ( ) ;
305+
306+ let overall_speed_mbps = if elapsed_secs > 0.0 {
307+ ( total_bytes_written as f64 / ( 1024.0 * 1024.0 ) ) / elapsed_secs
308+ } else {
309+ 0.0
310+ } ;
311+
312+ let recent_elapsed = last_progress_time. elapsed ( ) . as_secs_f64 ( ) ;
313+ let recent_speed_mbps = if recent_elapsed > 0.0 {
314+ ( bytes_since_last_log as f64 / ( 1024.0 * 1024.0 ) ) / recent_elapsed
315+ } else {
316+ 0.0
317+ } ;
318+
319+ let gb_written = total_bytes_written as f64 / ( 1024.0 * 1024.0 * 1024.0 ) ;
320+
321+ info ! (
322+ "📊 Write progress: {:.2} GB written | Speed: {:.2} MB/s (avg: {:.2} MB/s) | Blocks: {}" ,
323+ gb_written,
324+ recent_speed_mbps,
325+ overall_speed_mbps,
326+ total_blocks_written
327+ ) ;
328+
329+ last_progress_bytes = total_bytes_written;
330+ last_progress_time = std:: time:: Instant :: now ( ) ;
331+ }
302332 }
303333
304334 // Complete hash calculation
@@ -408,6 +438,11 @@ impl TapeOperations {
408438 // Prepare for writing to tape
409439 self . scsi . locate_to_eod ( 1 ) ?;
410440
441+ // Explicitly set block size (and Buffered Mode) before writing
442+ let block_size_u32 = self . write_options . block_size ;
443+ info ! ( "Setting drive block size to {} (Buffered Mode enabled) for stream" , block_size_u32) ;
444+ self . scsi . set_block_size ( block_size_u32) ?;
445+
411446 let write_start_position = self . scsi . read_position ( ) ?;
412447
413448 // Create file entry in index - now guaranteed to have index
@@ -416,9 +451,10 @@ impl TapeOperations {
416451 . and_then ( |idx| idx. highestfileuid )
417452 . unwrap_or ( 0 ) + 1 ;
418453
419- // ⭐ STREAMING WRITE - Ensure full-sized blocks for LTFS compatibility
420- // LTFSCopyGUI expects consistent block sizes when reading back
454+ // ⭐ STREAMING WRITE - Single block at a time (like LTFSCopyGUI)
455+ // Windows SCSI pass-through doesn't support multi-block batch writes
421456 let block_size = self . write_options . block_size as usize ;
457+
422458 let mut write_buffer = vec ! [ 0u8 ; block_size] ; // Buffer for writing full blocks
423459 let mut read_buffer = vec ! [ 0u8 ; block_size] ; // Buffer for reading from stream
424460 let mut buffer_fill = 0usize ; // How many bytes are currently in write_buffer
@@ -428,7 +464,10 @@ impl TapeOperations {
428464 let mut last_progress_bytes = 0u64 ;
429465 let mut last_progress_time = std:: time:: Instant :: now ( ) ;
430466
431- info ! ( "Starting streaming write with block size: {} bytes (fixed transfer size)" , block_size) ;
467+ info ! (
468+ "Starting streaming write (Block size: {} bytes, single-block mode)" ,
469+ block_size
470+ ) ;
432471
433472 loop {
434473 // Read data from the stream
@@ -461,7 +500,7 @@ impl TapeOperations {
461500 buffer_fill += bytes_to_copy;
462501 offset += bytes_to_copy;
463502
464- // If buffer is full, write it to tape
503+ // If buffer is full, write single block to tape
465504 if buffer_fill == block_size {
466505 let blocks_written = self . scsi . write_blocks ( 1 , & write_buffer) ? as u64 ;
467506 total_blocks_written += blocks_written;
@@ -471,20 +510,18 @@ impl TapeOperations {
471510 }
472511 }
473512
474- // Log progress every 1GB with detailed statistics
513+ // Log progress every 100MB with detailed statistics
475514 let bytes_since_last_log = total_bytes_written - last_progress_bytes;
476- if bytes_since_last_log >= 1024 * 1024 * 1024 {
515+ if bytes_since_last_log >= 100 * 1024 * 1024 {
477516 let elapsed = write_start_time. elapsed ( ) ;
478517 let elapsed_secs = elapsed. as_secs_f64 ( ) ;
479518
480- // Calculate overall speed
481519 let overall_speed_mbps = if elapsed_secs > 0.0 {
482520 ( total_bytes_written as f64 / ( 1024.0 * 1024.0 ) ) / elapsed_secs
483521 } else {
484522 0.0
485523 } ;
486524
487- // Calculate recent speed (since last log)
488525 let recent_elapsed = last_progress_time. elapsed ( ) . as_secs_f64 ( ) ;
489526 let recent_speed_mbps = if recent_elapsed > 0.0 {
490527 ( bytes_since_last_log as f64 / ( 1024.0 * 1024.0 ) ) / recent_elapsed
0 commit comments