(* The structure is straight from /usr/include/linux/ext3_fs.h *)
bitmatch bits with
- | s_inodes_count : 32 : littleendian; (* Inodes count *)
- s_blocks_count : 32 : littleendian; (* Blocks count *)
- s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *)
- s_free_blocks_count : 32 : littleendian; (* Free blocks count *)
- s_free_inodes_count : 32 : littleendian; (* Free inodes count *)
- s_first_data_block : 32 : littleendian; (* First Data Block *)
- s_log_block_size : 32 : littleendian; (* Block size *)
- s_log_frag_size : 32 : littleendian; (* Fragment size *)
- s_blocks_per_group : 32 : littleendian; (* # Blocks per group *)
- s_frags_per_group : 32 : littleendian; (* # Fragments per group *)
- s_inodes_per_group : 32 : littleendian; (* # Inodes per group *)
- s_mtime : 32 : littleendian; (* Mount time *)
- s_wtime : 32 : littleendian; (* Write time *)
- s_mnt_count : 16 : littleendian; (* Mount count *)
- s_max_mnt_count : 16 : littleendian; (* Maximal mount count *)
- 0xef53 : 16 : littleendian; (* Magic signature *)
- s_state : 16 : littleendian; (* File system state *)
- s_errors : 16 : littleendian; (* Behaviour when detecting errors *)
- s_minor_rev_level : 16 : littleendian; (* minor revision level *)
- s_lastcheck : 32 : littleendian; (* time of last check *)
- s_checkinterval : 32 : littleendian; (* max. time between checks *)
- s_creator_os : 32 : littleendian; (* OS *)
- s_rev_level : 32 : littleendian; (* Revision level *)
- s_def_resuid : 16 : littleendian; (* Default uid for reserved blocks *)
- s_def_resgid : 16 : littleendian; (* Default gid for reserved blocks *)
- s_first_ino : 32 : littleendian; (* First non-reserved inode *)
- s_inode_size : 16 : littleendian; (* size of inode structure *)
- s_block_group_nr : 16 : littleendian; (* block group # of this superblock *)
- s_feature_compat : 32 : littleendian; (* compatible feature set *)
- s_feature_incompat : 32 : littleendian; (* incompatible feature set *)
- s_feature_ro_compat : 32 : littleendian; (* readonly-compatible feature set *)
- s_uuid : 128 : bitstring; (* 128-bit uuid for volume *)
- s_volume_name : 128 : bitstring; (* volume name XXX string *)
- s_last_mounted : 512 : bitstring; (* directory where last mounted XXX string *)
- s_algorithm_usage_bitmap : 32 : littleendian; (* For compression *)
- s_prealloc_blocks : 8; (* Nr of blocks to try to preallocate*)
- s_prealloc_dir_blocks : 8; (* Nr to preallocate for dirs *)
- s_reserved_gdt_blocks : 16 : littleendian; (* Per group desc for online growth *)
- s_journal_uuid : 128 : bitstring; (* uuid of journal superblock *)
- s_journal_inum : 32 : littleendian; (* inode number of journal file *)
- s_journal_dev : 32 : littleendian; (* device number of journal file *)
- s_last_orphan : 32 : littleendian; (* start of list of inodes to delete *)
- s_hash_seed0 : 32 : littleendian; (* HTREE hash seed *)
- s_hash_seed1 : 32 : littleendian;
- s_hash_seed2 : 32 : littleendian;
- s_hash_seed3 : 32 : littleendian;
- s_def_hash_version : 8; (* Default hash version to use *)
- s_reserved_char_pad : 8;
- s_reserved_word_pad : 16 : littleendian;
- s_default_mount_opts : 32 : littleendian;
- s_first_meta_bg : 32 : littleendian; (* First metablock block group *)
- s_reserved : 6080 : bitstring -> (* Padding to the end of the block *)
+ | { s_inodes_count : 32 : littleendian; (* Inodes count *)
+ s_blocks_count : 32 : littleendian; (* Blocks count *)
+ s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *)
+ s_free_blocks_count : 32 : littleendian; (* Free blocks count *)
+ s_free_inodes_count : 32 : littleendian; (* Free inodes count *)
+ s_first_data_block : 32 : littleendian; (* First Data Block *)
+ s_log_block_size : 32 : littleendian; (* Block size *)
+ s_log_frag_size : 32 : littleendian; (* Fragment size *)
+ s_blocks_per_group : 32 : littleendian; (* # Blocks per group *)
+ s_frags_per_group : 32 : littleendian; (* # Fragments per group *)
+ s_inodes_per_group : 32 : littleendian; (* # Inodes per group *)
+ s_mtime : 32 : littleendian; (* Mount time *)
+ s_wtime : 32 : littleendian; (* Write time *)
+ s_mnt_count : 16 : littleendian; (* Mount count *)
+ s_max_mnt_count : 16 : littleendian; (* Maximal mount count *)
+ 0xef53 : 16 : littleendian; (* Magic signature *)
+ s_state : 16 : littleendian; (* File system state *)
+ s_errors : 16 : littleendian; (* Behaviour when detecting errors *)
+ s_minor_rev_level : 16 : littleendian; (* minor revision level *)
+ s_lastcheck : 32 : littleendian; (* time of last check *)
+ s_checkinterval : 32 : littleendian; (* max. time between checks *)
+ s_creator_os : 32 : littleendian; (* OS *)
+ s_rev_level : 32 : littleendian; (* Revision level *)
+ s_def_resuid : 16 : littleendian; (* Default uid for reserved blocks *)
+ s_def_resgid : 16 : littleendian; (* Default gid for reserved blocks *)
+ s_first_ino : 32 : littleendian; (* First non-reserved inode *)
+ s_inode_size : 16 : littleendian; (* size of inode structure *)
+ s_block_group_nr : 16 : littleendian; (* block group # of this superblock *)
+ s_feature_compat : 32 : littleendian; (* compatible feature set *)
+ s_feature_incompat : 32 : littleendian; (* incompatible feature set *)
+ s_feature_ro_compat : 32 : littleendian; (* readonly-compatible feature set *)
+ s_uuid : 128 : string; (* 128-bit uuid for volume *)
+ s_volume_name : 128 : string; (* volume name *)
+ s_last_mounted : 512 : string; (* directory where last mounted *)
+ s_algorithm_usage_bitmap : 32 : littleendian; (* For compression *)
+ s_prealloc_blocks : 8; (* Nr of blocks to try to preallocate*)
+ s_prealloc_dir_blocks : 8; (* Nr to preallocate for dirs *)
+ s_reserved_gdt_blocks : 16 : littleendian;(* Per group desc for online growth *)
+ s_journal_uuid : 128 : string; (* uuid of journal superblock *)
+ s_journal_inum : 32 : littleendian; (* inode number of journal file *)
+ s_journal_dev : 32 : littleendian; (* device number of journal file *)
+ s_last_orphan : 32 : littleendian; (* start of list of inodes to delete *)
+ s_hash_seed0 : 32 : littleendian; (* HTREE hash seed *)
+ s_hash_seed1 : 32 : littleendian;
+ s_hash_seed2 : 32 : littleendian;
+ s_hash_seed3 : 32 : littleendian;
+ s_def_hash_version : 8; (* Default hash version to use *)
+ s_reserved_char_pad : 8;
+ s_reserved_word_pad : 16 : littleendian;
+ s_default_mount_opts : 32 : littleendian;
+ s_first_meta_bg : 32 : littleendian; (* First metablock block group *)
+ _ : 6080 : bitstring } -> (* Padding to the end of the block *)
(* Work out the block size in bytes. *)
let s_log_block_size = Int32.to_int s_log_block_size in
-^ Int64.of_int32 s_free_inodes_count;
}
- | _ ->
+ | { _ } ->
raise Not_found (* Not an EXT2/3 superblock. *)
(* Register with main code. *)
(*Bitmatch.hexdump_bitstring stdout bits;*)
bitmatch bits with
- | sector0 : sector_size*8 : bitstring; (* sector 0 *)
- labelone : 8*8 : bitstring; (* "LABELONE" *)
- padding : 16*8 : bitstring; (* Seems to contain something. *)
- lvm2_ver : 8*8 : bitstring; (* "LVM2 001" *)
- uuid : 32*8 : bitstring; (* UUID *)
- padding2 : (sector_size-64)*8 : bitstring; (* to end of second sector *)
- sector234567 : sector_size*8 * 6 : bitstring; (* sectors 2-6 *)
- padding3 : 0x28*8 : bitstring; (* start of sector 8 *)
- metadata_offset : 32 : littleendian;(* metadata offset *)
- padding4 : 4*8 : bitstring;
- metadata_length : 32 : littleendian (* length of metadata (bytes) *)
- when Bitmatch.string_of_bitstring labelone = "LABELONE" &&
- Bitmatch.string_of_bitstring lvm2_ver = "LVM2 001" ->
-
- (* Metadata offset is relative to end of PV label. *)
- let metadata_offset = metadata_offset +* 0x1000_l in
- (* Metadata length appears to include the trailing \000 which
- * we don't want.
- *)
- let metadata_length = metadata_length -* 1_l in
-
- let metadata = read_metadata dev metadata_offset metadata_length in
-
- let uuid = Bitmatch.string_of_bitstring uuid in
-
- uuid, metadata
-
- | _ ->
- invalid_arg
- (sprintf "LVM2: read_pv_label: %s: not an LVM2 physical volume" dev#name)
+ | {
+ (* sector 0 *)
+ sector0 : sector_size*8 : bitstring;
+
+ (* sector 1 *)
+ "LABELONE" : 64 : string; (* "LABELONE" *)
+ _ : 128 : bitstring; (* Seems to contain something. *)
+ "LVM2 001" : 64 : string; (* "LVM2 001" *)
+ uuid : 256 : string; (* UUID *)
+ endsect : (sector_size-64)*8 : bitstring; (* to end of second sector *)
+
+ (* sectors 2-7 *)
+ sectors234567 : sector_size*8 * 6 : bitstring;
+
+ (* sector 8 *)
+ _ : 320 : bitstring; (* start of sector 8 *)
+ metadata_offset : 32 : littleendian; (* metadata offset *)
+ _ : 32 : bitstring;
+ metadata_length : 32 : littleendian (* length of metadata (bytes) *)
+ } ->
+
+ (* Metadata offset is relative to end of PV label. *)
+ let metadata_offset = metadata_offset +* 0x1000_l in
+ (* Metadata length appears to include the trailing \000 which
+ * we don't want.
+ *)
+ let metadata_length = metadata_length -* 1_l in
+
+ let metadata = read_metadata dev metadata_offset metadata_length in
+
+ uuid, metadata
+
+ | { _ } ->
+ invalid_arg
+ (sprintf "LVM2: read_pv_label: %s: not an LVM2 physical volume"
+ dev#name)
and read_metadata dev offset32 len32 =
if !debug then
@raise Not_found if it is not an MBR.
*)
let rec probe_mbr dev =
- (* Adjust size to sectors. *)
- let size = dev#size /^ sector_size64 in
-
(* Read the first sector. *)
let bits =
try dev#read_bitstring 0L sector_size
(* Does this match a likely-looking MBR? *)
bitmatch bits with
- | padding : 3568 : bitstring; (* padding to byte offset 446 *)
- part0 : 128 : bitstring; (* partitions *)
- part1 : 128 : bitstring;
- part2 : 128 : bitstring;
- part3 : 128 : bitstring;
- 0x55 : 8; 0xAA : 8 -> (* MBR signature *)
+ | { _ : 3568 : bitstring; (* padding to byte offset 446 *)
+ part0 : 128 : bitstring; (* partitions *)
+ part1 : 128 : bitstring;
+ part2 : 128 : bitstring;
+ part3 : 128 : bitstring;
+ 0x55 : 8; 0xAA : 8 } -> (* MBR signature *)
(* Parse the partition table entries. *)
let primaries =
*)
{ parts_name = "MBR"; parts = primaries }
- | _ ->
+ | { _ } ->
raise Not_found (* not an MBR *)
(* Parse a single partition table entry. See the table here:
*)
and parse_mbr_entry dev i bits =
bitmatch bits with
- | 0l : 32; 0l : 32; 0l : 32; 0l : 32 ->
- { part_status = NullEntry; part_type = 0;
- part_dev = null_device; part_content = `Unknown }
-
- | 0 : 8; first_chs : 24;
- part_type : 8; last_chs : 24;
- first_lba : 32 : unsigned, littleendian;
- part_size : 32 : unsigned, littleendian ->
- make_mbr_entry Nonbootable dev (i+1) part_type first_lba part_size
-
- | 0x80 : 8; first_chs : 24;
- part_type : 8; last_chs : 24;
- first_lba : 32 : unsigned, littleendian;
- part_size : 32 : unsigned, littleendian ->
- make_mbr_entry Bootable dev (i+1) part_type first_lba part_size
-
- | _ ->
+ | { 0l : 32; 0l : 32; 0l : 32; 0l : 32 } ->
+ { part_status = NullEntry; part_type = 0;
+ part_dev = null_device; part_content = `Unknown }
+
+ | { ((0|0x80) as bootable) : 8; first_chs : 24;
+ part_type : 8; last_chs : 24;
+ first_lba : 32 : unsigned, littleendian;
+ part_size : 32 : unsigned, littleendian } ->
+ let bootable = if bootable = 0 then Nonbootable else Bootable in
+ make_mbr_entry bootable dev (i+1) part_type first_lba part_size
+
+ | { _ } ->
{ part_status = Malformed; part_type = 0;
part_dev = null_device; part_content = `Unknown }