+ (* Return 'i' rounded up to the next multiple of 'a'. *)
+ let roundup64 i a = let a = a -^ 1L in (i +^ a) &^ (~^ a) in
+
+ let rec loop partnum start = function
+ | p :: ps ->
+ (match p.p_operation with
+ | OpDelete -> loop partnum start ps (* skip p *)
+
+ | OpIgnore | OpCopy -> (* same size *)
+ (* Size in sectors. *)
+ let size = (p.p_part.G.part_size +^ sectsize -^ 1L) /^ sectsize in
+ (* Start of next partition + alignment. *)
+ let end_ = start +^ size in
+ let next = roundup64 end_ alignment in
+
+ { p with p_target_start = start; p_target_end = end_ -^ 1L;
+ p_target_partnum = partnum } :: loop (partnum+1) next ps
+
+ | OpResize newsize -> (* resized partition *)
+ (* New size in sectors. *)
+ let size = (newsize +^ sectsize -^ 1L) /^ sectsize in
+ (* Start of next partition + alignment. *)
+ let next = start +^ size in
+ let next = roundup64 next alignment in
+
+ { p with p_target_start = start; p_target_end = next -^ 1L;
+ p_target_partnum = partnum } :: loop (partnum+1) next ps
+ )
+
+ | [] ->
+ (* Create the surplus partition if there is room for it. *)
+ if extra_partition && surplus >= min_extra_partition then (
+ [ {
+ (* Since this partition has no source, this data is
+ * meaningless and not used since the operation is
+ * OpIgnore.
+ *)
+ p_name = "";
+ p_part = { G.part_num = 0l; part_start = 0L; part_end = 0L;
+ part_size = 0L };
+ p_bootable = false; p_mbr_id = None; p_type = ContentUnknown;
+
+ (* Target information is meaningful. *)
+ p_operation = OpIgnore;
+ p_target_partnum = partnum;
+ p_target_start = start; p_target_end = ~^ 64L
+ } ]
+ )
+ else
+ []