ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

Super.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.