Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenSuper.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: Mke2fs 00003 * FILE: Super.c 00004 * PROGRAMMER: Matt Wu <mattwu@163.com> 00005 * HOMEPAGE: http://ext2.yeah.net 00006 */ 00007 00008 /* INCLUDES **************************************************************/ 00009 00010 #include "Mke2fs.h" 00011 #include <debug.h> 00012 00013 /* DEFINITIONS ***********************************************************/ 00014 00015 extern int inode_ratio; 00016 00017 00018 /* FUNCTIONS *************************************************************/ 00019 00020 void ext2_print_super(PEXT2_SUPER_BLOCK pExt2Sb) 00021 { 00022 int i; 00023 00024 DPRINT("\nExt2 Super Block Details ...\n\n"); 00025 DPRINT(" Inode Count: %lu\n", pExt2Sb->s_inodes_count); 00026 DPRINT(" Block Count: %lu\n", pExt2Sb->s_blocks_count); 00027 DPRINT(" Reserved Block Count: %lu\n", pExt2Sb->s_r_blocks_count); 00028 DPRINT(" Free Blocks: %lu\n", pExt2Sb->s_free_blocks_count); 00029 DPRINT(" Free Inodes: %lu\n", pExt2Sb->s_free_inodes_count); 00030 DPRINT(" First Data Block: %lu\n", pExt2Sb->s_first_data_block); 00031 DPRINT(" Log Block Size: %lu\n", pExt2Sb->s_log_block_size); 00032 DPRINT(" Log Frag Size: %ld\n", pExt2Sb->s_log_frag_size); 00033 DPRINT(" Blocks per Group: %lu\n", pExt2Sb->s_blocks_per_group); 00034 DPRINT(" Fragments per Group: %lu\n", pExt2Sb->s_frags_per_group); 00035 DPRINT(" Inodes per Group: %lu\n", pExt2Sb->s_inodes_per_group); 00036 // DPRINT(" Mount Time: %s", ctime((time_t *) & (pExt2Sb->s_mtime))); 00037 // DPRINT(" Write Time: %s", ctime((time_t *) & (pExt2Sb->s_wtime))); 00038 DPRINT(" Mount Count: %u\n", pExt2Sb->s_mnt_count); 00039 DPRINT(" Max Mount Count: %d\n", pExt2Sb->s_max_mnt_count); 00040 DPRINT(" Magic Number: %X (%s)\n", pExt2Sb->s_magic, 00041 pExt2Sb->s_magic == EXT2_SUPER_MAGIC ? "OK" : "BAD"); 00042 DPRINT(" File System State: %X\n", pExt2Sb->s_state); 00043 DPRINT(" Error Behaviour: %X\n", pExt2Sb->s_errors); 00044 DPRINT(" Minor rev: %u\n", pExt2Sb->s_minor_rev_level); 00045 // DPRINT(" Last Check: %s", ctime((time_t *) & (pExt2Sb->s_lastcheck))); 00046 DPRINT(" Check Interval: %lu\n", pExt2Sb->s_checkinterval); 00047 DPRINT(" Creator OS: %lu\n", pExt2Sb->s_creator_os); 00048 DPRINT(" Revision Level: %lu\n", pExt2Sb->s_rev_level); 00049 DPRINT(" Reserved Block Default UID: %u\n", pExt2Sb->s_def_resuid); 00050 DPRINT(" Reserved Block Default GID: %u\n", pExt2Sb->s_def_resgid); 00051 DPRINT(" uuid = "); 00052 for (i=0; i < 16; i++) 00053 DbgPrint("%x ", pExt2Sb->s_uuid[i]); 00054 DbgPrint("\n"); 00055 00056 DPRINT(" volume label name: "); 00057 for (i=0; i < 16; i++) 00058 { 00059 if (pExt2Sb->s_volume_name[i] == 0) 00060 break; 00061 DbgPrint("%c", pExt2Sb->s_volume_name[i]); 00062 } 00063 DbgPrint("\n"); 00064 00065 DPRINT("\n\n"); 00066 } 00067 00068 #define set_field(field, default) if (!pExt2Sb->field) pExt2Sb->field = (default); 00069 00070 /* 00071 * Initialize super block ... 00072 */ 00073 00074 bool ext2_initialize_sb(PEXT2_FILESYS Ext2Sys) 00075 { 00076 int frags_per_block = 0; 00077 ULONG overhead = 0; 00078 int rem = 0; 00079 ULONG i = 0; 00080 ULONG group_block = 0; 00081 ULONG numblocks = 0; 00082 PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb; 00083 LARGE_INTEGER SysTime; 00084 00085 NtQuerySystemTime(&SysTime); 00086 00087 Ext2Sys->blocksize = EXT2_BLOCK_SIZE(pExt2Sb); 00088 Ext2Sys->fragsize = EXT2_FRAG_SIZE(pExt2Sb); 00089 frags_per_block = Ext2Sys->blocksize / Ext2Sys->fragsize; 00090 00091 pExt2Sb->s_magic = EXT2_SUPER_MAGIC; 00092 pExt2Sb->s_state = EXT2_VALID_FS; 00093 00094 pExt2Sb->s_first_data_block = (pExt2Sb->s_log_block_size) ? 0 : 1; 00095 pExt2Sb->s_max_mnt_count = EXT2_DFL_MAX_MNT_COUNT; 00096 00097 pExt2Sb->s_errors = EXT2_ERRORS_DEFAULT; 00098 00099 pExt2Sb->s_checkinterval = EXT2_DFL_CHECKINTERVAL; 00100 00101 if (!pExt2Sb->s_rev_level) 00102 pExt2Sb->s_rev_level = EXT2_GOOD_OLD_REV; 00103 00104 if (pExt2Sb->s_rev_level >= EXT2_DYNAMIC_REV) 00105 { 00106 set_field(s_first_ino, EXT2_GOOD_OLD_FIRST_INO); 00107 set_field(s_inode_size, EXT2_GOOD_OLD_INODE_SIZE); 00108 } 00109 00110 RtlTimeToSecondsSince1970(&SysTime, &pExt2Sb->s_wtime); 00111 pExt2Sb->s_lastcheck = pExt2Sb->s_mtime = pExt2Sb->s_wtime; 00112 00113 if (!pExt2Sb->s_blocks_per_group) 00114 pExt2Sb->s_blocks_per_group = Ext2Sys->blocksize * 8; 00115 00116 pExt2Sb->s_frags_per_group = pExt2Sb->s_blocks_per_group * frags_per_block; 00117 pExt2Sb->s_creator_os = EXT2_OS_WINNT; 00118 00119 if (pExt2Sb->s_r_blocks_count >= pExt2Sb->s_blocks_count) 00120 { 00121 goto cleanup; 00122 } 00123 00124 /* 00125 * If we're creating an external journal device, we don't need 00126 * to bother with the rest. 00127 */ 00128 if (pExt2Sb->s_feature_incompat & 00129 EXT3_FEATURE_INCOMPAT_JOURNAL_DEV) 00130 { 00131 Ext2Sys->group_desc_count = 0; 00132 // ext2fs_mark_super_dirty(fs); 00133 return true; 00134 } 00135 00136 retry: 00137 00138 Ext2Sys->group_desc_count = (pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block 00139 + EXT2_BLOCKS_PER_GROUP(pExt2Sb) - 1) / EXT2_BLOCKS_PER_GROUP(pExt2Sb); 00140 00141 if (Ext2Sys->group_desc_count == 0) 00142 return false; 00143 00144 Ext2Sys->desc_blocks = (Ext2Sys->group_desc_count + EXT2_DESC_PER_BLOCK(pExt2Sb) 00145 - 1) / EXT2_DESC_PER_BLOCK(pExt2Sb); 00146 00147 if (!pExt2Sb->s_inodes_count) 00148 pExt2Sb->s_inodes_count = pExt2Sb->s_blocks_count / ( inode_ratio /Ext2Sys->blocksize); 00149 00150 /* 00151 * Make sure we have at least EXT2_FIRST_INO + 1 inodes, so 00152 * that we have enough inodes for the filesystem(!) 00153 */ 00154 if (pExt2Sb->s_inodes_count < EXT2_FIRST_INODE(pExt2Sb)+1) 00155 pExt2Sb->s_inodes_count = EXT2_FIRST_INODE(pExt2Sb)+1; 00156 00157 /* 00158 * There should be at least as many inodes as the user 00159 * requested. Figure out how many inodes per group that 00160 * should be. But make sure that we don't allocate more than 00161 * one bitmap's worth of inodes 00162 */ 00163 pExt2Sb->s_inodes_per_group = (pExt2Sb->s_inodes_count + Ext2Sys->group_desc_count - 1) 00164 /Ext2Sys->group_desc_count; 00165 00166 if (pExt2Sb->s_inodes_per_group > (ULONG)(Ext2Sys->blocksize*8)) 00167 pExt2Sb->s_inodes_per_group = Ext2Sys->blocksize*8; 00168 00169 /* 00170 * Make sure the number of inodes per group completely fills 00171 * the inode table blocks in the descriptor. If not, add some 00172 * additional inodes/group. Waste not, want not... 00173 */ 00174 Ext2Sys->inode_blocks_per_group = (((pExt2Sb->s_inodes_per_group * EXT2_INODE_SIZE(pExt2Sb)) 00175 + EXT2_BLOCK_SIZE(pExt2Sb) - 1) / EXT2_BLOCK_SIZE(pExt2Sb)); 00176 00177 pExt2Sb->s_inodes_per_group = ((Ext2Sys->inode_blocks_per_group * EXT2_BLOCK_SIZE(pExt2Sb)) 00178 / EXT2_INODE_SIZE(pExt2Sb)); 00179 00180 /* 00181 * Finally, make sure the number of inodes per group is a 00182 * multiple of 8. This is needed to simplify the bitmap 00183 * splicing code. 00184 */ 00185 pExt2Sb->s_inodes_per_group &= ~7; 00186 Ext2Sys->inode_blocks_per_group = (((pExt2Sb->s_inodes_per_group * EXT2_INODE_SIZE(pExt2Sb)) 00187 + EXT2_BLOCK_SIZE(pExt2Sb) - 1) / EXT2_BLOCK_SIZE(pExt2Sb)); 00188 00189 /* 00190 * adjust inode count to reflect the adjusted inodes_per_group 00191 */ 00192 pExt2Sb->s_inodes_count = pExt2Sb->s_inodes_per_group * Ext2Sys->group_desc_count; 00193 pExt2Sb->s_free_inodes_count = pExt2Sb->s_inodes_count; 00194 00195 /* 00196 * Overhead is the number of bookkeeping blocks per group. It 00197 * includes the superblock backup, the group descriptor 00198 * backups, the inode bitmap, the block bitmap, and the inode 00199 * table. 00200 * 00201 * XXX Not all block groups need the descriptor blocks, but 00202 * being clever is tricky... 00203 */ 00204 overhead = (int) (3 + Ext2Sys->desc_blocks + Ext2Sys->inode_blocks_per_group); 00205 00206 /* 00207 * See if the last group is big enough to support the 00208 * necessary data structures. If not, we need to get rid of 00209 * it. 00210 */ 00211 rem = (int) ((pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block) % 00212 pExt2Sb->s_blocks_per_group); 00213 00214 if ((Ext2Sys->group_desc_count == 1) && rem && (rem < overhead)) 00215 return false; 00216 00217 if (rem && (rem < overhead+50)) 00218 { 00219 pExt2Sb->s_blocks_count -= rem; 00220 goto retry; 00221 } 00222 00223 /* 00224 * At this point we know how big the filesystem will be. So we can do 00225 * any and all allocations that depend on the block count. 00226 */ 00227 00228 // Allocate block bitmap 00229 if(!ext2_allocate_block_bitmap(Ext2Sys)) 00230 { 00231 goto cleanup; 00232 } 00233 00234 // Allocate inode bitmap 00235 if(!ext2_allocate_inode_bitmap(Ext2Sys)) 00236 { 00237 goto cleanup; 00238 } 00239 00240 // Allocate gourp desc 00241 if(!ext2_allocate_group_desc(Ext2Sys)) 00242 { 00243 goto cleanup; 00244 } 00245 00246 /* 00247 * Reserve the superblock and group descriptors for each 00248 * group, and fill in the correct group statistics for group. 00249 * Note that although the block bitmap, inode bitmap, and 00250 * inode table have not been allocated (and in fact won't be 00251 * by this routine), they are accounted for nevertheless. 00252 */ 00253 group_block = pExt2Sb->s_first_data_block; 00254 numblocks = 0; 00255 00256 pExt2Sb->s_free_blocks_count = 0; 00257 00258 for (i = 0; i < Ext2Sys->group_desc_count; i++) 00259 { 00260 if (i == Ext2Sys->group_desc_count-1) 00261 { 00262 numblocks = (pExt2Sb->s_blocks_count - pExt2Sb->s_first_data_block) 00263 % pExt2Sb->s_blocks_per_group; 00264 00265 if (!numblocks) 00266 numblocks = pExt2Sb->s_blocks_per_group; 00267 } 00268 else 00269 { 00270 numblocks = pExt2Sb->s_blocks_per_group; 00271 } 00272 00273 if (ext2_bg_has_super(pExt2Sb, i)) 00274 { 00275 ULONG j; 00276 00277 for (j=0; j < Ext2Sys->desc_blocks+1; j++) 00278 ext2_mark_bitmap(Ext2Sys->block_map, group_block + j); 00279 00280 numblocks -= 1 + Ext2Sys->desc_blocks; 00281 } 00282 00283 numblocks -= 2 + Ext2Sys->inode_blocks_per_group; 00284 00285 pExt2Sb->s_free_blocks_count += numblocks; 00286 Ext2Sys->group_desc[i].bg_free_blocks_count = (__u16)numblocks; 00287 Ext2Sys->group_desc[i].bg_free_inodes_count = (__u16)pExt2Sb->s_inodes_per_group; 00288 Ext2Sys->group_desc[i].bg_used_dirs_count = 0; 00289 00290 group_block += pExt2Sb->s_blocks_per_group; 00291 } 00292 00293 return true; 00294 00295 cleanup: 00296 00297 ext2_free_group_desc(Ext2Sys); 00298 ext2_free_block_bitmap(Ext2Sys); 00299 ext2_free_inode_bitmap(Ext2Sys); 00300 00301 return false; 00302 } Generated on Wed May 23 2012 04:34:03 for ReactOS by
1.7.6.1
|