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

Memory.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:          Mke2fs
00003  * FILE:             Memory.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 char *device_name;
00016 
00017 /* FUNCTIONS *************************************************************/
00018 
00019 
00020 /*
00021  * Return the group # of an inode number
00022  */
00023 int ext2_group_of_ino(PEXT2_FILESYS fs, ULONG ino)
00024 {
00025     return (ino - 1) / fs->ext2_sb->s_inodes_per_group;
00026 }
00027 
00028 /*
00029  * Return the group # of a block
00030  */
00031 int ext2_group_of_blk(PEXT2_FILESYS fs, ULONG blk)
00032 {
00033     return (blk - fs->ext2_sb->s_first_data_block) /
00034         fs->ext2_sb->s_blocks_per_group;
00035 }
00036 
00037 void ext2_inode_alloc_stats2(PEXT2_FILESYS fs, ULONG ino,
00038                    int inuse, int isdir)
00039 {
00040     int group = ext2_group_of_ino(fs, ino);
00041 
00042     if (inuse > 0)
00043         ext2_mark_inode_bitmap(fs->inode_map, ino);
00044     else
00045         ext2_unmark_inode_bitmap(fs->inode_map, ino);
00046 
00047     fs->group_desc[group].bg_free_inodes_count -= inuse;
00048 
00049     if (isdir)
00050         fs->group_desc[group].bg_used_dirs_count += inuse;
00051 
00052     fs->ext2_sb->s_free_inodes_count -= inuse;
00053 }
00054 
00055 
00056 void ext2_inode_alloc_stats(PEXT2_FILESYS fs, ULONG ino, int inuse)
00057 {
00058     ext2_inode_alloc_stats2(fs, ino, inuse, 0);
00059 }
00060 
00061 void ext2_block_alloc_stats(PEXT2_FILESYS fs, ULONG blk, int inuse)
00062 {
00063     int group = ext2_group_of_blk(fs, blk);
00064 
00065     if (inuse > 0)
00066         ext2_mark_block_bitmap(fs->block_map, blk);
00067     else
00068         ext2_unmark_block_bitmap(fs->block_map, blk);
00069 
00070     fs->group_desc[group].bg_free_blocks_count -= inuse;
00071     fs->ext2_sb->s_free_blocks_count -= inuse;
00072 }
00073 
00074 
00075 bool ext2_allocate_tables(PEXT2_FILESYS Ext2Sys)
00076 {
00077     bool    retval;
00078     ULONG   i;
00079 
00080     for (i = 0; i < Ext2Sys->group_desc_count; i++)
00081     {
00082         retval = ext2_allocate_group_table(Ext2Sys, i, Ext2Sys->block_map);
00083 
00084         if (!retval)
00085             return retval;
00086     }
00087 
00088     return true;
00089 }
00090 
00091 
00092 bool ext2_allocate_group_table(PEXT2_FILESYS fs, ULONG group,
00093                       PEXT2_BLOCK_BITMAP bmap)
00094 {
00095     bool    retval;
00096     ULONG   group_blk, start_blk, last_blk, new_blk, blk, j;
00097 
00098     group_blk = fs->ext2_sb->s_first_data_block +
00099         (group * fs->ext2_sb->s_blocks_per_group);
00100     
00101     last_blk = group_blk + fs->ext2_sb->s_blocks_per_group;
00102     if (last_blk >= fs->ext2_sb->s_blocks_count)
00103         last_blk = fs->ext2_sb->s_blocks_count - 1;
00104 
00105     start_blk = group_blk + 3 + fs->desc_blocks;
00106     if (start_blk > last_blk)
00107         start_blk = group_blk;
00108 
00109     if (!bmap)
00110         bmap = fs->block_map;
00111     
00112     /*
00113      * Allocate the inode table
00114      */
00115     if (!fs->group_desc[group].bg_inode_table)
00116     {
00117         retval = ext2_get_free_blocks(fs, start_blk, last_blk,
00118                         fs->inode_blocks_per_group,
00119                         bmap, &new_blk);
00120         if (!retval)
00121             return retval;
00122 
00123         for (j=0, blk = new_blk;
00124              j < fs->inode_blocks_per_group;
00125              j++, blk++)
00126             ext2_mark_block_bitmap(bmap, blk);
00127 
00128         fs->group_desc[group].bg_inode_table = new_blk;
00129     }
00130 
00131     /*
00132      * Allocate the block and inode bitmaps, if necessary
00133      */
00134     if (fs->stride)
00135     {
00136         start_blk += fs->inode_blocks_per_group;
00137         start_blk += ((fs->stride * group) %
00138                   (last_blk - start_blk));
00139         if (start_blk > last_blk)
00140             /* should never happen */
00141             start_blk = group_blk;
00142     }
00143     else
00144     {
00145         start_blk = group_blk;
00146     }
00147 
00148     if (!fs->group_desc[group].bg_block_bitmap)
00149     {
00150         retval = ext2_get_free_blocks(fs, start_blk, last_blk,
00151                         1, bmap, &new_blk);
00152 
00153         if (!retval) 
00154             retval = ext2_get_free_blocks(fs, group_blk,
00155                     last_blk, 1, bmap, &new_blk);
00156 
00157         if (!retval)
00158             return retval;
00159 
00160         ext2_mark_block_bitmap(bmap, new_blk);
00161         fs->group_desc[group].bg_block_bitmap = new_blk;
00162     }
00163 
00164     if (!fs->group_desc[group].bg_inode_bitmap)
00165     {
00166         retval = ext2_get_free_blocks(fs, start_blk, last_blk,
00167                         1, bmap, &new_blk);
00168         if (!retval) 
00169             retval = ext2_get_free_blocks(fs, group_blk,
00170                     last_blk, 1, bmap, &new_blk);
00171         if (!retval)
00172             return retval;
00173 
00174         ext2_mark_block_bitmap(bmap, new_blk);
00175         fs->group_desc[group].bg_inode_bitmap = new_blk;
00176     }
00177 
00178     return true;
00179 }
00180 
00181 
00182 bool ext2_get_free_blocks(PEXT2_FILESYS fs, ULONG start, ULONG finish,
00183                  int num, PEXT2_BLOCK_BITMAP map, ULONG *ret)
00184 {
00185     ULONG   b = start;
00186 
00187     if (!map)
00188         map = fs->block_map;
00189 
00190     if (!map)
00191         return false;
00192 
00193     if (!b)
00194         b = fs->ext2_sb->s_first_data_block;
00195 
00196     if (!finish)
00197         finish = start;
00198 
00199     if (!num)
00200         num = 1;
00201 
00202     do
00203     {
00204         if (b+num-1 > fs->ext2_sb->s_blocks_count)
00205             b = fs->ext2_sb->s_first_data_block;
00206 
00207         if (ext2_test_block_bitmap_range(map, b, num))
00208         {
00209             *ret = b;
00210             return true;
00211         }
00212 
00213         b++;
00214 
00215     } while (b != finish);
00216 
00217     return false;
00218 }
00219 
00220 
00221 bool write_inode_tables(PEXT2_FILESYS fs)
00222 {
00223     bool    retval;
00224     ULONG   blk, num;
00225     int     i;
00226 
00227     for (i = 0; (ULONG)i < fs->group_desc_count; i++)
00228     {
00229         blk = fs->group_desc[i].bg_inode_table;
00230         num = fs->inode_blocks_per_group;
00231 
00232         retval = zero_blocks(fs, blk, num, &blk, &num);
00233         if (!retval)
00234         {
00235             DPRINT1("\nMke2fs: Could not write %lu blocks "
00236                 "in inode table starting at %lu.\n",
00237                 num, blk);
00238 
00239             zero_blocks(0, 0, 0, 0, 0);
00240             return false;
00241         }
00242     }
00243 
00244     zero_blocks(0, 0, 0, 0, 0);
00245 
00246     return true;
00247 }
00248 
00249 
00250 /*
00251  * Stupid algorithm --- we now just search forward starting from the
00252  * goal.  Should put in a smarter one someday....
00253  */
00254 bool ext2_new_block(PEXT2_FILESYS fs, ULONG goal,
00255                PEXT2_BLOCK_BITMAP map, ULONG *ret)
00256 {
00257     ULONG   i;
00258 
00259     if (!map)
00260         map = fs->block_map;
00261 
00262     if (!map)
00263         return false;
00264 
00265     if (!goal || (goal >= fs->ext2_sb->s_blocks_count))
00266         goal = fs->ext2_sb->s_first_data_block;
00267 
00268     i = goal;
00269 
00270     do
00271     {
00272         if (!ext2_test_block_bitmap(map, i))
00273         {
00274             *ret = i;
00275             return true;
00276         }
00277 
00278         i++;
00279 
00280         if (i >= fs->ext2_sb->s_blocks_count)
00281             i = fs->ext2_sb->s_first_data_block;
00282 
00283     } while (i != goal);
00284 
00285     return false;
00286 }
00287 
00288 
00289 /*
00290  * This function zeros out the allocated block, and updates all of the
00291  * appropriate filesystem records.
00292  */
00293 bool ext2_alloc_block(PEXT2_FILESYS fs, ULONG goal, ULONG *ret)
00294 {
00295     bool        retval;
00296     ULONG       block;
00297     char        *buf = NULL;
00298 
00299     buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, fs->blocksize);
00300     if (!buf)
00301         return false;
00302 
00303     if (!fs->block_map)
00304     {
00305         retval = ext2_read_block_bitmap(fs);
00306         if (!retval)
00307             goto fail;
00308     }
00309 
00310     retval = ext2_new_block(fs, goal, 0, &block);
00311 
00312     if (!retval)
00313         goto fail;
00314 
00315     retval = NT_SUCCESS(Ext2WriteDisk(
00316                 fs,
00317                 ((LONGLONG)block * fs->blocksize),
00318                 fs->blocksize, (unsigned char *)buf));
00319 
00320     if (!retval)
00321     {
00322         goto fail;
00323     }
00324     
00325     ext2_block_alloc_stats(fs, block, +1);
00326     *ret = block;
00327 
00328     if (buf)
00329     {
00330         RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
00331     }
00332 
00333     return true;
00334 
00335 fail:
00336 
00337     if (buf)
00338     {
00339         RtlFreeHeap(RtlGetProcessHeap(), 0, buf);
00340     }
00341 
00342     return false;
00343 }
00344 
00345 
00346 /*
00347  * Create new directory block
00348  */
00349 bool ext2_new_dir_block(PEXT2_FILESYS fs, ULONG dir_ino,
00350                    ULONG parent_ino, char **block)
00351 {
00352     PEXT2_DIR_ENTRY dir = NULL;
00353     char        *buf;
00354     int         rec_len;
00355     int         filetype = 0;
00356 
00357     buf = (char *)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, fs->blocksize);
00358     if (!buf)
00359         return false;
00360 
00361     dir = (PEXT2_DIR_ENTRY) buf;
00362     dir->rec_len = fs->blocksize;
00363 
00364     if (dir_ino)
00365     {
00366         if (fs->ext2_sb->s_feature_incompat &
00367             EXT2_FEATURE_INCOMPAT_FILETYPE)
00368             filetype = EXT2_FT_DIR << 8;
00369         /*
00370          * Set up entry for '.'
00371          */
00372         dir->inode = dir_ino;
00373         dir->name_len = 1 | filetype;
00374         dir->name[0] = '.';
00375         rec_len = dir->rec_len - EXT2_DIR_REC_LEN(1);
00376         dir->rec_len = EXT2_DIR_REC_LEN(1);
00377 
00378         /*
00379          * Set up entry for '..'
00380          */
00381         dir = (struct ext2_dir_entry *) (buf + dir->rec_len);
00382         dir->rec_len = rec_len;
00383         dir->inode = parent_ino;
00384         dir->name_len = 2 | filetype;
00385         dir->name[0] = '.';
00386         dir->name[1] = '.';
00387     }
00388 
00389     *block = buf;
00390 
00391     return true;
00392 }
00393 
00394 bool ext2_write_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
00395 {
00396     bool    retval = false;
00397 
00398     retval = NT_SUCCESS(Ext2WriteDisk(
00399                 fs,
00400                 ((ULONGLONG)block * fs->blocksize),
00401                 fs->blocksize, (unsigned char *)inbuf));
00402 
00403     return retval;
00404 }
00405 
00406 bool ext2_read_block(PEXT2_FILESYS fs, ULONG block, void *inbuf)
00407 {
00408     bool    retval = false;
00409 
00410     retval = NT_SUCCESS(Ext2ReadDisk(
00411                 fs,
00412                 ((ULONGLONG)block * fs->blocksize),
00413                 fs->blocksize, (unsigned char *)inbuf));
00414 
00415     return retval;
00416 }

Generated on Fri May 25 2012 04:34:40 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.