@@ -1258,58 +1258,38 @@ impl VirtualFs {
12581258 // Maximum bytes we should return (capped at file boundary).
12591259 let to_read = ( ( size as u64 ) . min ( file_size - offset) ) as usize ;
12601260
1261- // Fast path: forward buffer has enough data (common case, zero-copy).
12621261 // IMPORTANT: Never return a short read unless at real EOF.
12631262 // The Linux FUSE kernel module shrinks i_size on short reads
12641263 // (fuse_read_update_size), which makes subsequent reads return
12651264 // 0 bytes and truncates the file from the application's view.
1266- if let Some ( data) = prefetch_state. try_serve_forward ( offset, size)
1267- && data. len ( ) == to_read
1268- {
1269- debug ! ( "prefetch hit (forward): offset={}, len={}" , offset, data. len( ) ) ;
1270- let eof = offset + data. len ( ) as u64 >= file_size;
1271- return Ok ( ( data, eof) ) ;
1272- }
12731265
1274- // Seek window fast path (also zero-copy)
1275- if let Some ( data) = prefetch_state. try_serve_seek ( offset, size)
1276- && data. len ( ) == to_read
1277- {
1278- debug ! ( "prefetch hit (seek): offset={}, len={}" , offset, data. len( ) ) ;
1279- let eof = offset + data. len ( ) as u64 >= file_size;
1280- return Ok ( ( data, eof) ) ;
1281- }
1282-
1283- // Assembly loop: serve available bytes, fetch more, repeat.
1284- // Only reached at prefetch window boundaries or cache misses.
12851266 let mut response = BytesMut :: with_capacity ( to_read) ;
12861267 let mut cursor = offset;
12871268
1288- loop {
1289- // Drain forward buffer into response
1290- let remaining = ( to_read - response. len ( ) ) as u32 ;
1291- if let Some ( data) = prefetch_state. try_serve_forward ( cursor, remaining) {
1292- cursor += data. len ( ) as u64 ;
1293- response. extend_from_slice ( & data) ;
1294- if response. len ( ) == to_read {
1295- break ;
1296- }
1269+ // Fast path: forward buffer has enough data (common case, zero-copy).
1270+ if let Some ( data) = prefetch_state. try_serve_forward ( offset, size) {
1271+ if data. len ( ) == to_read {
1272+ debug ! ( "prefetch hit (forward): offset={}, len={}" , offset, data. len( ) ) ;
1273+ let eof = offset + data. len ( ) as u64 >= file_size;
1274+ return Ok ( ( data, eof) ) ;
12971275 }
1298-
1299- // Also try seek window; if it produces data, loop back to
1300- // retry try_serve_forward at the new cursor before fetching.
1301- if response. len ( ) < to_read {
1302- let remaining = ( to_read - response. len ( ) ) as u32 ;
1303- if let Some ( data) = prefetch_state. try_serve_seek ( cursor, remaining) {
1304- cursor += data. len ( ) as u64 ;
1305- response. extend_from_slice ( & data) ;
1306- if response. len ( ) == to_read {
1307- break ;
1308- }
1309- continue ;
1310- }
1276+ cursor += data. len ( ) as u64 ;
1277+ response. extend_from_slice ( & data) ;
1278+ } else if let Some ( data) = prefetch_state. try_serve_seek ( offset, size) {
1279+ // Seek window: only reachable when forward buffer has no data
1280+ // at this offset (backward seek). Zero-copy on full hit.
1281+ if data. len ( ) == to_read {
1282+ debug ! ( "prefetch hit (seek): offset={}, len={}" , offset, data. len( ) ) ;
1283+ let eof = offset + data. len ( ) as u64 >= file_size;
1284+ return Ok ( ( data, eof) ) ;
13111285 }
1286+ cursor += data. len ( ) as u64 ;
1287+ response. extend_from_slice ( & data) ;
1288+ }
13121289
1290+ // Assembly loop: fetch more data until we have to_read bytes.
1291+ // Only reached at prefetch window boundaries or cache misses.
1292+ while response. len ( ) < to_read {
13131293 // Fetch more data
13141294 let remaining = ( to_read - response. len ( ) ) as u32 ;
13151295 let plan = prefetch_state. prepare_fetch ( cursor, remaining) ;
@@ -1478,7 +1458,7 @@ impl VirtualFs {
14781458 }
14791459 } ;
14801460
1481- // Store fetched chunks and loop back to drain them
1461+ // Store fetched chunks
14821462 prefetch_state. store_fetched ( cursor, chunks, total) ;
14831463
14841464 // No-progress guard: return EIO rather than a short read
@@ -1494,6 +1474,13 @@ impl VirtualFs {
14941474 ) ;
14951475 return Err ( libc:: EIO ) ;
14961476 }
1477+
1478+ // Drain freshly filled buffer into response
1479+ let remaining = ( to_read - response. len ( ) ) as u32 ;
1480+ if let Some ( data) = prefetch_state. try_serve_forward ( cursor, remaining) {
1481+ cursor += data. len ( ) as u64 ;
1482+ response. extend_from_slice ( & data) ;
1483+ }
14971484 }
14981485
14991486 let eof = cursor >= file_size;
0 commit comments