ReactOS  0.4.14-dev-317-g96040ec
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 
15 extern 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  {
106  set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO);
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 
136 retry:
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 
295 cleanup:
296 
297  ext2_free_group_desc(Ext2Sys);
298  ext2_free_block_bitmap(Ext2Sys);
299  ext2_free_inode_bitmap(Ext2Sys);
300 
301  return false;
302 }
int blocksize
Definition: Mke2fs.h:154
#define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV
Definition: ext3_fs.h:681
#define DbgPrint
Definition: loader.c:25
#define EXT2_OS_WINNT
Definition: ext2_fs.h:447
BOOLEAN NTAPI RtlTimeToSecondsSince1970(PLARGE_INTEGER Time, PULONG ElapsedSeconds)
ULONG group_desc_count
Definition: Mke2fs.h:156
bool ext2_allocate_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:43
bool ext2_allocate_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:100
#define EXT2_GOOD_OLD_REV
Definition: ext2_fs.h:426
void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:194
#define EXT2_DFL_MAX_MNT_COUNT
Definition: ext2_fs.h:332
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
PEXT2_GROUP_DESC group_desc
Definition: Mke2fs.h:158
#define EXT2_SUPER_MAGIC
Definition: ext2fs.h:344
void ext2_print_super(PEXT2_SUPER_BLOCK pExt2Sb)
Definition: Super.c:20
#define EXT2_VALID_FS
Definition: ext2_fs.h:310
void DPRINT(...)
Definition: polytest.cpp:61
bool ext2_allocate_inode_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:140
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
bool ext2_initialize_sb(PEXT2_FILESYS Ext2Sys)
Definition: Super.c:74
#define EXT2_INODE_SIZE(sb)
Definition: ext2.h:192
unsigned short __u16
Definition: compat.h:89
void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys)
Definition: Bitmap.c:205
#define EXT2_DYNAMIC_REV
Definition: ext2_fs.h:427
if(!(yy_init))
Definition: macro.lex.yy.c:714
unsigned long desc_blocks
Definition: Mke2fs.h:157
#define EXT2_DESC_PER_BLOCK(s)
Definition: ext2.h:196
bool ext2_bg_has_super(PEXT2_SUPER_BLOCK pExt2Sb, int group_block)
Definition: Group.c:30
#define EXT2_ERRORS_DEFAULT
Definition: ext2_fs.h:341
unsigned long inode_blocks_per_group
Definition: Mke2fs.h:160
#define EXT2_FIRST_INODE(s)
Definition: Mke2fs.h:116
void ext2_free_group_desc(PEXT2_FILESYS Ext2Sys)
Definition: Group.c:61
bool ext2_mark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno)
Definition: Bitmap.c:52
#define EXT2_BLOCK_SIZE(sb)
Definition: ext2.h:186
#define set_field(field, default)
Definition: Super.c:68
#define EXT2_GOOD_OLD_INODE_SIZE
Definition: ext2.h:54
#define EXT2_GOOD_OLD_FIRST_INO
Definition: ext2_fs.h:66
unsigned int ULONG
Definition: retypes.h:1
NTSTATUS NTAPI NtQuerySystemTime(OUT PLARGE_INTEGER SystemTime)
Definition: time.c:417
char * cleanup(char *str)
Definition: wpickclick.c:99
#define EXT2_FRAG_SIZE(s)
Definition: ext2_fs.h:119
#define EXT2_DFL_CHECKINTERVAL
Definition: ext2_fs.h:333
int inode_ratio
Definition: Mke2fs.c:17
#define EXT2_BLOCKS_PER_GROUP(s)
Definition: ext2_fs.h:169
PEXT2_SUPER_BLOCK ext2_sb
Definition: Mke2fs.h:159
PEXT2_BLOCK_BITMAP block_map
Definition: Mke2fs.h:162
int fragsize
Definition: Mke2fs.h:155