Added #contiguous method to make block mapping more efficient, and
[virt-df.git] / lib / diskimage_lvm2.ml
index ea127cb..4432e90 100644 (file)
@@ -64,22 +64,39 @@ object (self)
    *)
   method blocksize = extent_size
 
-  (* Map block (extent) i to the underlying device. *)
-  method mapblock i =
+  method private map i =
     if i < ~^0 || i >= size_in_extents then
       invalid_arg "linear_map_device: read outside device";
 
     let rec loop = function
       | [] ->
-         []
+         None
       | (start_extent, end_extent, dev, pvoffset) :: rest ->
-         if start_extent <= i && i < end_extent then
-           [dev, (pvoffset +^ i) *^ extent_size]
-         else
+         if start_extent <= i && i < end_extent then (
+           let dev_offset = (pvoffset +^ i) *^ extent_size in
+           Some (start_extent, end_extent, dev, dev_offset, pvoffset)
+         ) else
            loop rest
     in
     loop segments
 
+  (* Map block (extent) i to the underlying device. *)
+  method map_block i =
+    match self#map i with
+    | Some (_, _, dev, dev_offset, _) -> [dev, dev_offset]
+    | None -> []
+
+  (* Continguous span. *)
+  method contiguous offset =
+    let offset_in_extents = offset /^ extent_size in
+
+    (* Get the segment that this offset lies in. *)
+    match self#map offset_in_extents with
+    | Some (_, end_extent, dev, dev_offset, _) ->
+       (* Contiguous bytes up to the end of this extent. *)
+       end_extent *^ extent_size -^ offset
+    | None -> ~^0
+
   (* NB. Use the superclass #read method. *)
 end