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

Bitmap.c
Go to the documentation of this file.
00001 /*
00002  * PROJECT:          Mke2fs
00003  * FILE:             Bitmap.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 /* FUNCTIONS *************************************************************/
00016 
00017 
00018 bool ext2_set_bit(int nr,void * addr)
00019 {
00020     int     mask;
00021     unsigned char *ADDR = (unsigned char *) addr;
00022 
00023     ADDR += nr >> 3;
00024     mask = 1 << (nr & 0x07);
00025     *ADDR |= mask;
00026 
00027     return true;
00028 }
00029 
00030 bool ext2_clear_bit(int nr, void * addr)
00031 {
00032     int     mask;
00033     unsigned char   *ADDR = (unsigned char *) addr;
00034 
00035     ADDR += nr >> 3;
00036     mask = 1 << (nr & 0x07);
00037     *ADDR &= ~mask;
00038     return true;
00039 }
00040 
00041 bool ext2_test_bit(int nr, void * addr)
00042 {
00043     int         mask;
00044     const unsigned char *ADDR = (const unsigned char *) addr;
00045 
00046     ADDR += nr >> 3;
00047     mask = 1 << (nr & 0x07);
00048 
00049     return ((mask & *ADDR) != 0);
00050 }
00051 
00052 bool ext2_mark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno)
00053 {
00054     if ((bitno < bitmap->start) || (bitno > bitmap->end))
00055     {
00056         return false;
00057     }
00058 
00059     return ext2_set_bit(bitno - bitmap->start, bitmap->bitmap);
00060 }
00061 
00062 bool ext2_unmark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno)
00063 {
00064     if ((bitno < bitmap->start) || (bitno > bitmap->end))
00065     {
00066         return false;
00067     }
00068 
00069     return ext2_clear_bit(bitno - bitmap->start, bitmap->bitmap);
00070 }
00071 
00072 
00073 bool ext2_test_block_bitmap(PEXT2_BLOCK_BITMAP bitmap,
00074                         ULONG block)
00075 {
00076     return ext2_test_bit(block - bitmap->start, bitmap->bitmap);
00077 }
00078 
00079 
00080 bool ext2_test_block_bitmap_range(PEXT2_BLOCK_BITMAP bitmap,
00081                         ULONG block, int num)
00082 {
00083     int i;
00084 
00085     for (i=0; i < num; i++)
00086     {
00087         if (ext2_test_block_bitmap(bitmap, block+i))
00088             return false;
00089     }
00090     return true;
00091 }
00092 
00093 bool ext2_test_inode_bitmap(PEXT2_BLOCK_BITMAP bitmap,
00094                         ULONG inode)
00095 {
00096     return ext2_test_bit(inode - bitmap->start, bitmap->bitmap);
00097 }
00098 
00099 
00100 bool ext2_allocate_block_bitmap(PEXT2_FILESYS Ext2Sys)
00101 {
00102     ULONG   size = 0;
00103 
00104     PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
00105     Ext2Sys->block_map = (PEXT2_BLOCK_BITMAP)
00106         RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(EXT2_BLOCK_BITMAP));
00107 
00108     if (!Ext2Sys->block_map)
00109     {
00110         DPRINT1("Mke2fs: error allocating block bitmap...\n");
00111         return false;
00112     }
00113 
00114     memset(Ext2Sys->block_map, 0, sizeof(EXT2_BLOCK_BITMAP));
00115 
00116     Ext2Sys->block_map->start = pExt2Sb->s_first_data_block;
00117     Ext2Sys->block_map->end = pExt2Sb->s_blocks_count-1;
00118     Ext2Sys->block_map->real_end = (EXT2_BLOCKS_PER_GROUP(pExt2Sb)
00119         * Ext2Sys->group_desc_count) -1 + Ext2Sys->block_map->start;
00120 
00121     size = (((Ext2Sys->block_map->real_end - Ext2Sys->block_map->start) / 8) + 1);
00122 
00123     Ext2Sys->block_map->bitmap =
00124         (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, size);
00125 
00126     if (!Ext2Sys->block_map->bitmap)
00127     {
00128         RtlFreeHeap(RtlGetProcessHeap(), 0, Ext2Sys->block_map);
00129         Ext2Sys->block_map = NULL;
00130         DPRINT1("Mke2fs: error allocating block bitmap...\n");
00131         return false;
00132     }
00133 
00134     memset(Ext2Sys->block_map->bitmap, 0, size);
00135 
00136     return true;
00137 }
00138 
00139 
00140 bool ext2_allocate_inode_bitmap(PEXT2_FILESYS Ext2Sys)
00141 {
00142     ULONG   size = 0;
00143 
00144     PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
00145 
00146     Ext2Sys->inode_map = (PEXT2_INODE_BITMAP)
00147         RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(EXT2_INODE_BITMAP));
00148 
00149     if (!Ext2Sys->inode_map)
00150     {
00151         DPRINT1("Mke2fs: error allocating inode bitmap...\n");
00152         return false;
00153     }
00154 
00155     memset(Ext2Sys->inode_map, 0, sizeof(EXT2_INODE_BITMAP));
00156 
00157     Ext2Sys->inode_map->start = 1;
00158     Ext2Sys->inode_map->end = pExt2Sb->s_inodes_count;
00159     Ext2Sys->inode_map->real_end = (EXT2_INODES_PER_GROUP(pExt2Sb)
00160         * Ext2Sys->group_desc_count);
00161 
00162     size = (((Ext2Sys->inode_map->real_end - Ext2Sys->inode_map->start) / 8) + 1);
00163 
00164     Ext2Sys->inode_map->bitmap =
00165         (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, size);
00166 
00167     if (!Ext2Sys->inode_map->bitmap)
00168     {
00169         RtlFreeHeap(RtlGetProcessHeap(), 0, Ext2Sys->inode_map);
00170         Ext2Sys->inode_map = NULL;
00171         DPRINT1("Mke2fs: error allocating block bitmap...\n");
00172         return false;
00173     }
00174 
00175     memset(Ext2Sys->inode_map->bitmap, 0, size);
00176 
00177     return true;
00178 }
00179 
00180 void ext2_free_generic_bitmap(PEXT2_GENERIC_BITMAP bitmap)
00181 {
00182     if (!bitmap)
00183         return;
00184 
00185     if (bitmap->bitmap)
00186     {
00187         RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap->bitmap);
00188         bitmap->bitmap = 0;
00189     }
00190 
00191     RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap);
00192 }
00193 
00194 void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys)
00195 {
00196     PEXT2_INODE_BITMAP bitmap = Ext2Sys->inode_map;
00197     if (!bitmap)
00198         return;
00199 
00200     ext2_free_generic_bitmap(bitmap);
00201 
00202     Ext2Sys->inode_map = NULL;
00203 }
00204 
00205 void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys)
00206 {
00207     PEXT2_BLOCK_BITMAP bitmap = Ext2Sys->block_map;
00208     if (!bitmap)
00209         return;
00210 
00211     ext2_free_generic_bitmap(bitmap);
00212 
00213     Ext2Sys->block_map = NULL;
00214 }
00215 
00216 bool ext2_write_inode_bitmap(PEXT2_FILESYS fs)
00217 {
00218     ULONG   i;
00219     ULONG   nbytes;
00220     bool    retval;
00221     char    *inode_bitmap = fs->inode_map->bitmap;
00222     char    *bitmap_block = NULL;
00223     ULONG   blk;
00224 
00225     if (!inode_bitmap)
00226         return false;
00227 
00228     nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->ext2_sb)+7) / 8);
00229     
00230     bitmap_block = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, fs->blocksize);
00231     if (!bitmap_block) return false;
00232 
00233     memset(bitmap_block, 0xff, fs->blocksize);
00234 
00235     for (i = 0; i < fs->group_desc_count; i++)
00236     {
00237         memcpy(bitmap_block, inode_bitmap, nbytes);
00238         blk = fs->group_desc[i].bg_inode_bitmap;
00239 
00240         if (blk)
00241         {
00242 /*
00243 #ifdef EXT2_BIG_ENDIAN_BITMAPS
00244             if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
00245                   (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
00246                 ext2_swap_bitmap(fs, bitmap_block, nbytes);
00247 #endif
00248 */
00249             retval = NT_SUCCESS(Ext2WriteDisk(
00250                     fs,
00251                     ((ULONGLONG)blk * fs->blocksize),
00252                     fs->blocksize, 
00253                     (unsigned char *)bitmap_block));
00254 
00255             if (!retval)
00256             {
00257                 RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
00258                 return false;
00259             }
00260         }
00261 
00262         inode_bitmap += nbytes;
00263     }
00264 
00265     RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
00266 
00267     return true;
00268 }
00269 
00270 bool ext2_write_block_bitmap (PEXT2_FILESYS fs)
00271 {
00272     ULONG   i;
00273     int     j;
00274     int     nbytes;
00275     int     nbits;
00276     bool    retval;
00277     char    *block_bitmap = fs->block_map->bitmap;
00278     char    *bitmap_block = NULL;
00279     ULONG   blk;
00280 
00281     if (!block_bitmap)
00282         return false;
00283 
00284     nbytes = EXT2_BLOCKS_PER_GROUP(fs->ext2_sb) / 8;
00285 
00286     bitmap_block = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, fs->blocksize);
00287     if (!bitmap_block)
00288         return false;
00289 
00290     memset(bitmap_block, 0xff, fs->blocksize);
00291 
00292     for (i = 0; i < fs->group_desc_count; i++)
00293     {
00294         memcpy(bitmap_block, block_bitmap, nbytes);
00295 
00296         if (i == fs->group_desc_count - 1)
00297         {
00298             /* Force bitmap padding for the last group */
00299             nbits = (int) ((fs->ext2_sb->s_blocks_count
00300                     - fs->ext2_sb->s_first_data_block)
00301                        % EXT2_BLOCKS_PER_GROUP(fs->ext2_sb));
00302 
00303             if (nbits)
00304             {
00305                 for (j = nbits; j < fs->blocksize * 8; j++)
00306                 {
00307                     ext2_set_bit(j, bitmap_block);
00308                 }
00309             }
00310         }
00311 
00312         blk = fs->group_desc[i].bg_block_bitmap;
00313 
00314         if (blk)
00315         {
00316 #ifdef EXT2_BIG_ENDIAN_BITMAPS
00317             if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
00318                   (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
00319                 ext2_swap_bitmap(fs, bitmap_block, nbytes);
00320 #endif
00321             retval = NT_SUCCESS(Ext2WriteDisk(
00322                         fs,
00323                         ((ULONGLONG)blk * fs->blocksize),
00324                         fs->blocksize,
00325                         (unsigned char *)bitmap_block));
00326 
00327             if (!retval)
00328             {
00329                 RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
00330                 return false;
00331             }
00332         }
00333 
00334         block_bitmap += nbytes;
00335     }
00336 
00337     RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
00338 
00339     return true;
00340 }
00341 
00342 bool ext2_write_bitmaps(PEXT2_FILESYS fs)
00343 {
00344     bool    retval;
00345 
00346     if (fs->block_map) // && ext2fs_test_bb_dirty(fs))
00347     {
00348         retval = ext2_write_block_bitmap(fs);
00349         if (!retval)
00350             return retval;
00351     }
00352 
00353     if (fs->inode_map) // && ext2fs_test_ib_dirty(fs))
00354     {
00355         retval = ext2_write_inode_bitmap(fs);
00356         if (!retval)
00357             return retval;
00358     }
00359 
00360     return true;
00361 }
00362 
00363 
00364 bool read_bitmaps(PEXT2_FILESYS fs, int do_inode, int do_block)
00365 {
00366     ULONG i;
00367     char *block_bitmap = 0, *inode_bitmap = 0;
00368     bool retval = false;
00369     ULONG block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->ext2_sb) / 8;
00370     ULONG inode_nbytes = EXT2_INODES_PER_GROUP(fs->ext2_sb) / 8;
00371     ULONG blk;
00372 
00373 //  fs->write_bitmaps = ext2_write_bitmaps;
00374 
00375     if (do_block)
00376     {
00377         if (fs->block_map)
00378             ext2_free_block_bitmap(fs);
00379 
00380         retval = ext2_allocate_block_bitmap(fs);
00381 
00382         if (!retval)
00383             goto cleanup;
00384 
00385         block_bitmap = fs->block_map->bitmap;
00386     }
00387 
00388     if (do_inode)
00389     {
00390         if (fs->inode_map)
00391             ext2_free_inode_bitmap(fs);
00392 
00393         retval = ext2_allocate_inode_bitmap(fs);
00394         if (!retval)
00395             goto cleanup;
00396 
00397         inode_bitmap = fs->inode_map->bitmap;
00398     }
00399 
00400     for (i = 0; i < fs->group_desc_count; i++)
00401     {
00402         if (block_bitmap)
00403         {
00404             blk = fs->group_desc[i].bg_block_bitmap;
00405 
00406             if (blk)
00407             {
00408                 retval = NT_SUCCESS(Ext2ReadDisk(
00409                             fs,
00410                             ((ULONGLONG)blk * fs->blocksize), 
00411                             block_nbytes,
00412                             (unsigned char *) block_bitmap));
00413 
00414                 if (!retval)
00415                 {
00416                     goto cleanup;
00417                 }
00418 
00419 #ifdef EXT2_BIG_ENDIAN_BITMAPS
00420                 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
00421                       (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
00422                     ext2_swap_bitmap(fs, block_bitmap, block_nbytes);
00423 #endif
00424             }
00425             else
00426             {
00427                 memset(block_bitmap, 0, block_nbytes);
00428             }
00429 
00430             block_bitmap += block_nbytes;
00431         }
00432 
00433         if (inode_bitmap)
00434         {
00435             blk = fs->group_desc[i].bg_inode_bitmap;
00436             if (blk)
00437             {
00438                 retval = NT_SUCCESS(Ext2ReadDisk(
00439                     fs, ((LONGLONG)blk * fs->blocksize), 
00440                     inode_nbytes, 
00441                     (unsigned char *)inode_bitmap));
00442 
00443                 if (!retval)
00444                 {
00445                     goto cleanup;
00446                 }
00447 
00448 #ifdef EXT2_BIG_ENDIAN_BITMAPS
00449                 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
00450                       (fs->flags & EXT2_FLAG_SWAP_BYTES_READ)))
00451                     ext2_swap_bitmap(fs, inode_bitmap, inode_nbytes);
00452 #endif
00453             }
00454             else
00455             {
00456                 memset(inode_bitmap, 0, inode_nbytes);
00457             }
00458 
00459             inode_bitmap += inode_nbytes;
00460         }
00461     }
00462 
00463     return true;
00464     
00465 cleanup:
00466 
00467     if (do_block)
00468     {
00469         RtlFreeHeap(RtlGetProcessHeap(), 0, fs->block_map);
00470         fs->block_map = NULL;
00471     }
00472 
00473     if (do_inode)
00474     {
00475         RtlFreeHeap(RtlGetProcessHeap(), 0, fs->inode_map);
00476         fs->inode_map = 0;
00477     }
00478 
00479     return false;
00480 }
00481 
00482 bool ext2_read_inode_bitmap (PEXT2_FILESYS fs)
00483 {
00484     return read_bitmaps(fs, 1, 0);
00485 }
00486 
00487 bool ext2_read_block_bitmap(PEXT2_FILESYS fs)
00488 {
00489     return read_bitmaps(fs, 0, 1);
00490 }
00491 
00492 bool ext2_read_bitmaps(PEXT2_FILESYS fs)
00493 {
00494 
00495     if (fs->inode_map && fs->block_map)
00496         return 0;
00497 
00498     return read_bitmaps(fs, !fs->inode_map, !fs->block_map);
00499 }
00500 

Generated on Sat May 26 2012 04:35: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.