ReactOS 0.4.15-dev-7918-g2a2556c
Super.c
Go to the documentation of this file.
1/*
2 * PROJECT: Mke2fs
3 * FILE: Super.c
4 * PROGRAMMER: Matt Wu <mattwu@163.com>
5 * HOMEPAGE: http://ext2.yeah.net
6 */
7
8/* INCLUDES **************************************************************/
9
10#include "Mke2fs.h"
11#include <debug.h>
12
13/* DEFINITIONS ***********************************************************/
14
15extern int inode_ratio;
16
17
18/* FUNCTIONS *************************************************************/
19
21{
22 int i;
23
24 DPRINT("\nExt2 Super Block Details ...\n\n");
25 DPRINT(" Inode Count: %lu\n", pExt2Sb->s_inodes_count);
26 DPRINT(" Block Count: %lu\n", pExt2Sb->s_blocks_count);
27 DPRINT(" Reserved Block Count: %lu\n", pExt2Sb->s_r_blocks_count);
28 DPRINT(" Free Blocks: %lu\n", pExt2Sb->s_free_blocks_count);
29 DPRINT(" Free Inodes: %lu\n", pExt2Sb->s_free_inodes_count);
30 DPRINT(" First Data Block: %lu\n", pExt2Sb->s_first_data_block);
31 DPRINT(" Log Block Size: %lu\n", pExt2Sb->s_log_block_size);
32 DPRINT(" Log Frag Size: %ld\n", pExt2Sb->s_log_frag_size);
33 DPRINT(" Blocks per Group: %lu\n", pExt2Sb->s_blocks_per_group);
34 DPRINT(" Fragments per Group: %lu\n", pExt2Sb->s_frags_per_group);
35 DPRINT(" Inodes per Group: %lu\n", pExt2Sb->s_inodes_per_group);
36// DPRINT(" Mount Time: %s", ctime((time_t *) & (pExt2Sb->s_mtime)));
37// DPRINT(" Write Time: %s", ctime((time_t *) & (pExt2Sb->s_wtime)));
38 DPRINT(" Mount Count: %u\n", pExt2Sb->s_mnt_count);
39 DPRINT(" Max Mount Count: %d\n", pExt2Sb->s_max_mnt_count);
40 DPRINT(" Magic Number: %X (%s)\n", pExt2Sb->s_magic,
41 pExt2Sb->s_magic == EXT2_SUPER_MAGIC ? "OK" : "BAD");
42 DPRINT(" File System State: %X\n", pExt2Sb->s_state);
43 DPRINT(" Error Behaviour: %X\n", pExt2Sb->s_errors);
44 DPRINT(" Minor rev: %u\n", pExt2Sb->s_minor_rev_level);
45// DPRINT(" Last Check: %s", ctime((time_t *) & (pExt2Sb->s_lastcheck)));
46 DPRINT(" Check Interval: %lu\n", pExt2Sb->s_checkinterval);
47 DPRINT(" Creator OS: %lu\n", pExt2Sb->s_creator_os);
48 DPRINT(" Revision Level: %lu\n", pExt2Sb->s_rev_level);
49 DPRINT(" Reserved Block Default UID: %u\n", pExt2Sb->s_def_resuid);
50 DPRINT(" Reserved Block Default GID: %u\n", pExt2Sb->s_def_resgid);
51 DPRINT(" uuid = ");
52 for (i=0; i < 16; i++)
53 DbgPrint("%x ", pExt2Sb->s_uuid[i]);
54 DbgPrint("\n");
55
56 DPRINT(" volume label name: ");
57 for (i=0; i < 16; i++)
58 {
59 if (pExt2Sb->s_volume_name[i] == 0)
60 break;
61 DbgPrint("%c", pExt2Sb->s_volume_name[i]);
62 }
63 DbgPrint("\n");
64
65 DPRINT("\n\n");
66}
67
68#define set_field(field, default) if (!pExt2Sb->field) pExt2Sb->field = (default);
69
70/*
71 * Initialize super block ...
72 */
73
75{
76 int frags_per_block = 0;
77 ULONG overhead = 0;
78 ULONG rem = 0;
79 ULONG i = 0;
80 ULONG group_block = 0;
81 ULONG numblocks = 0;
82 PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
83 LARGE_INTEGER SysTime;
84
85 NtQuerySystemTime(&SysTime);
86
87 Ext2Sys->blocksize = EXT2_BLOCK_SIZE(pExt2Sb);
88 Ext2Sys->fragsize = EXT2_FRAG_SIZE(pExt2Sb);
89 frags_per_block = Ext2Sys->blocksize / Ext2Sys->fragsize;
90
91 pExt2Sb->s_magic = EXT2_SUPER_MAGIC;
92 pExt2Sb->s_state = EXT2_VALID_FS;
93
94 pExt2Sb->s_first_data_block = (pExt2Sb->s_log_block_size) ? 0 : 1;
95 pExt2Sb->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT;
96
97 pExt2Sb->s_errors = EXT2_ERRORS_DEFAULT;
98
99 pExt2Sb->s_checkinterval = EXT2_DFL_CHECKINTERVAL;
100
101 if (!pExt2Sb->s_rev_level)
102 pExt2Sb->s_rev_level = EXT2_GOOD_OLD_REV;
103
104 if (pExt2Sb->s_rev_level >= EXT2_DYNAMIC_REV)
105 {
107 set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE);
108 }
109
110 RtlTimeToSecondsSince1970(&SysTime, &pExt2Sb->s_wtime);
111 pExt2Sb->s_lastcheck = pExt2Sb->s_mtime = pExt2Sb->s_wtime;
112
113 if (!pExt2Sb->s_blocks_per_group)
114 pExt2Sb->s_blocks_per_group = Ext2Sys->blocksize * 8;
115
116 pExt2Sb->s_frags_per_group = pExt2Sb->s_blocks_per_group * frags_per_block;
117 pExt2Sb->s_creator_os = EXT2_OS_WINNT;
118
119 if (pExt2Sb->s_r_blocks_count >= pExt2Sb->s_blocks_count)
120 {
121 goto cleanup;
122 }
123
124 /*
125 * If we're creating an external journal device, we don't need
126 * to bother with the rest.
127 */
128 if (pExt2Sb->s_feature_incompat &
130 {
131 Ext2Sys->group_desc_count = 0;
132 // ext2fs_mark_super_dirty(fs);
133 return true;
134 }
135
136retry:
137
138 Ext2Sys->group_desc_count = (pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block
139 + EXT2_BLOCKS_PER_GROUP(pExt2Sb) - 1) / EXT2_BLOCKS_PER_GROUP(pExt2Sb);
140
141 if (Ext2Sys->group_desc_count == 0)
142 return false;
143
144 Ext2Sys->desc_blocks = (Ext2Sys->group_desc_count + EXT2_DESC_PER_BLOCK(pExt2Sb)
145 - 1) / EXT2_DESC_PER_BLOCK(pExt2Sb);
146
147 if (!pExt2Sb->s_inodes_count)
148 pExt2Sb->s_inodes_count = pExt2Sb->s_blocks_count / ( inode_ratio /Ext2Sys->blocksize);
149
150 /*
151 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so
152 * that we have enough inodes for the filesystem(!)
153 */
154 if (pExt2Sb->s_inodes_count < EXT2_FIRST_INODE(pExt2Sb)+1)
155 pExt2Sb->s_inodes_count = EXT2_FIRST_INODE(pExt2Sb)+1;
156
157 /*
158 * There should be at least as many inodes as the user
159 * requested. Figure out how many inodes per group that
160 * should be. But make sure that we don't allocate more than
161 * one bitmap's worth of inodes
162 */
163 pExt2Sb->s_inodes_per_group = (pExt2Sb->s_inodes_count + Ext2Sys->group_desc_count - 1)
164 /Ext2Sys->group_desc_count;
165
166 if (pExt2Sb->s_inodes_per_group > (ULONG)(Ext2Sys->blocksize*8))
167 pExt2Sb->s_inodes_per_group = Ext2Sys->blocksize*8;
168
169 /*
170 * Make sure the number of inodes per group completely fills
171 * the inode table blocks in the descriptor. If not, add some
172 * additional inodes/group. Waste not, want not...
173 */
174 Ext2Sys->inode_blocks_per_group = (((pExt2Sb->s_inodes_per_group * EXT2_INODE_SIZE(pExt2Sb))
175 + EXT2_BLOCK_SIZE(pExt2Sb) - 1) / EXT2_BLOCK_SIZE(pExt2Sb));
176
177 pExt2Sb->s_inodes_per_group = ((Ext2Sys->inode_blocks_per_group * EXT2_BLOCK_SIZE(pExt2Sb))
178 / EXT2_INODE_SIZE(pExt2Sb));
179
180 /*
181 * Finally, make sure the number of inodes per group is a
182 * multiple of 8. This is needed to simplify the bitmap
183 * splicing code.
184 */
185 pExt2Sb->s_inodes_per_group &= ~7;
186 Ext2Sys->inode_blocks_per_group = (((pExt2Sb->s_inodes_per_group * EXT2_INODE_SIZE(pExt2Sb))
187 + EXT2_BLOCK_SIZE(pExt2Sb) - 1) / EXT2_BLOCK_SIZE(pExt2Sb));
188
189 /*
190 * adjust inode count to reflect the adjusted inodes_per_group
191 */
192 pExt2Sb->s_inodes_count = pExt2Sb->s_inodes_per_group * Ext2Sys->group_desc_count;
193 pExt2Sb->s_free_inodes_count = pExt2Sb->s_inodes_count;
194
195 /*
196 * Overhead is the number of bookkeeping blocks per group. It
197 * includes the superblock backup, the group descriptor
198 * backups, the inode bitmap, the block bitmap, and the inode
199 * table.
200 *
201 * XXX Not all block groups need the descriptor blocks, but
202 * being clever is tricky...
203 */
204 overhead = (3 + Ext2Sys->desc_blocks + Ext2Sys->inode_blocks_per_group);
205
206 /*
207 * See if the last group is big enough to support the
208 * necessary data structures. If not, we need to get rid of
209 * it.
210 */
211 rem = ((pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block) %
212 pExt2Sb->s_blocks_per_group);
213
214 if ((Ext2Sys->group_desc_count == 1) && rem && (rem < overhead))
215 return false;
216
217 if (rem && (rem < overhead+50))
218 {
219 pExt2Sb->s_blocks_count -= rem;
220 goto retry;
221 }
222
223 /*
224 * At this point we know how big the filesystem will be. So we can do
225 * any and all allocations that depend on the block count.
226 */
227
228 // Allocate block bitmap
229 if(!ext2_allocate_block_bitmap(Ext2Sys))
230 {
231 goto cleanup;
232 }
233
234 // Allocate inode bitmap
235 if(!ext2_allocate_inode_bitmap(Ext2Sys))
236 {
237 goto cleanup;
238 }
239
240 // Allocate gourp desc
241 if(!ext2_allocate_group_desc(Ext2Sys))
242 {
243 goto cleanup;
244 }
245
246 /*
247 * Reserve the superblock and group descriptors for each
248 * group, and fill in the correct group statistics for group.
249 * Note that although the block bitmap, inode bitmap, and
250 * inode table have not been allocated (and in fact won't be
251 * by this routine), they are accounted for nevertheless.
252 */
253 group_block = pExt2Sb->s_first_data_block;
254 numblocks = 0;
255
256 pExt2Sb->s_free_blocks_count = 0;
257
258 for (i = 0; i < Ext2Sys->group_desc_count; i++)
259 {
260 if (i == Ext2Sys->group_desc_count-1)
261 {
262 numblocks = (pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block)
263 % pExt2Sb->s_blocks_per_group;
264
265 if (!numblocks)
266 numblocks = pExt2Sb->s_blocks_per_group;
267 }
268 else
269 {
270 numblocks = pExt2Sb->s_blocks_per_group;
271 }
272
273 if (ext2_bg_has_super(pExt2Sb, i))
274 {
275 ULONG j;
276
277 for (j=0; j < Ext2Sys->desc_blocks+1; j++)
278 ext2_mark_bitmap(Ext2Sys->block_map, group_block + j);
279
280 numblocks -= 1 + Ext2Sys->desc_blocks;
281 }
282
283 numblocks -= 2 + Ext2Sys->inode_blocks_per_group;
284
285 pExt2Sb->s_free_blocks_count += numblocks;
286 Ext2Sys->group_desc[i].bg_free_blocks_count = (__u16)numblocks;
287 Ext2Sys->group_desc[i].bg_free_inodes_count = (__u16)pExt2Sb->s_inodes_per_group;
288 Ext2Sys->group_desc[i].bg_used_dirs_count = 0;
289
290 group_block += pExt2Sb->s_blocks_per_group;
291 }
292
293 return true;
294
295cleanup:
296
297 ext2_free_group_desc(Ext2Sys);
298 ext2_free_block_bitmap(Ext2Sys);
299 ext2_free_inode_bitmap(Ext2Sys);
300
301 return false;
302}
void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:194
bool ext2_allocate_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:100
bool ext2_mark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno)
Definition: Bitmap.c:52
bool ext2_allocate_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:140
void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:205
void ext2_free_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:61
bool ext2_bg_has_super(PEXT2_SUPER_BLOCK pExt2Sb, int group_block)
Definition: Group.c:30
bool ext2_allocate_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:43
#define EXT2_FIRST_INODE(s)
Definition: Mke2fs.h:116
void ext2_print_super(PEXT2_SUPER_BLOCK pExt2Sb)
Definition: Super.c:20
int inode_ratio
Definition: Mke2fs.c:17
#define set_field(field, default)
Definition: Super.c:68
bool ext2_initialize_sb(PEXT2_FILESYS Ext2Sys)
Definition: Super.c:74
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
#define EXT2_BLOCK_SIZE(sb)
Definition: ext2.h:186
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54
#define EXT2_DESC_PER_BLOCK(s)
Definition: ext2.h:196
static void cleanup(void)
Definition: main.c:1335
#define EXT2_VALID_FS
Definition: ext2_fs.h:310
#define EXT2_GOOD_OLD_FIRST_INO
Definition: ext2_fs.h:66
#define EXT2_FRAG_SIZE(s)
Definition: ext2_fs.h:119
#define EXT2_BLOCKS_PER_GROUP(s)
Definition: ext2_fs.h:169
#define EXT2_ERRORS_DEFAULT
Definition: ext2_fs.h:341
#define EXT2_DFL_CHECKINTERVAL
Definition: ext2_fs.h:333
#define EXT2_DFL_MAX_MNT_COUNT
Definition: ext2_fs.h:332
#define EXT2_GOOD_OLD_REV
Definition: ext2_fs.h:426
#define EXT2_DYNAMIC_REV
Definition: ext2_fs.h:427
#define EXT2_SUPER_MAGIC
Definition: ext2fs.h:349
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
Definition: ext3_fs.h:681
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
#define DbgPrint
Definition: hal.h:12
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
if(dx< 0)
Definition: linetemp.h:194
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:483
#define __u16
Definition: types.h:13
#define EXT2_OS_WINNT
Definition: ext2_fs.h:447
#define DPRINT
Definition: sndvol32.h:71
PEXT2_SUPER_BLOCK ext2_sb
Definition: Mke2fs.h:159
unsigned long inode_blocks_per_group
Definition: Mke2fs.h:160
PEXT2_BLOCK_BITMAP block_map
Definition: Mke2fs.h:162
ULONG group_desc_count
Definition: Mke2fs.h:156
int blocksize
Definition: Mke2fs.h:154
unsigned long desc_blocks
Definition: Mke2fs.h:157
int fragsize
Definition: Mke2fs.h:155
PEXT2_GROUP_DESC group_desc
Definition: Mke2fs.h:158
__u16 bg_used_dirs_count
Definition: ext2_fs.h:155
__u16 bg_free_blocks_count
Definition: ext2_fs.h:153
__u16 bg_free_inodes_count
Definition: ext2_fs.h:154
uint32_t ULONG
Definition: typedefs.h:59