List.fold_left max 0L
(List.map (fun (_, end_extent, _, _) -> end_extent) segments) in
let size = size_in_extents *^ extent_size in
-object
+object (self)
inherit device
method name = name
method size = size
- (* Read method checks which segment the request lies inside and
- * maps it to the underlying device. If there is no mapping then
- * we have to return an error.
- *
- * The request must lie inside a single extent, otherwise this is
- * also an error (XXX - should lift this restriction, however default
- * extent size is 4 MB so we probably won't hit this very often).
+ (* The natural blocksize for LVM devices is the extent size.
+ * NB. Throws a runtime exception if the extent size is bigger
+ * than an int (only likely to matter on 32 bit).
*)
- method read offset len =
- let offset_in_extents = offset /^ extent_size in
-
- (* Check we don't cross an extent boundary. *)
- if (offset +^ Int64.of_int (len-1)) /^ extent_size <> offset_in_extents
- then invalid_arg "linear_map_device: request crosses extent boundary";
+ method blocksize = Int64.to_int extent_size
- if offset_in_extents < 0L || offset_in_extents >= size_in_extents then
+ (* Map block (extent) i to the underlying device. *)
+ method mapblock i =
+ if i < 0L || i >= size_in_extents then
invalid_arg "linear_map_device: read outside device";
let rec loop = function
| [] ->
- invalid_arg "linear_map_device: offset not mapped"
+ []
| (start_extent, end_extent, dev, pvoffset) :: rest ->
- if start_extent <= offset_in_extents &&
- offset_in_extents < end_extent
- then dev#read (offset +^ pvoffset *^ extent_size) len
- else loop rest
+ if start_extent <= i && i < end_extent then
+ [dev, (pvoffset +^ i) *^ extent_size]
+ else
+ loop rest
in
loop segments
+
+ (* NB. Use the superclass #read method. *)
end
(*----------------------------------------------------------------------*)
let pe_start = pe_start *^ sector_size64 in
let pe_count = get_int64 "pe_count" meta in
let pe_count = pe_count *^ extent_size in
- let pvdev = new offset_device pvuuid pe_start pe_count dev in
+ let pvdev =
+ new offset_device
+ pvuuid (* name *)
+ pe_start pe_count (* start, size in bytes *)
+ (* don't really have a natural block size ... *)
+ (Int64.to_int extent_size)
+ dev (* underlying device *) in
Some (pvname, pvdev)
| _ ->