Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > DoxygenBitmap.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
1.7.6.1
|