Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501/* * PROJECT: Mke2fs * FILE: Bitmap.c * PROGRAMMER: Matt Wu <mattwu@163.com> * HOMEPAGE: http://ext2.yeah.net */
/* INCLUDES **************************************************************/
#include "Mke2fs.h"#include <debug.h>
/* DEFINITIONS ***********************************************************/
/* FUNCTIONS *************************************************************/
bool ext2_set_bit(int nr,void * addr){ int mask; unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3; mask = 1 << (nr & 0x07); *ADDR |= mask;
return true;}
bool ext2_clear_bit(int nr, void * addr){ int mask; unsigned char *ADDR = (unsigned char *) addr;
ADDR += nr >> 3; mask = 1 << (nr & 0x07); *ADDR &= ~mask; return true;}
bool ext2_test_bit(int nr, void * addr){ int mask; const unsigned char *ADDR = (const unsigned char *) addr;
ADDR += nr >> 3; mask = 1 << (nr & 0x07);
return ((mask & *ADDR) != 0);}
bool ext2_mark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno){ if ((bitno < bitmap->start) || (bitno > bitmap->end)) { return false; }
return ext2_set_bit(bitno - bitmap->start, bitmap->bitmap);}
bool ext2_unmark_bitmap(PEXT2_BITMAP bitmap, ULONG bitno){ if ((bitno < bitmap->start) || (bitno > bitmap->end)) { return false; }
return ext2_clear_bit(bitno - bitmap->start, bitmap->bitmap);}
bool ext2_test_block_bitmap(PEXT2_BLOCK_BITMAP bitmap, ULONG block){ return ext2_test_bit(block - bitmap->start, bitmap->bitmap);}
bool ext2_test_block_bitmap_range(PEXT2_BLOCK_BITMAP bitmap, ULONG block, int num){ int i;
for (i=0; i < num; i++) { if (ext2_test_block_bitmap(bitmap, block+i)) return false; } return true;}
bool ext2_test_inode_bitmap(PEXT2_BLOCK_BITMAP bitmap, ULONG inode){ return ext2_test_bit(inode - bitmap->start, bitmap->bitmap);}
bool ext2_allocate_block_bitmap(PEXT2_FILESYS Ext2Sys){ ULONG size = 0;
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb; Ext2Sys->block_map = (PEXT2_BLOCK_BITMAP) RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(EXT2_BLOCK_BITMAP));
if (!Ext2Sys->block_map) { DPRINT1("Mke2fs: error allocating block bitmap...\n"); return false; }
memset(Ext2Sys->block_map, 0, sizeof(EXT2_BLOCK_BITMAP));
Ext2Sys->block_map->start = pExt2Sb->s_first_data_block; Ext2Sys->block_map->end = pExt2Sb->s_blocks_count-1; Ext2Sys->block_map->real_end = (EXT2_BLOCKS_PER_GROUP(pExt2Sb) * Ext2Sys->group_desc_count) -1 + Ext2Sys->block_map->start;
size = (((Ext2Sys->block_map->real_end - Ext2Sys->block_map->start) / 8) + 1);
Ext2Sys->block_map->bitmap = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, size);
if (!Ext2Sys->block_map->bitmap) { RtlFreeHeap(RtlGetProcessHeap(), 0, Ext2Sys->block_map); Ext2Sys->block_map = NULL; DPRINT1("Mke2fs: error allocating block bitmap...\n"); return false; }
memset(Ext2Sys->block_map->bitmap, 0, size);
return true;}
bool ext2_allocate_inode_bitmap(PEXT2_FILESYS Ext2Sys){ ULONG size = 0;
PEXT2_SUPER_BLOCK pExt2Sb = Ext2Sys->ext2_sb;
Ext2Sys->inode_map = (PEXT2_INODE_BITMAP) RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(EXT2_INODE_BITMAP));
if (!Ext2Sys->inode_map) { DPRINT1("Mke2fs: error allocating inode bitmap...\n"); return false; }
memset(Ext2Sys->inode_map, 0, sizeof(EXT2_INODE_BITMAP));
Ext2Sys->inode_map->start = 1; Ext2Sys->inode_map->end = pExt2Sb->s_inodes_count; Ext2Sys->inode_map->real_end = (EXT2_INODES_PER_GROUP(pExt2Sb) * Ext2Sys->group_desc_count);
size = (((Ext2Sys->inode_map->real_end - Ext2Sys->inode_map->start) / 8) + 1);
Ext2Sys->inode_map->bitmap = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, size);
if (!Ext2Sys->inode_map->bitmap) { RtlFreeHeap(RtlGetProcessHeap(), 0, Ext2Sys->inode_map); Ext2Sys->inode_map = NULL; DPRINT1("Mke2fs: error allocating block bitmap...\n"); return false; }
memset(Ext2Sys->inode_map->bitmap, 0, size);
return true;}
void ext2_free_generic_bitmap(PEXT2_GENERIC_BITMAP bitmap){ if (!bitmap) return;
if (bitmap->bitmap) { RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap->bitmap); bitmap->bitmap = 0; }
RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap);}
void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys){ PEXT2_INODE_BITMAP bitmap = Ext2Sys->inode_map; if (!bitmap) return;
ext2_free_generic_bitmap(bitmap);
Ext2Sys->inode_map = NULL;}
void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys){ PEXT2_BLOCK_BITMAP bitmap = Ext2Sys->block_map; if (!bitmap) return;
ext2_free_generic_bitmap(bitmap);
Ext2Sys->block_map = NULL;}
bool ext2_write_inode_bitmap(PEXT2_FILESYS fs){ ULONG i; ULONG nbytes; bool retval; char *inode_bitmap = fs->inode_map->bitmap; char *bitmap_block = NULL; ULONG blk;
if (!inode_bitmap) return false;
nbytes = (size_t) ((EXT2_INODES_PER_GROUP(fs->ext2_sb)+7) / 8);
bitmap_block = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, fs->blocksize); if (!bitmap_block) return false;
memset(bitmap_block, 0xff, fs->blocksize);
for (i = 0; i < fs->group_desc_count; i++) { memcpy(bitmap_block, inode_bitmap, nbytes); blk = fs->group_desc[i].bg_inode_bitmap;
if (blk) {/*#ifdef EXT2_BIG_ENDIAN_BITMAPS if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))) ext2_swap_bitmap(fs, bitmap_block, nbytes);#endif*/ retval = NT_SUCCESS(Ext2WriteDisk( fs, ((ULONGLONG)blk * fs->blocksize), fs->blocksize, (unsigned char *)bitmap_block));
if (!retval) { RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block); return false; } }
inode_bitmap += nbytes; }
RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
return true;}
bool ext2_write_block_bitmap (PEXT2_FILESYS fs){ ULONG i; int j; int nbytes; int nbits; bool retval; char *block_bitmap = fs->block_map->bitmap; char *bitmap_block = NULL; ULONG blk;
if (!block_bitmap) return false;
nbytes = EXT2_BLOCKS_PER_GROUP(fs->ext2_sb) / 8;
bitmap_block = (char *)RtlAllocateHeap(RtlGetProcessHeap(), 0, fs->blocksize); if (!bitmap_block) return false;
memset(bitmap_block, 0xff, fs->blocksize);
for (i = 0; i < fs->group_desc_count; i++) { memcpy(bitmap_block, block_bitmap, nbytes);
if (i == fs->group_desc_count - 1) { /* Force bitmap padding for the last group */ nbits = (int) ((fs->ext2_sb->s_blocks_count - fs->ext2_sb->s_first_data_block) % EXT2_BLOCKS_PER_GROUP(fs->ext2_sb));
if (nbits) { for (j = nbits; j < fs->blocksize * 8; j++) { ext2_set_bit(j, bitmap_block); } } }
blk = fs->group_desc[i].bg_block_bitmap;
if (blk) {#ifdef EXT2_BIG_ENDIAN_BITMAPS if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE))) ext2_swap_bitmap(fs, bitmap_block, nbytes);#endif retval = NT_SUCCESS(Ext2WriteDisk( fs, ((ULONGLONG)blk * fs->blocksize), fs->blocksize, (unsigned char *)bitmap_block));
if (!retval) { RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block); return false; } }
block_bitmap += nbytes; }
RtlFreeHeap(RtlGetProcessHeap(), 0, bitmap_block);
return true;}
bool ext2_write_bitmaps(PEXT2_FILESYS fs){ bool retval;
if (fs->block_map) // && ext2fs_test_bb_dirty(fs)) { retval = ext2_write_block_bitmap(fs); if (!retval) return retval; }
if (fs->inode_map) // && ext2fs_test_ib_dirty(fs)) { retval = ext2_write_inode_bitmap(fs); if (!retval) return retval; }
return true;}
bool read_bitmaps(PEXT2_FILESYS fs, int do_inode, int do_block){ ULONG i; char *block_bitmap = 0, *inode_bitmap = 0; bool retval = false; ULONG block_nbytes = EXT2_BLOCKS_PER_GROUP(fs->ext2_sb) / 8; ULONG inode_nbytes = EXT2_INODES_PER_GROUP(fs->ext2_sb) / 8; ULONG blk;
// fs->write_bitmaps = ext2_write_bitmaps;
if (do_block) { if (fs->block_map) ext2_free_block_bitmap(fs);
retval = ext2_allocate_block_bitmap(fs);
if (!retval) goto cleanup;
block_bitmap = fs->block_map->bitmap; }
if (do_inode) { if (fs->inode_map) ext2_free_inode_bitmap(fs);
retval = ext2_allocate_inode_bitmap(fs); if (!retval) goto cleanup;
inode_bitmap = fs->inode_map->bitmap; }
for (i = 0; i < fs->group_desc_count; i++) { if (block_bitmap) { blk = fs->group_desc[i].bg_block_bitmap;
if (blk) { retval = NT_SUCCESS(Ext2ReadDisk( fs, ((ULONGLONG)blk * fs->blocksize), block_nbytes, (unsigned char *) block_bitmap));
if (!retval) { goto cleanup; }
#ifdef EXT2_BIG_ENDIAN_BITMAPS if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))) ext2_swap_bitmap(fs, block_bitmap, block_nbytes);#endif } else { memset(block_bitmap, 0, block_nbytes); }
block_bitmap += block_nbytes; }
if (inode_bitmap) { blk = fs->group_desc[i].bg_inode_bitmap; if (blk) { retval = NT_SUCCESS(Ext2ReadDisk( fs, ((LONGLONG)blk * fs->blocksize), inode_nbytes, (unsigned char *)inode_bitmap));
if (!retval) { goto cleanup; }
#ifdef EXT2_BIG_ENDIAN_BITMAPS if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) || (fs->flags & EXT2_FLAG_SWAP_BYTES_READ))) ext2_swap_bitmap(fs, inode_bitmap, inode_nbytes);#endif } else { memset(inode_bitmap, 0, inode_nbytes); }
inode_bitmap += inode_nbytes; } }
return true;
cleanup:
if (do_block) { RtlFreeHeap(RtlGetProcessHeap(), 0, fs->block_map); fs->block_map = NULL; }
if (do_inode) { RtlFreeHeap(RtlGetProcessHeap(), 0, fs->inode_map); fs->inode_map = 0; }
return false;}
bool ext2_read_inode_bitmap (PEXT2_FILESYS fs){ return read_bitmaps(fs, 1, 0);}
bool ext2_read_block_bitmap(PEXT2_FILESYS fs){ return read_bitmaps(fs, 0, 1);}
bool ext2_read_bitmaps(PEXT2_FILESYS fs){
if (fs->inode_map && fs->block_map) return 0;
return read_bitmaps(fs, !fs->inode_map, !fs->block_map);}