@@ -195,23 +195,6 @@ let get_chunk_numbers_in_increasing_order descriptor_list offset =
195195 let chunks = process [] offset descriptor_list in
196196 List. rev chunks
197197
198- let get_allocated_chunks_from_clusters cluster_size cluster_list =
199- let chunk_size = Int64. to_int chunk_size in
200- let chunks_in_cluster = (cluster_size + chunk_size - 1 ) / chunk_size in
201- let set =
202- List. fold_left
203- (fun set cluster_no ->
204- let cluster_offset = cluster_no * cluster_size in
205- let chunk_no = cluster_offset / chunk_size in
206- let chunks_to_add =
207- Seq. init chunks_in_cluster (fun i -> chunk_no + i)
208- in
209- ChunkSet. add_seq chunks_to_add set
210- )
211- ChunkSet. empty cluster_list
212- in
213- set
214-
215198let send_one ofd (__context : Context.t ) rpc session_id progress refresh_session
216199 (prefix , vdi_ref , _size ) =
217200 let size = Db.VDI. get_virtual_size ~__context ~self: vdi_ref in
@@ -317,26 +300,47 @@ let send_one ofd (__context : Context.t) rpc session_id progress refresh_session
317300 | _ ->
318301 failwith (Printf. sprintf " %s: unreachable" __FUNCTION__)
319302 in
320- let set =
321- get_allocated_chunks_from_clusters cluster_size cluster_list
322- in
323303 (* First and last chunks are always written - it's a limitation
324304 of the XVA format *)
325305 let last_chunk =
326306 Int64. ((to_int size - to_int chunk_size + 1 ) / to_int chunk_size)
327307 in
328- let set = set |> ChunkSet. add 0 |> ChunkSet. add last_chunk in
329- ChunkSet. iter
330- (fun this_chunk_no ->
331- let offset = Int64. (mul (of_int this_chunk_no) chunk_size) in
308+ let process_chunk chunk_no ~force =
309+ if force || (chunk_no <> 0 && chunk_no <> last_chunk) then
310+ let offset = Int64. (mul (of_int chunk_no) chunk_size) in
332311 let _ =
333- write_chunk this_chunk_no offset
312+ write_chunk chunk_no offset
334313 ~write_check: (fun _ _ -> true )
335314 ~seek: true ~timeout_workaround: false
336315 in
337316 ()
317+ in
318+
319+ process_chunk 0 ~force: true ;
320+
321+ let chunk_size = Int64. to_int chunk_size in
322+ let chunks_in_cluster =
323+ (cluster_size + chunk_size - 1 ) / chunk_size
324+ in
325+ (* Iterate over allocated intervals, copying every cluster inside *)
326+ List. iter
327+ (fun (cluster_no_left , cluster_no_right ) ->
328+ let calc_chunk cluster =
329+ let cluster_offset = cluster * cluster_size in
330+ let chunk_no = cluster_offset / chunk_size in
331+ chunk_no
332+ in
333+ let left_chunk_no = calc_chunk cluster_no_left in
334+ let right_chunk_no =
335+ calc_chunk cluster_no_right + chunks_in_cluster - 1
336+ in
337+ for i = left_chunk_no to right_chunk_no do
338+ process_chunk i ~force: false
339+ done
338340 )
339- set
341+ cluster_list ;
342+
343+ process_chunk last_chunk ~force: true
340344 with e ->
341345 debug " %s: Falling back to reading the whole raw disk after %s"
342346 __FUNCTION__ (Printexc. to_string e) ;
0 commit comments