1 (* 'df' command for virtual domains.
2 (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 Support for EXT2/EXT3 filesystems.
25 (* Int64 operators for convenience. *)
28 let ( *^ ) = Int64.mul
31 let sector_size = Virt_df.sector_size
32 let read_int32_le = Virt_df.read_int32_le
34 let probe_ext2 target part_type fd start size =
35 LargeFile.lseek fd ((start+^2L) *^ sector_size) SEEK_SET;
36 let str = String.create 128 in
37 if read fd str 0 128 <> 128 then
38 failwith "error reading ext2/ext3 magic"
40 if str.[56] != '\x53' || str.[57] != '\xEF' then (
41 Virt_df.ProbeFailed "partition marked EXT2/3 but no valid filesystem"
43 (* Refer to <linux/ext2_fs.h> *)
44 let s_inodes_count = read_int32_le str 0 in
45 let s_blocks_count = read_int32_le str 4 in
46 let s_r_blocks_count = read_int32_le str 8 in
47 let s_free_blocks_count = read_int32_le str 12 in
48 let s_free_inodes_count = read_int32_le str 16 in
49 let s_first_data_block = read_int32_le str 20 in
50 let s_log_block_size = read_int32_le str 24 in
51 (*let s_log_frag_size = read_int32_le str 28 in*)
52 let s_blocks_per_group = read_int32_le str 32 in
54 (* Work out the block size in bytes. *)
55 let s_log_block_size = Int64.to_int s_log_block_size in
56 let block_size = 1024L in
57 let block_size = Int64.shift_left block_size s_log_block_size in
59 (* Number of groups. *)
61 (s_blocks_count -^ s_first_data_block -^ 1L)
62 /^ s_blocks_per_group +^ 1L in
65 (* Number of group descriptors per block. *)
66 let s_inodes_per_block = s_blocksize /
67 let s_desc_per_block = block_size / s_inodes_per_block in
69 (s_groups_count +^ s_desc_per_block -^ 1L)
73 (* Calculate the block overhead (used by superblocks, inodes, etc.)
74 * See fs/ext2/super.c.
76 let overhead = s_first_data_block in
77 let overhead = (* XXX *) overhead in
81 Virt_df.fs_name = "Linux ext2/3";
82 fs_block_size = block_size;
83 fs_blocks_total = s_blocks_count -^ overhead;
84 fs_blocks_reserved = s_r_blocks_count;
85 fs_blocks_avail = s_free_blocks_count;
86 fs_blocks_used = s_blocks_count -^ overhead -^ s_free_blocks_count;
87 fs_inodes_total = s_inodes_count;
88 fs_inodes_reserved = 0L; (* XXX? *)
89 fs_inodes_avail = s_free_inodes_count;
90 fs_inodes_used = s_inodes_count (*-^ 0L*) -^ s_free_inodes_count;
95 (* Register with main code. *)
98 [ 0x83 ] (* Partition type. *)