| /* |
| * Copyright 2000-2004 by Hans Reiser, licensing governed by |
| * reiserfsprogs/README |
| */ |
| |
| /* |
| * 2000/10/26 - Initial version. |
| */ |
| |
| #include "includes.h" |
| #include <assert.h> |
| |
| |
| /* create clean bitmap */ |
| reiserfs_bitmap_t * reiserfs_create_bitmap (unsigned int bit_count) |
| { |
| reiserfs_bitmap_t * bm; |
| |
| bm = getmem (sizeof (*bm)); |
| if (!bm) |
| return 0; |
| bm->bm_bit_size = bit_count; |
| bm->bm_byte_size = ((unsigned long long)bit_count + 7) / 8; |
| bm->bm_set_bits = 0; |
| bm->bm_map = getmem (bm->bm_byte_size); |
| if (!bm->bm_map) { |
| freemem (bm); |
| return 0; |
| } |
| |
| return bm; |
| } |
| |
| /* Expand existing bitmap. Return non-zero if can't. FIXME: it is |
| assumed that bit_count is new number of blocks to be addressed */ |
| int reiserfs_expand_bitmap (reiserfs_bitmap_t * bm, unsigned int bit_count) |
| { |
| unsigned int byte_count = ((bit_count + 7) / 8); |
| char * new_map; |
| |
| new_map = expandmem (bm->bm_map, bm->bm_byte_size, |
| byte_count - bm->bm_byte_size); |
| |
| if (!new_map) { |
| return 1; |
| } |
| |
| bm->bm_map = new_map; |
| bm->bm_byte_size = byte_count; |
| bm->bm_bit_size = bit_count; |
| |
| bm->bm_dirty = 1; |
| |
| return 0; |
| } |
| |
| void reiserfs_shrink_bitmap (reiserfs_bitmap_t * bm, unsigned int bit_count) |
| { |
| unsigned long i; |
| |
| assert (bm->bm_bit_size >= bit_count); |
| |
| bm->bm_byte_size = (bit_count + 7) / 8; |
| bm->bm_bit_size = bit_count; |
| bm->bm_set_bits = 0; |
| |
| bm->bm_dirty = 1; |
| |
| for (i = 0; i < bm->bm_bit_size; i++) { |
| if (reiserfs_bitmap_test_bit(bm, i)) |
| bm->bm_set_bits++; |
| } |
| } |
| |
| /* bitmap destructor */ |
| void reiserfs_delete_bitmap (reiserfs_bitmap_t * bm) |
| { |
| freemem(bm->bm_map); |
| bm->bm_map = NULL; /* to not reuse bitmap handle */ |
| bm->bm_bit_size = 0; |
| bm->bm_byte_size = 0; |
| freemem(bm); |
| } |
| |
| |
| void reiserfs_bitmap_copy (reiserfs_bitmap_t * to, reiserfs_bitmap_t * from) |
| { |
| assert (to->bm_byte_size == from->bm_byte_size); |
| memcpy (to->bm_map, from->bm_map, from->bm_byte_size); |
| to->bm_bit_size = from->bm_bit_size; |
| to->bm_set_bits = from->bm_set_bits; |
| to->bm_dirty = 1; |
| } |
| |
| int reiserfs_bitmap_compare (reiserfs_bitmap_t * bm1, reiserfs_bitmap_t * bm2) |
| { |
| unsigned long i, diff; |
| unsigned long int bytes, bits; |
| |
| assert (bm1->bm_byte_size == bm2->bm_byte_size && |
| bm1->bm_bit_size == bm2->bm_bit_size); |
| |
| diff = 0; |
| |
| /* compare full bytes */ |
| bytes = bm1->bm_bit_size / 8; |
| bits = bytes * 8; |
| if (memcmp (bm1->bm_map, bm2->bm_map, bytes)) { |
| for (i = 0; i < bits; i ++) |
| if (reiserfs_bitmap_test_bit(bm1, i) != reiserfs_bitmap_test_bit(bm2, i)) |
| diff ++; |
| } |
| |
| /* compare last byte of bitmap which can be used partially */ |
| bits = bm1->bm_bit_size % 8; |
| for (i = bm1->bm_bit_size / 8 * 8; i < bm1->bm_bit_size / 8 * 8 + bits; i ++) |
| if (reiserfs_bitmap_test_bit(bm1, i) != reiserfs_bitmap_test_bit(bm2, i)) |
| diff ++; |
| |
| /* int mask; |
| |
| mask = 255 >> (8 - bits); |
| if ((bm1->bm_map [bytes] & mask) != (bm2->bm_map [bytes] & mask)) { |
| diff ++; |
| } |
| }*/ |
| return diff; |
| } |
| |
| /* |
| Does X | Y for every bit of the bitmap `to`, where |
| X - bit of the `to` bitmap, |
| Y - `from` bitmap. |
| Save result in the `to` bitmap. |
| */ |
| void reiserfs_bitmap_disjunction (reiserfs_bitmap_t * to, |
| reiserfs_bitmap_t * from) |
| { |
| unsigned int i; |
| |
| assert (to->bm_byte_size == from->bm_byte_size && |
| to->bm_bit_size == from->bm_bit_size); |
| |
| for (i = 0; i < to->bm_bit_size; i++) { |
| if (misc_test_bit(i, from->bm_map) && !misc_test_bit(i, to->bm_map)) { |
| misc_set_bit(i, to->bm_map); |
| to->bm_set_bits ++; |
| to->bm_dirty = 1; |
| } |
| } |
| } |
| |
| /* |
| Does X & !Y for every bit of the bitmap `base`, where |
| X - bit of the `base` bitmap, |
| Y - `exclude` bitmap. |
| Save result in the `base` bitmap. |
| */ |
| void reiserfs_bitmap_delta (reiserfs_bitmap_t * base, reiserfs_bitmap_t * exclude) { |
| unsigned int i; |
| |
| assert (base->bm_byte_size == exclude->bm_byte_size && |
| base->bm_bit_size == exclude->bm_bit_size); |
| |
| for (i = 0; i < base->bm_bit_size; i++) { |
| if (misc_test_bit(i, exclude->bm_map) && misc_test_bit(i, base->bm_map)) { |
| misc_clear_bit(i, base->bm_map); |
| base->bm_set_bits --; |
| base->bm_dirty = 1; |
| } |
| } |
| } |
| |
| void reiserfs_bitmap_set_bit (reiserfs_bitmap_t * bm, unsigned int bit_number) |
| { |
| assert(bit_number < bm->bm_bit_size); |
| if (misc_test_bit (bit_number, bm->bm_map)) |
| return; |
| misc_set_bit(bit_number, bm->bm_map); |
| bm->bm_set_bits ++; |
| bm->bm_dirty = 1; |
| } |
| |
| |
| void reiserfs_bitmap_clear_bit (reiserfs_bitmap_t * bm, unsigned int bit_number) |
| { |
| assert(bit_number < bm->bm_bit_size); |
| if (!misc_test_bit (bit_number, bm->bm_map)) |
| return; |
| misc_clear_bit (bit_number, bm->bm_map); |
| bm->bm_set_bits --; |
| bm->bm_dirty = 1; |
| } |
| |
| |
| int reiserfs_bitmap_test_bit (reiserfs_bitmap_t * bm, unsigned int bit_number) |
| { |
| if (bit_number >= bm->bm_bit_size) |
| printf ("bit %u, bitsize %lu\n", bit_number, bm->bm_bit_size); |
| assert(bit_number < bm->bm_bit_size); |
| return misc_test_bit(bit_number, bm->bm_map); |
| } |
| |
| |
| unsigned int reiserfs_bitmap_zeros (reiserfs_bitmap_t * bm) { |
| return bm->bm_bit_size - bm->bm_set_bits; |
| } |
| |
| |
| unsigned int reiserfs_bitmap_ones (reiserfs_bitmap_t * bm) { |
| return bm->bm_set_bits; |
| } |
| |
| |
| int reiserfs_bitmap_find_zero_bit (reiserfs_bitmap_t * bm, unsigned long * first) |
| { |
| unsigned long bit_nr = *first; |
| assert(*first < bm->bm_bit_size); |
| |
| bit_nr = misc_find_next_zero_bit(bm->bm_map, bm->bm_bit_size, *first); |
| |
| if (bit_nr >= bm->bm_bit_size) { /* search failed */ |
| return 1; |
| } |
| |
| *first = bit_nr; |
| return 0; |
| } |
| |
| |
| /* read every bitmap block and copy their content into bitmap 'bm' */ |
| static int reiserfs_fetch_ondisk_bitmap (reiserfs_bitmap_t * bm, reiserfs_filsys_t * fs) |
| { |
| unsigned int last_byte_unused_bits; |
| unsigned long block, to_copy; |
| struct buffer_head * bh; |
| unsigned int i; |
| int copied; |
| int ret = 0; |
| char * p; |
| |
| to_copy = (get_sb_block_count (fs->fs_ondisk_sb) + 7) / 8; |
| |
| /*reiserfs_warning (stderr, "Fetching on-disk bitmap..");*/ |
| assert (bm->bm_byte_size == to_copy); |
| |
| copied = fs->fs_blocksize; |
| p = bm->bm_map; |
| block = fs->fs_super_bh->b_blocknr + 1; |
| |
| while (to_copy) { |
| bh = bread (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_warning (stderr, "reiserfs_fetch_ondisk_bitmap: " |
| "bread failed reading bitmap (%lu)\n", block); |
| |
| bh = getblk (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_exit (1, "reiserfs_fetch_ondisk_bitmap: " |
| "getblk failed"); |
| } |
| |
| memset (bh->b_data, 0xff, bh->b_size); |
| mark_buffer_uptodate (bh, 1); |
| } |
| |
| if (to_copy < fs->fs_blocksize) { |
| for (i = to_copy; i < fs->fs_blocksize; i++) { |
| if (bh->b_data[i] != (char)0xff) { |
| ret = 1; |
| break; |
| } |
| } |
| |
| copied = to_copy; |
| } |
| memcpy (p, bh->b_data, copied); |
| brelse (bh); |
| p += copied; |
| to_copy -= copied; |
| |
| /* next bitmap block */ |
| if (spread_bitmaps (fs)) |
| block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); |
| else |
| block ++; |
| } |
| |
| /* on disk bitmap has bits out of SB_BLOCK_COUNT set to 1, where as |
| reiserfs_bitmap_t has those bits set to 0 */ |
| last_byte_unused_bits = bm->bm_byte_size * 8 - bm->bm_bit_size; |
| |
| for (i = 0; i < last_byte_unused_bits; i ++) { |
| if (misc_test_bit (bm->bm_bit_size + i, bm->bm_map) == 0) |
| ret = 1; |
| else |
| misc_clear_bit (bm->bm_bit_size + i, bm->bm_map); |
| } |
| |
| bm->bm_set_bits = 0; |
| /* FIXME: optimize that */ |
| for (i = 0; i < bm->bm_bit_size; i ++) |
| if (reiserfs_bitmap_test_bit (bm, i)) |
| bm->bm_set_bits ++; |
| |
| bm->bm_dirty = 0; |
| |
| return ret; |
| } |
| |
| |
| /* copy bitmap 'bm' to buffers which hold on-disk bitmap if bitmap was ever |
| changed and return 1. Otherwise - return 0 */ |
| int reiserfs_flush_to_ondisk_bitmap (reiserfs_bitmap_t * bm, reiserfs_filsys_t * fs) |
| { |
| unsigned int last_byte_unused_bits, i; |
| unsigned long to_copy, copied, block; |
| struct buffer_head * bh; |
| char * p; |
| |
| /* make sure that the device is big enough */ |
| bh = bread (fs->fs_dev, bm->bm_bit_size - 1, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_warning (stderr, "reiserfs_flush_to_ondisk_bitmap: bread failed for block %lu\n", |
| bm->bm_bit_size - 1); |
| /* |
| bh = getblk (fs->fs_dev, bm->bm_bit_size - 1, fs->fs_blocksize); |
| if (!bh) |
| reiserfs_panic ("reiserfs_flush_to_ondisk_bitmap: getblk failed"); |
| mark_buffer_uptodate (bh, 1); |
| mark_buffer_dirty (bh); |
| bwrite (bh);*/ |
| } |
| brelse (bh); |
| |
| if (!bm->bm_dirty) |
| return 0; |
| |
| to_copy = bm->bm_byte_size; |
| |
| copied = fs->fs_blocksize; |
| p = bm->bm_map; |
| block = fs->fs_super_bh->b_blocknr + 1; |
| |
| while (to_copy) { |
| /* we bread to make sure that filesystem contains enough blocks */ |
| bh = getblk (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_exit (1, "Getblk failed for (%lu)\n", block); |
| } |
| |
| memset (bh->b_data, 0xff, bh->b_size); |
| mark_buffer_uptodate (bh, 1); |
| |
| if (to_copy < fs->fs_blocksize) |
| copied = to_copy; |
| memcpy (bh->b_data, p, copied); |
| if (copied == to_copy) { |
| /* set unused bits of last byte of a bitmap to 1 */ |
| last_byte_unused_bits = bm->bm_byte_size * 8 - bm->bm_bit_size; |
| |
| for (i = 0; i < last_byte_unused_bits; i ++) |
| misc_set_bit ((bm->bm_bit_size % (fs->fs_blocksize * 8)) + i, bh->b_data); |
| } |
| mark_buffer_dirty (bh); |
| brelse (bh); |
| p += copied; |
| to_copy -= copied; |
| |
| /* next bitmap block */ |
| if (spread_bitmaps (fs)) |
| block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); |
| else |
| block ++; |
| } |
| |
| |
| return 1; |
| } |
| |
| |
| void reiserfs_bitmap_zero (reiserfs_bitmap_t * bm) |
| { |
| memset (bm->bm_map, 0, bm->bm_byte_size); |
| bm->bm_set_bits = 0; |
| bm->bm_dirty = 1; |
| } |
| |
| |
| void reiserfs_bitmap_fill (reiserfs_bitmap_t * bm) |
| { |
| memset (bm->bm_map, 0xff, bm->bm_byte_size); |
| bm->bm_set_bits = bm->bm_bit_size; |
| bm->bm_dirty = 1; |
| } |
| |
| |
| /* format of bitmap saved in a file: |
| magic number (32 bits) |
| bm_bit_size (32 bits) |
| number of ranges of used and free blocks (32 bits) |
| number of contiguously used block, .. of free blocks, used, free, etc |
| magic number (32 bits) */ |
| |
| #define BITMAP_START_MAGIC 374031 |
| #define BITMAP_END_MAGIC 7786472 |
| |
| |
| FILE * open_file (char * filename, char * option) |
| { |
| FILE * fp = fopen (filename, option); |
| if (!fp) { |
| reiserfs_warning (stderr, "open_file: could not open file %s\n", filename); |
| return 0; |
| } |
| reiserfs_warning (stderr, "Temp file opened by fsck: \"%s\" .. \n", filename); |
| return fp; |
| } |
| |
| |
| void close_file (FILE * fp) |
| { |
| fclose (fp); |
| /*reiserfs_warning (stderr, "done\n"); fflush (stderr);*/ |
| } |
| |
| |
| void reiserfs_bitmap_save (FILE * fp, reiserfs_bitmap_t * bm) |
| { |
| // FILE * fp; |
| __u32 v; |
| int zeros; |
| int count; |
| unsigned int i; |
| int extents; |
| long position; |
| |
| /* fp = fopen (filename, "w+"); |
| if (!fp) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_save: could not save bitmap in %s: %s", |
| filename, strerror(errno)); |
| return; |
| }*/ |
| |
| |
| // reiserfs_warning (stderr, "Saving bitmap in \"%s\" .. ", filename); fflush (stderr); |
| |
| |
| |
| v = BITMAP_START_MAGIC; |
| fwrite (&v, 4, 1, fp); |
| |
| v = bm->bm_bit_size; |
| fwrite (&v, 4, 1, fp); |
| |
| /*printf ("SAVE: bit_size - %d\n", v);*/ |
| |
| position = ftell(fp); |
| |
| if (fseek (fp, 4, SEEK_CUR)) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_save: fseek failed: %s\n", strerror(errno)); |
| // fclose (fp); |
| return; |
| } |
| |
| zeros = 0; |
| count = 0; |
| extents = 0; |
| for (i = 0; i < v; i ++) { |
| if (reiserfs_bitmap_test_bit (bm, i)) { |
| if (zeros) { |
| /* previous bit was not set, write amount of not set |
| bits, switch to count set bits */ |
| fwrite (&count, 4, 1, fp); |
| /*printf ("SAVE: Free %d\n", count);*/ |
| extents ++; |
| count = 1; |
| zeros = 0; |
| } else { |
| /* one more zero bit appeared */ |
| count ++; |
| } |
| } else { |
| /* zero bit found */ |
| if (zeros) { |
| count ++; |
| } else { |
| /* previous bit was set, write amount of set bits, |
| switch to count not set bits */ |
| fwrite (&count, 4, 1, fp); |
| /*printf ("SAVE: Used %d\n", count);*/ |
| extents ++; |
| count = 1; |
| zeros = 1; |
| } |
| } |
| } |
| |
| fwrite (&count, 4, 1, fp); |
| extents ++; |
| /* |
| if (zeros) |
| printf ("SAVE: Free %d\n", count); |
| else |
| printf ("SAVE: Used %d\n", count); |
| */ |
| |
| v = BITMAP_END_MAGIC; |
| fwrite (&v, 4, 1, fp); |
| |
| if (fseek (fp, position, SEEK_SET)) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_save: fseek failed: %s", strerror(errno)); |
| return; |
| } |
| |
| fwrite (&extents, 4, 1, fp); |
| |
| if (fseek (fp, 0, SEEK_END)) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_save: fseek failed: %s", strerror(errno)); |
| return; |
| } |
| } |
| |
| |
| /* format of fsck dump file: |
| after pass0 |
| magic number (32 bits) |
| passed stage number |
| bitmap of leaves |
| bitmap of good_unfm |
| bitmap of bad_unfm |
| magic number (32 bits) */ |
| |
| #define FSCK_DUMP_START_MAGIC 374033 |
| #define FSCK_DUMP_END_MAGIC 7786470 |
| |
| |
| void reiserfs_begin_stage_info_save(FILE * file, unsigned long stage) |
| { |
| __u32 v = FSCK_DUMP_START_MAGIC; |
| fwrite (&v, 4, 1, file); |
| fwrite (&stage, 4, 1, file); |
| } |
| |
| |
| void reiserfs_end_stage_info_save(FILE * file) |
| { |
| __u32 v = FSCK_DUMP_END_MAGIC; |
| fwrite (&v, 4, 1, file); |
| } |
| |
| |
| /*return last passed stage*/ |
| int is_stage_magic_correct (FILE * fp) |
| { |
| __u32 v; |
| |
| if (fseek (fp, -4, SEEK_END)) { |
| reiserfs_warning (stderr, "is_stage_magic_correct: fseek failed: %s\n", |
| strerror(errno)); |
| return -1; |
| } |
| |
| fread (&v, 4, 1, fp); |
| if (v != FSCK_DUMP_END_MAGIC) { |
| reiserfs_warning (stderr, "is_stage_magic_correct: no magic found\n"); |
| return -1; |
| } |
| |
| if (fseek (fp, 0, SEEK_SET)) { |
| reiserfs_warning (stderr, "is_stage_magic_correct: fseek failed: %s\n", |
| strerror(errno)); |
| return -1; |
| } |
| |
| fread (&v, 4, 1, fp); |
| if (v != FSCK_DUMP_START_MAGIC) { |
| reiserfs_warning (stderr, "is_stage_magic_correct: no magic found\n"); |
| return -1; |
| } |
| |
| fread (&v, 4, 1, fp); |
| if (v != PASS_0_DONE && v != PASS_1_DONE && v != TREE_IS_BUILT && v != SEMANTIC_DONE && v != LOST_FOUND_DONE) { |
| reiserfs_warning (stderr, "is_stage_magic_correct: wrong pass found"); |
| return -1; |
| } |
| |
| return (__u16)v; |
| } |
| |
| |
| reiserfs_bitmap_t * reiserfs_bitmap_load (FILE * fp) |
| { |
| // FILE * fp; |
| __u32 v; |
| int count; |
| int i, j; |
| int extents; |
| int bit; |
| reiserfs_bitmap_t * bm; |
| |
| /* fp = fopen (filename, "r"); |
| if (!fp) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_load: fopen failed: %s\n", strerror(errno)); |
| return 0; |
| }*/ |
| |
| fread (&v, 4, 1, fp); |
| if (v != BITMAP_START_MAGIC) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_load: " |
| "no bitmap start magic found"); |
| // fclose (fp); |
| return 0; |
| } |
| |
| /* read bit size of bitmap */ |
| fread (&v, 4, 1, fp); |
| |
| bm = reiserfs_create_bitmap (v); |
| if (!bm) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_load: creation failed"); |
| // fclose (fp); |
| return 0; |
| } |
| |
| /*printf ("LOAD: bit_size - %d\n", v);*/ |
| |
| fread (&extents, 4, 1, fp); |
| |
| /*printf ("LOAD: extents - %d\n", extents);*/ |
| |
| bit = 0; |
| for (i = 0; i < extents; i ++) { |
| fread (&count, 4, 1, fp); |
| /* |
| if (i % 2) |
| printf ("LOAD: Free %d\n", count); |
| else |
| printf ("LOAD: Used %d\n", count); |
| */ |
| for (j = 0; j < count; j ++, bit ++) |
| if (i % 2 == 0) { |
| reiserfs_bitmap_set_bit (bm, bit); |
| } |
| } |
| |
| fread (&v, 4, 1, fp); |
| |
| /*printf ("LOAD: Endmagic %d\n", v);*/ |
| |
| // fclose (fp); |
| if (v != BITMAP_END_MAGIC) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_load: " |
| "no bitmap end magic found"); |
| return 0; |
| } |
| |
| /* reiserfs_warning (stderr, "%d bits set - done\n", reiserfs_bitmap_ones (bm));*/ |
| fflush (stderr); |
| return bm; |
| } |
| |
| |
| void reiserfs_bitmap_invert (reiserfs_bitmap_t * bm) |
| { |
| unsigned int i; |
| |
| /*reiserfs_warning (stderr, "Bitmap inverting..");fflush (stderr);*/ |
| for (i = 0; i < bm->bm_bit_size; i ++) { |
| if (reiserfs_bitmap_test_bit (bm, i)) |
| reiserfs_bitmap_clear_bit (bm, i); |
| else |
| reiserfs_bitmap_set_bit (bm, i); |
| } |
| |
| /*reiserfs_warning (stderr, "done\n");*/ |
| } |
| |
| |
| void reiserfs_free_ondisk_bitmap (reiserfs_filsys_t * fs) |
| { |
| if (fs->fs_bitmap2) { |
| reiserfs_delete_bitmap (fs->fs_bitmap2); |
| fs->fs_bitmap2 = 0; |
| } |
| } |
| |
| /* read bitmap blocks */ |
| int reiserfs_open_ondisk_bitmap (reiserfs_filsys_t * fs) |
| { |
| unsigned int blocks = get_sb_block_count(fs->fs_ondisk_sb) ; |
| unsigned int bmap_nr = reiserfs_bmap_nr(blocks, fs->fs_blocksize); |
| |
| if (fs->fs_bitmap2) |
| reiserfs_panic ("bitmap is initiaized already"); |
| |
| fs->fs_bitmap2 = reiserfs_create_bitmap (blocks); |
| if (!fs->fs_bitmap2) |
| return -1; |
| |
| if (reiserfs_bmap_over(bmap_nr)) { |
| if (get_sb_bmap_nr(fs->fs_ondisk_sb) != 0) { |
| reiserfs_warning (stderr, "%s: large file system has " |
| "incorrect bitmap count %u. Should be 0 " |
| "to indicate overflow.\nPlease re-run with " |
| "--rebuild-sb to fix it.\n", __FUNCTION__, |
| get_sb_bmap_nr(fs->fs_ondisk_sb)); |
| return -1; |
| } |
| } else if (bmap_nr != get_sb_bmap_nr (fs->fs_ondisk_sb)) { |
| reiserfs_warning (stderr, "%s: wrong either bitmaps number,\n", |
| __FUNCTION__); |
| reiserfs_warning (stderr, "count of blocks or blocksize, run with " |
| "--rebuild-sb to fix it\n"); |
| return -1; |
| } |
| |
| return reiserfs_fetch_ondisk_bitmap (fs->fs_bitmap2, fs); |
| } |
| |
| int reiserfs_create_ondisk_bitmap (reiserfs_filsys_t * fs) |
| { |
| if (fs->fs_bitmap2) |
| reiserfs_panic ("bitmap is initiaized already"); |
| |
| fs->fs_bitmap2 = reiserfs_create_bitmap (get_sb_block_count (fs->fs_ondisk_sb)); |
| if (!fs->fs_bitmap2) |
| return 0; |
| |
| return 1; |
| } |
| |
| void reiserfs_close_ondisk_bitmap (reiserfs_filsys_t * fs) |
| { |
| if (!fs->fs_bitmap2) |
| return; |
| reiserfs_flush_to_ondisk_bitmap (fs->fs_bitmap2, fs); |
| reiserfs_free_ondisk_bitmap (fs); |
| } |