| /* |
| * ext2fs.h --- ext2fs |
| * |
| * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o. |
| * |
| * %Begin-Header% |
| * This file may be redistributed under the terms of the GNU Public |
| * License. |
| * %End-Header% |
| */ |
| |
| #include "ext2fs.h" |
| #include "bitops.h" |
| |
| /* |
| * Allocate memory |
| */ |
| errcode_t ext2fs_get_mem(unsigned long size, void *ptr) |
| { |
| void **pp = (void **)ptr; |
| |
| *pp = malloc(size); |
| if (!*pp) |
| return EXT2_ET_NO_MEMORY; |
| return 0; |
| } |
| |
| /* |
| * Free memory |
| */ |
| errcode_t ext2fs_free_mem(void *ptr) |
| { |
| void **pp = (void **)ptr; |
| |
| free(*pp); |
| *pp = 0; |
| return 0; |
| } |
| |
| /* |
| * Resize memory |
| */ |
| errcode_t ext2fs_resize_mem(unsigned long EXT2FS_ATTR((unused)) old_size, |
| unsigned long size, void *ptr) |
| { |
| void *p; |
| void **pp = (void **)ptr; |
| |
| p = realloc(*pp, size); |
| if (!p) |
| return EXT2_ET_NO_MEMORY; |
| *pp = p; |
| return 0; |
| } |
| |
| /* |
| * Mark a filesystem superblock as dirty |
| */ |
| void ext2fs_mark_super_dirty(ext2_filsys fs) |
| { |
| fs->flags |= EXT2_FLAG_DIRTY | EXT2_FLAG_CHANGED; |
| } |
| |
| /* |
| * Mark a filesystem as changed |
| */ |
| void ext2fs_mark_changed(ext2_filsys fs) |
| { |
| fs->flags |= EXT2_FLAG_CHANGED; |
| } |
| |
| /* |
| * Check to see if a filesystem has changed |
| */ |
| int ext2fs_test_changed(ext2_filsys fs) |
| { |
| return (fs->flags & EXT2_FLAG_CHANGED); |
| } |
| |
| /* |
| * Mark a filesystem as valid |
| */ |
| void ext2fs_mark_valid(ext2_filsys fs) |
| { |
| fs->flags |= EXT2_FLAG_VALID; |
| } |
| |
| /* |
| * Mark a filesystem as NOT valid |
| */ |
| void ext2fs_unmark_valid(ext2_filsys fs) |
| { |
| fs->flags &= ~EXT2_FLAG_VALID; |
| } |
| |
| /* |
| * Check to see if a filesystem is valid |
| */ |
| int ext2fs_test_valid(ext2_filsys fs) |
| { |
| return (fs->flags & EXT2_FLAG_VALID); |
| } |
| |
| /* |
| * Mark the inode bitmap as dirty |
| */ |
| void ext2fs_mark_ib_dirty(ext2_filsys fs) |
| { |
| fs->flags |= EXT2_FLAG_IB_DIRTY | EXT2_FLAG_CHANGED; |
| } |
| |
| /* |
| * Mark the block bitmap as dirty |
| */ |
| void ext2fs_mark_bb_dirty(ext2_filsys fs) |
| { |
| fs->flags |= EXT2_FLAG_BB_DIRTY | EXT2_FLAG_CHANGED; |
| } |
| |
| /* |
| * Check to see if a filesystem's inode bitmap is dirty |
| */ |
| int ext2fs_test_ib_dirty(ext2_filsys fs) |
| { |
| return (fs->flags & EXT2_FLAG_IB_DIRTY); |
| } |
| |
| /* |
| * Check to see if a filesystem's block bitmap is dirty |
| */ |
| int ext2fs_test_bb_dirty(ext2_filsys fs) |
| { |
| return (fs->flags & EXT2_FLAG_BB_DIRTY); |
| } |
| |
| /* |
| * Return the group # of a block |
| */ |
| int ext2fs_group_of_blk(ext2_filsys fs, blk_t blk) |
| { |
| return (blk - fs->super->s_first_data_block) / |
| fs->super->s_blocks_per_group; |
| } |
| |
| /* |
| * Return the group # of an inode number |
| */ |
| int ext2fs_group_of_ino(ext2_filsys fs, ext2_ino_t ino) |
| { |
| return (ino - 1) / fs->super->s_inodes_per_group; |
| } |
| |
| blk_t ext2fs_inode_data_blocks(ext2_filsys fs, |
| struct ext2_inode *inode) |
| { |
| return inode->i_blocks - |
| (inode->i_file_acl ? fs->blocksize >> 9 : 0); |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| __u16 ext2fs_swab16(__u16 val) |
| { |
| return (val >> 8) | (val << 8); |
| } |
| |
| __u32 ext2fs_swab32(__u32 val) |
| { |
| return ((val>>24) | ((val>>8)&0xFF00) | |
| ((val<<8)&0xFF0000) | (val<<24)); |
| } |
| |
| int ext2fs_find_first_bit_set(void * addr, unsigned size) |
| { |
| char *cp = (unsigned char *) addr; |
| int res = 0, d0; |
| |
| if (!size) |
| return 0; |
| |
| while ((size > res) && (*cp == 0)) { |
| cp++; |
| res += 8; |
| } |
| d0 = ffs(*cp); |
| if (d0 == 0) |
| return size; |
| |
| return res + d0 - 1; |
| } |
| |
| int ext2fs_find_next_bit_set (void * addr, int size, int offset) |
| { |
| unsigned char * p; |
| int set = 0, bit = offset & 7, res = 0, d0; |
| |
| res = offset >> 3; |
| p = ((unsigned char *) addr) + res; |
| |
| if (bit) { |
| set = ffs(*p & ~((1 << bit) - 1)); |
| if (set) |
| return (offset & ~7) + set - 1; |
| p++; |
| res += 8; |
| } |
| while ((size > res) && (*p == 0)) { |
| p++; |
| res += 8; |
| } |
| d0 = ffs(*p); |
| if (d0 == 0) |
| return size; |
| |
| return (res + d0 - 1); |
| } |
| |
| int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, |
| blk_t bitno); |
| |
| int ext2fs_test_generic_bitmap(ext2fs_generic_bitmap bitmap, |
| blk_t bitno) |
| { |
| if ((bitno < bitmap->start) || (bitno > bitmap->end)) { |
| ext2fs_warn_bitmap2(bitmap, EXT2FS_TEST_ERROR, bitno); |
| return 0; |
| } |
| return ext2fs_test_bit(bitno - bitmap->start, bitmap->bitmap); |
| } |
| |
| int ext2fs_mark_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) |
| bitmap, |
| block); |
| } |
| |
| int ext2fs_unmark_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, |
| block); |
| } |
| |
| int ext2fs_test_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, |
| block); |
| } |
| |
| int ext2fs_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| return ext2fs_mark_generic_bitmap((ext2fs_generic_bitmap) bitmap, |
| inode); |
| } |
| |
| int ext2fs_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| return ext2fs_unmark_generic_bitmap((ext2fs_generic_bitmap) bitmap, |
| inode); |
| } |
| |
| int ext2fs_test_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| return ext2fs_test_generic_bitmap((ext2fs_generic_bitmap) bitmap, |
| inode); |
| } |
| |
| void ext2fs_fast_mark_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, |
| bitmap->description); |
| return; |
| } |
| #endif |
| ext2fs_set_bit(block - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_fast_unmark_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, |
| block, bitmap->description); |
| return; |
| } |
| #endif |
| ext2fs_clear_bit(block - bitmap->start, bitmap->bitmap); |
| } |
| |
| int ext2fs_fast_test_block_bitmap(ext2fs_block_bitmap bitmap, |
| blk_t block) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, |
| block, bitmap->description); |
| return 0; |
| } |
| #endif |
| return ext2fs_test_bit(block - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_fast_mark_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((inode < bitmap->start) || (inode > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_MARK, |
| inode, bitmap->description); |
| return; |
| } |
| #endif |
| ext2fs_set_bit(inode - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_fast_unmark_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((inode < bitmap->start) || (inode > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_UNMARK, |
| inode, bitmap->description); |
| return; |
| } |
| #endif |
| ext2fs_clear_bit(inode - bitmap->start, bitmap->bitmap); |
| } |
| |
| int ext2fs_fast_test_inode_bitmap(ext2fs_inode_bitmap bitmap, |
| ext2_ino_t inode) |
| { |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((inode < bitmap->start) || (inode > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_INODE_TEST, |
| inode, bitmap->description); |
| return 0; |
| } |
| #endif |
| return ext2fs_test_bit(inode - bitmap->start, bitmap->bitmap); |
| } |
| |
| blk_t ext2fs_get_block_bitmap_start(ext2fs_block_bitmap bitmap) |
| { |
| return bitmap->start; |
| } |
| |
| ext2_ino_t ext2fs_get_inode_bitmap_start(ext2fs_inode_bitmap bitmap) |
| { |
| return bitmap->start; |
| } |
| |
| blk_t ext2fs_get_block_bitmap_end(ext2fs_block_bitmap bitmap) |
| { |
| return bitmap->end; |
| } |
| |
| ext2_ino_t ext2fs_get_inode_bitmap_end(ext2fs_inode_bitmap bitmap) |
| { |
| return bitmap->end; |
| } |
| |
| int ext2fs_test_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, |
| block, bitmap->description); |
| return 0; |
| } |
| for (i=0; i < num; i++) { |
| if (ext2fs_fast_test_block_bitmap(bitmap, block+i)) |
| return 0; |
| } |
| return 1; |
| } |
| |
| int ext2fs_fast_test_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_TEST, |
| block, bitmap->description); |
| return 0; |
| } |
| #endif |
| for (i=0; i < num; i++) { |
| if (ext2fs_fast_test_block_bitmap(bitmap, block+i)) |
| return 0; |
| } |
| return 1; |
| } |
| |
| void ext2fs_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, |
| bitmap->description); |
| return; |
| } |
| for (i=0; i < num; i++) |
| ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_fast_mark_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_MARK, block, |
| bitmap->description); |
| return; |
| } |
| #endif |
| for (i=0; i < num; i++) |
| ext2fs_set_bit(block + i - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, |
| bitmap->description); |
| return; |
| } |
| for (i=0; i < num; i++) |
| ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap); |
| } |
| |
| void ext2fs_fast_unmark_block_bitmap_range(ext2fs_block_bitmap bitmap, |
| blk_t block, int num) |
| { |
| int i; |
| |
| #ifdef EXT2FS_DEBUG_FAST_OPS |
| if ((block < bitmap->start) || (block+num-1 > bitmap->end)) { |
| ext2fs_warn_bitmap(EXT2_ET_BAD_BLOCK_UNMARK, block, |
| bitmap->description); |
| return; |
| } |
| #endif |
| for (i=0; i < num; i++) |
| ext2fs_clear_bit(block + i - bitmap->start, bitmap->bitmap); |
| } |