Use tables of callbacks for the functions.
[virt-df.git] / lib / diskimage_ext2.ml
index 1b70977..ea020b5 100644 (file)
@@ -24,12 +24,20 @@ open Printf
 
 open Diskimage_utils
 
+open Int63.Operators
+
+let ( +* ) = Int32.add
+let ( -* ) = Int32.sub
+let ( ** ) = Int32.mul
+let ( /* ) = Int32.div
+
 let plugin_id = "ext2"
-let superblock_offset = 1024L
+let superblock_offset = ~^1024
+let superblock_len = ~^1024
 
 let probe dev =
   (* Load the superblock. *)
-  let bits = dev#read_bitstring superblock_offset 1024 in
+  let bits = dev#read_bitstring superblock_offset superblock_len in
 
   (* The structure is straight from /usr/include/linux/ext3_fs.h *)
   bitmatch bits with
@@ -88,8 +96,7 @@ let probe dev =
 
    (* Work out the block size in bytes. *)
    let s_log_block_size = Int32.to_int s_log_block_size in
-   let block_size = 1024L in
-   let block_size = Int64.shift_left block_size s_log_block_size in
+   let block_size = ~^1024 <^< s_log_block_size in
 
    (* Number of groups. *)
    let s_groups_count =
@@ -110,26 +117,43 @@ let probe dev =
    (* Calculate the block overhead (used by superblocks, inodes, etc.)
     * See fs/ext2/super.c.
     *)
-   let overhead = Int64.of_int32 s_first_data_block in
+   let overhead = Int63.of_int32 s_first_data_block in
    let overhead = (* XXX *) overhead in
 
+   (* The blocksize of the filesystem is likely to be quite different
+    * from that of the underlying device, so create an overlay device
+    * with the natural filesystem blocksize.
+    *)
+   let fs_dev = new blocksize_overlay block_size dev in
+
    {
      fs_plugin_id = plugin_id;
-     fs_block_size = block_size;
-     fs_blocks_total = Int64.of_int32 s_blocks_count -^ overhead;
+     fs_dev = fs_dev;
+
+     fs_blocksize = block_size;
+     fs_blocks_total = Int63.of_int32 s_blocks_count -^ overhead;
+
      fs_is_swap = false;
-     fs_blocks_reserved = Int64.of_int32 s_r_blocks_count;
-     fs_blocks_avail = Int64.of_int32 s_free_blocks_count;
+
+     fs_blocks_reserved = Int63.of_int32 s_r_blocks_count;
+     fs_blocks_avail = Int63.of_int32 s_free_blocks_count;
      fs_blocks_used =
-       Int64.of_int32 s_blocks_count -^ overhead
-       -^ Int64.of_int32 s_free_blocks_count;
-     fs_inodes_total = Int64.of_int32 s_inodes_count;
-     fs_inodes_reserved = 0L;  (* XXX? *)
-     fs_inodes_avail = Int64.of_int32 s_free_inodes_count;
-     fs_inodes_used = Int64.of_int32 s_inodes_count
-       (*-^ 0L*)
-       -^ Int64.of_int32 s_free_inodes_count;
+       Int63.of_int32 s_blocks_count -^ overhead
+       -^ Int63.of_int32 s_free_blocks_count;
+     fs_inodes_total = Int63.of_int32 s_inodes_count;
+     fs_inodes_reserved = ~^0; (* XXX? *)
+     fs_inodes_avail = Int63.of_int32 s_free_inodes_count;
+     fs_inodes_used = Int63.of_int32 s_inodes_count
+       (*-^ 0*)
+       -^ Int63.of_int32 s_free_inodes_count;
    }
 
   | { _ } ->
       raise Not_found                  (* Not an EXT2/3 superblock. *)
+
+let offset_is_free _ _ = false
+
+let callbacks = {
+  fs_cb_probe = probe;
+  fs_cb_offset_is_free = offset_is_free;
+}