4 * PROGRAMMER: Matt Wu <mattwu@163.com>
5 * HOMEPAGE: http://ext2.yeah.net
8 /* INCLUDES **************************************************************/
12 /* DEFINITIONS ***********************************************************/
14 /* FUNCTIONS *************************************************************/
17 bool ext2_set_bit(int nr
,void * addr
)
20 unsigned char *ADDR
= (unsigned char *) addr
;
23 mask
= 1 << (nr
& 0x07);
29 bool ext2_clear_bit(int nr
, void * addr
)
32 unsigned char *ADDR
= (unsigned char *) addr
;
35 mask
= 1 << (nr
& 0x07);
40 bool ext2_test_bit(int nr
, void * addr
)
43 const unsigned char *ADDR
= (const unsigned char *) addr
;
46 mask
= 1 << (nr
& 0x07);
48 return ((mask
& *ADDR
) != 0);
51 bool ext2_mark_bitmap(PEXT2_BITMAP bitmap
, ULONG bitno
)
53 if ((bitno
< bitmap
->start
) || (bitno
> bitmap
->end
))
58 return ext2_set_bit(bitno
- bitmap
->start
, bitmap
->bitmap
);
61 bool ext2_unmark_bitmap(PEXT2_BITMAP bitmap
, ULONG bitno
)
63 if ((bitno
< bitmap
->start
) || (bitno
> bitmap
->end
))
68 return ext2_clear_bit(bitno
- bitmap
->start
, bitmap
->bitmap
);
72 bool ext2_test_block_bitmap(PEXT2_BLOCK_BITMAP bitmap
,
75 return ext2_test_bit(block
- bitmap
->start
, bitmap
->bitmap
);
79 bool ext2_test_block_bitmap_range(PEXT2_BLOCK_BITMAP bitmap
,
84 for (i
=0; i
< num
; i
++)
86 if (ext2_test_block_bitmap(bitmap
, block
+i
))
92 bool ext2_test_inode_bitmap(PEXT2_BLOCK_BITMAP bitmap
,
95 return ext2_test_bit(inode
- bitmap
->start
, bitmap
->bitmap
);
99 bool ext2_allocate_block_bitmap(PEXT2_FILESYS Ext2Sys
)
103 PEXT2_SUPER_BLOCK pExt2Sb
= Ext2Sys
->ext2_sb
;
104 Ext2Sys
->block_map
= (PEXT2_BLOCK_BITMAP
)
105 RtlAllocateHeap(GetProcessHeap(), 0, sizeof(EXT2_BLOCK_BITMAP
));
107 if (!Ext2Sys
->block_map
)
109 KdPrint(("Mke2fs: error allocating block bitmap...\n"));
113 memset(Ext2Sys
->block_map
, 0, sizeof(EXT2_BLOCK_BITMAP
));
115 Ext2Sys
->block_map
->start
= pExt2Sb
->s_first_data_block
;
116 Ext2Sys
->block_map
->end
= pExt2Sb
->s_blocks_count
-1;
117 Ext2Sys
->block_map
->real_end
= (EXT2_BLOCKS_PER_GROUP(pExt2Sb
)
118 * Ext2Sys
->group_desc_count
) -1 + Ext2Sys
->block_map
->start
;
120 size
= (((Ext2Sys
->block_map
->real_end
- Ext2Sys
->block_map
->start
) / 8) + 1);
122 Ext2Sys
->block_map
->bitmap
=
123 (char *)RtlAllocateHeap(GetProcessHeap(), 0, size
);
125 if (!Ext2Sys
->block_map
->bitmap
)
127 RtlFreeHeap(GetProcessHeap(), 0, Ext2Sys
->block_map
);
128 Ext2Sys
->block_map
= NULL
;
129 KdPrint(("Mke2fs: error allocating block bitmap...\n"));
133 memset(Ext2Sys
->block_map
->bitmap
, 0, size
);
139 bool ext2_allocate_inode_bitmap(PEXT2_FILESYS Ext2Sys
)
143 PEXT2_SUPER_BLOCK pExt2Sb
= Ext2Sys
->ext2_sb
;
145 Ext2Sys
->inode_map
= (PEXT2_INODE_BITMAP
)
146 RtlAllocateHeap(GetProcessHeap(), 0, sizeof(EXT2_INODE_BITMAP
));
148 if (!Ext2Sys
->inode_map
)
150 KdPrint(("Mke2fs: error allocating inode bitmap...\n"));
154 memset(Ext2Sys
->inode_map
, 0, sizeof(EXT2_INODE_BITMAP
));
156 Ext2Sys
->inode_map
->start
= 1;
157 Ext2Sys
->inode_map
->end
= pExt2Sb
->s_inodes_count
;
158 Ext2Sys
->inode_map
->real_end
= (EXT2_INODES_PER_GROUP(pExt2Sb
)
159 * Ext2Sys
->group_desc_count
);
161 size
= (((Ext2Sys
->inode_map
->real_end
- Ext2Sys
->inode_map
->start
) / 8) + 1);
163 Ext2Sys
->inode_map
->bitmap
=
164 (char *)RtlAllocateHeap(GetProcessHeap(), 0, size
);
166 if (!Ext2Sys
->inode_map
->bitmap
)
168 RtlFreeHeap(GetProcessHeap(), 0, Ext2Sys
->inode_map
);
169 Ext2Sys
->inode_map
= NULL
;
170 KdPrint(("Mke2fs: error allocating block bitmap...\n"));
174 memset(Ext2Sys
->inode_map
->bitmap
, 0, size
);
179 void ext2_free_generic_bitmap(PEXT2_GENERIC_BITMAP bitmap
)
186 RtlFreeHeap(GetProcessHeap(), 0, bitmap
->bitmap
);
190 RtlFreeHeap(GetProcessHeap(), 0, bitmap
);
193 void ext2_free_inode_bitmap(PEXT2_FILESYS Ext2Sys
)
195 PEXT2_INODE_BITMAP bitmap
= Ext2Sys
->inode_map
;
199 ext2_free_generic_bitmap(bitmap
);
201 Ext2Sys
->inode_map
= NULL
;
204 void ext2_free_block_bitmap(PEXT2_FILESYS Ext2Sys
)
206 PEXT2_BLOCK_BITMAP bitmap
= Ext2Sys
->block_map
;
210 ext2_free_generic_bitmap(bitmap
);
212 Ext2Sys
->block_map
= NULL
;
215 bool ext2_write_inode_bitmap(PEXT2_FILESYS fs
)
220 char *inode_bitmap
= fs
->inode_map
->bitmap
;
221 char *bitmap_block
= NULL
;
227 nbytes
= (size_t) ((EXT2_INODES_PER_GROUP(fs
->ext2_sb
)+7) / 8);
229 bitmap_block
= (char *)RtlAllocateHeap(GetProcessHeap(), 0, fs
->blocksize
);
230 if (!bitmap_block
) return false;
232 memset(bitmap_block
, 0xff, fs
->blocksize
);
234 for (i
= 0; i
< fs
->group_desc_count
; i
++)
236 memcpy(bitmap_block
, inode_bitmap
, nbytes
);
237 blk
= fs
->group_desc
[i
].bg_inode_bitmap
;
242 #ifdef EXT2_BIG_ENDIAN_BITMAPS
243 if (!((fs->flags & EXT2_FLAG_SWAP_BYTES) ||
244 (fs->flags & EXT2_FLAG_SWAP_BYTES_WRITE)))
245 ext2_swap_bitmap(fs, bitmap_block, nbytes);
248 retval
= NT_SUCCESS(Ext2WriteDisk(
250 ((ULONGLONG
)blk
* fs
->blocksize
),
252 (unsigned char *)bitmap_block
));
256 RtlFreeHeap(GetProcessHeap(), 0, bitmap_block
);
261 inode_bitmap
+= nbytes
;
264 RtlFreeHeap(GetProcessHeap(), 0, bitmap_block
);
269 bool ext2_write_block_bitmap (PEXT2_FILESYS fs
)
276 char *block_bitmap
= fs
->block_map
->bitmap
;
277 char *bitmap_block
= NULL
;
283 nbytes
= EXT2_BLOCKS_PER_GROUP(fs
->ext2_sb
) / 8;
285 bitmap_block
= (char *)RtlAllocateHeap(GetProcessHeap(), 0, fs
->blocksize
);
289 memset(bitmap_block
, 0xff, fs
->blocksize
);
291 for (i
= 0; i
< fs
->group_desc_count
; i
++)
293 memcpy(bitmap_block
, block_bitmap
, nbytes
);
295 if (i
== fs
->group_desc_count
- 1)
297 /* Force bitmap padding for the last group */
298 nbits
= (int) ((fs
->ext2_sb
->s_blocks_count
299 - fs
->ext2_sb
->s_first_data_block
)
300 % EXT2_BLOCKS_PER_GROUP(fs
->ext2_sb
));
304 for (j
= nbits
; j
< fs
->blocksize
* 8; j
++)
306 ext2_set_bit(j
, bitmap_block
);
311 blk
= fs
->group_desc
[i
].bg_block_bitmap
;
315 #ifdef EXT2_BIG_ENDIAN_BITMAPS
316 if (!((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
317 (fs
->flags
& EXT2_FLAG_SWAP_BYTES_WRITE
)))
318 ext2_swap_bitmap(fs
, bitmap_block
, nbytes
);
320 retval
= NT_SUCCESS(Ext2WriteDisk(
322 ((ULONGLONG
)blk
* fs
->blocksize
),
324 (unsigned char *)bitmap_block
));
328 RtlFreeHeap(GetProcessHeap(), 0, bitmap_block
);
333 block_bitmap
+= nbytes
;
336 RtlFreeHeap(GetProcessHeap(), 0, bitmap_block
);
341 bool ext2_write_bitmaps(PEXT2_FILESYS fs
)
345 if (fs
->block_map
) // && ext2fs_test_bb_dirty(fs))
347 retval
= ext2_write_block_bitmap(fs
);
352 if (fs
->inode_map
) // && ext2fs_test_ib_dirty(fs))
354 retval
= ext2_write_inode_bitmap(fs
);
363 bool read_bitmaps(PEXT2_FILESYS fs
, int do_inode
, int do_block
)
366 char *block_bitmap
= 0, *inode_bitmap
= 0;
368 ULONG block_nbytes
= EXT2_BLOCKS_PER_GROUP(fs
->ext2_sb
) / 8;
369 ULONG inode_nbytes
= EXT2_INODES_PER_GROUP(fs
->ext2_sb
) / 8;
372 // fs->write_bitmaps = ext2_write_bitmaps;
377 ext2_free_block_bitmap(fs
);
379 retval
= ext2_allocate_block_bitmap(fs
);
384 block_bitmap
= fs
->block_map
->bitmap
;
390 ext2_free_inode_bitmap(fs
);
392 retval
= ext2_allocate_inode_bitmap(fs
);
396 inode_bitmap
= fs
->inode_map
->bitmap
;
399 for (i
= 0; i
< fs
->group_desc_count
; i
++)
403 blk
= fs
->group_desc
[i
].bg_block_bitmap
;
407 retval
= NT_SUCCESS(Ext2ReadDisk(
409 ((ULONGLONG
)blk
* fs
->blocksize
),
411 (unsigned char *) block_bitmap
));
418 #ifdef EXT2_BIG_ENDIAN_BITMAPS
419 if (!((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
420 (fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
)))
421 ext2_swap_bitmap(fs
, block_bitmap
, block_nbytes
);
426 memset(block_bitmap
, 0, block_nbytes
);
429 block_bitmap
+= block_nbytes
;
434 blk
= fs
->group_desc
[i
].bg_inode_bitmap
;
437 retval
= NT_SUCCESS(Ext2ReadDisk(
438 fs
, ((LONGLONG
)blk
* fs
->blocksize
),
440 (unsigned char *)inode_bitmap
));
447 #ifdef EXT2_BIG_ENDIAN_BITMAPS
448 if (!((fs
->flags
& EXT2_FLAG_SWAP_BYTES
) ||
449 (fs
->flags
& EXT2_FLAG_SWAP_BYTES_READ
)))
450 ext2_swap_bitmap(fs
, inode_bitmap
, inode_nbytes
);
455 memset(inode_bitmap
, 0, inode_nbytes
);
458 inode_bitmap
+= inode_nbytes
;
468 RtlFreeHeap(GetProcessHeap(), 0, fs
->block_map
);
469 fs
->block_map
= NULL
;
474 RtlFreeHeap(GetProcessHeap(), 0, fs
->inode_map
);
481 bool ext2_read_inode_bitmap (PEXT2_FILESYS fs
)
483 return read_bitmaps(fs
, 1, 0);
486 bool ext2_read_block_bitmap(PEXT2_FILESYS fs
)
488 return read_bitmaps(fs
, 0, 1);
491 bool ext2_read_bitmaps(PEXT2_FILESYS fs
)
494 if (fs
->inode_map
&& fs
->block_map
)
497 return read_bitmaps(fs
, !fs
->inode_map
, !fs
->block_map
);