let size = disk#size in (* Size in bytes. *)
let nr_blocks = size /^ blocksize in (* Number of disk sectors. *)
- (* Get the lookup function for this disk. *)
- let lookup = Diskimage.get_owners_lookup machine ownership disk in
+ if !Diskimage.debug then
+ eprintf "Writing disk %s (%s sectors) ...\n%!"
+ disk#name (Int63.to_string nr_blocks);
- (* Lookup each sector. *)
- for blk = 0 to nr_blocks-1 do
- ignore (lookup blk)
- done
- ) machine.Diskimage.m_disks;
+ (* Get the lookup function for this disk. *)
+ let lookup_offset =
+ Diskimage.get_owners_lookup machine ownership disk in
+
+ (* Convenience function to look up a block and test freeness. *)
+ let block_is_free blk =
+ let offset = blk *^ blocksize in
+ Diskimage.offset_is_free (lookup_offset offset)
+ in
+
+ (* Look up owners for each sector in turn. *)
+ let rec loop blk =
+ if blk < nr_blocks then (
+ (* The current sector (blk) is either free or not free. Look
+ * for a stretch of sectors which are the same.
+ *)
+ let current_free = block_is_free blk in
+ let rec find_end blk =
+ if blk < nr_blocks then (
+ if block_is_free blk = current_free then
+ find_end (Int63.succ blk)
+ else
+ blk
+ ) else
+ nr_blocks (* End of the disk image. *)
+ in
+ let end_blk = find_end (Int63.succ blk) in
+
+ (* Current stretch is from blk .. end_blk-1. *)
+ if !Diskimage.debug then
+ eprintf " %s stretch %s to %s-1 (%s bytes)\n"
+ (if current_free then "free" else "used")
+ (Int63.to_string blk) (Int63.to_string end_blk)
+ (Int63.to_string ((end_blk-^blk) *^ blocksize));
+
+
+
+
+ loop end_blk
+ )
+ in
+ loop ~^0
+ ) machine.Diskimage.m_disks