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.
27 let plugin_id = "ext2"
28 let superblock_offset = 1024L
31 (* Load the superblock. *)
32 let bits = dev#read_bitstring superblock_offset 1024 in
34 (* The structure is straight from /usr/include/linux/ext3_fs.h *)
36 | { s_inodes_count : 32 : littleendian; (* Inodes count *)
37 s_blocks_count : 32 : littleendian; (* Blocks count *)
38 s_r_blocks_count : 32 : littleendian; (* Reserved blocks count *)
39 s_free_blocks_count : 32 : littleendian; (* Free blocks count *)
40 s_free_inodes_count : 32 : littleendian; (* Free inodes count *)
41 s_first_data_block : 32 : littleendian; (* First Data Block *)
42 s_log_block_size : 32 : littleendian; (* Block size *)
43 s_log_frag_size : 32 : littleendian; (* Fragment size *)
44 s_blocks_per_group : 32 : littleendian; (* # Blocks per group *)
45 s_frags_per_group : 32 : littleendian; (* # Fragments per group *)
46 s_inodes_per_group : 32 : littleendian; (* # Inodes per group *)
47 s_mtime : 32 : littleendian; (* Mount time *)
48 s_wtime : 32 : littleendian; (* Write time *)
49 s_mnt_count : 16 : littleendian; (* Mount count *)
50 s_max_mnt_count : 16 : littleendian; (* Maximal mount count *)
51 0xef53 : 16 : littleendian; (* Magic signature *)
52 s_state : 16 : littleendian; (* File system state *)
53 s_errors : 16 : littleendian; (* Behaviour when detecting errors *)
54 s_minor_rev_level : 16 : littleendian; (* minor revision level *)
55 s_lastcheck : 32 : littleendian; (* time of last check *)
56 s_checkinterval : 32 : littleendian; (* max. time between checks *)
57 s_creator_os : 32 : littleendian; (* OS *)
58 s_rev_level : 32 : littleendian; (* Revision level *)
59 s_def_resuid : 16 : littleendian; (* Default uid for reserved blocks *)
60 s_def_resgid : 16 : littleendian; (* Default gid for reserved blocks *)
61 s_first_ino : 32 : littleendian; (* First non-reserved inode *)
62 s_inode_size : 16 : littleendian; (* size of inode structure *)
63 s_block_group_nr : 16 : littleendian; (* block group # of this superblock *)
64 s_feature_compat : 32 : littleendian; (* compatible feature set *)
65 s_feature_incompat : 32 : littleendian; (* incompatible feature set *)
66 s_feature_ro_compat : 32 : littleendian; (* readonly-compatible feature set *)
67 s_uuid : 128 : string; (* 128-bit uuid for volume *)
68 s_volume_name : 128 : string; (* volume name *)
69 s_last_mounted : 512 : string; (* directory where last mounted *)
70 s_algorithm_usage_bitmap : 32 : littleendian; (* For compression *)
71 s_prealloc_blocks : 8; (* Nr of blocks to try to preallocate*)
72 s_prealloc_dir_blocks : 8; (* Nr to preallocate for dirs *)
73 s_reserved_gdt_blocks : 16 : littleendian;(* Per group desc for online growth *)
74 s_journal_uuid : 128 : string; (* uuid of journal superblock *)
75 s_journal_inum : 32 : littleendian; (* inode number of journal file *)
76 s_journal_dev : 32 : littleendian; (* device number of journal file *)
77 s_last_orphan : 32 : littleendian; (* start of list of inodes to delete *)
78 s_hash_seed0 : 32 : littleendian; (* HTREE hash seed *)
79 s_hash_seed1 : 32 : littleendian;
80 s_hash_seed2 : 32 : littleendian;
81 s_hash_seed3 : 32 : littleendian;
82 s_def_hash_version : 8; (* Default hash version to use *)
83 s_reserved_char_pad : 8;
84 s_reserved_word_pad : 16 : littleendian;
85 s_default_mount_opts : 32 : littleendian;
86 s_first_meta_bg : 32 : littleendian; (* First metablock block group *)
87 _ : 6080 : bitstring } -> (* Padding to the end of the block *)
89 (* Work out the block size in bytes. *)
90 let s_log_block_size = Int32.to_int s_log_block_size in
91 let block_size = 1024L in
92 let block_size = Int64.shift_left block_size s_log_block_size in
94 (* Number of groups. *)
97 (s_blocks_count -* s_first_data_block -* 1l)
98 /* s_blocks_per_group +* 1l
102 (* Number of group descriptors per block. *)
103 let s_inodes_per_block = s_blocksize /
104 let s_desc_per_block = block_size / s_inodes_per_block in
106 (s_groups_count +^ s_desc_per_block -^ 1L)
110 (* Calculate the block overhead (used by superblocks, inodes, etc.)
111 * See fs/ext2/super.c.
113 let overhead = Int64.of_int32 s_first_data_block in
114 let overhead = (* XXX *) overhead in
116 (* The blocksize of the filesystem is likely to be quite different
117 * from that of the underlying device, so create an overlay device
118 * with the natural filesystem blocksize.
120 let fs_dev = new blocksize_overlay (Int64.to_int block_size) dev in
123 fs_plugin_id = plugin_id;
126 fs_blocksize = Int64.to_int block_size;
127 fs_blocks_total = Int64.of_int32 s_blocks_count -^ overhead;
131 fs_blocks_reserved = Int64.of_int32 s_r_blocks_count;
132 fs_blocks_avail = Int64.of_int32 s_free_blocks_count;
134 Int64.of_int32 s_blocks_count -^ overhead
135 -^ Int64.of_int32 s_free_blocks_count;
136 fs_inodes_total = Int64.of_int32 s_inodes_count;
137 fs_inodes_reserved = 0L; (* XXX? *)
138 fs_inodes_avail = Int64.of_int32 s_free_inodes_count;
139 fs_inodes_used = Int64.of_int32 s_inodes_count
141 -^ Int64.of_int32 s_free_inodes_count;
145 raise Not_found (* Not an EXT2/3 superblock. *)