| /* |
| * Copyright 2000-2004 by Hans Reiser, licensing governed by |
| * reiserfsprogs/README |
| */ |
| |
| #ifdef HAVE_CONFIG_H |
| # include <config.h> |
| #endif |
| |
| #include "reiserfs/libreiserfs.h" |
| #include "misc/malloc.h" |
| |
| #include <assert.h> |
| #include <errno.h> |
| |
| /* create clean bitmap */ |
| reiserfs_bitmap_t * reiserfs_bitmap_create (unsigned int bit_count) |
| { |
| reiserfs_bitmap_t * bm; |
| |
| bm = misc_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_map = misc_getmem (bm->bm_byte_size); |
| if (!bm->bm_map) { |
| misc_freemem (bm); |
| return 0; |
| } |
| |
| return bm; |
| } |
| |
| /* read every bitmap block and copy their content into bitmap 'bm' */ |
| static int reiserfs_bitmap_fetch (reiserfs_bitmap_t * bm, |
| reiserfs_filsys_t * fs) |
| { |
| unsigned int last_byte_unused_bits; |
| unsigned long block, to_copy; |
| reiserfs_bh_t * bh; |
| unsigned int i; |
| int copied; |
| int ret = 0; |
| char * p; |
| |
| to_copy = (reiserfs_sb_get_blocks (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 = reiserfs_buffer_read (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_fetch: " |
| "reiserfs_buffer_read failed reading bitmap " |
| "(%lu)\n", block); |
| |
| bh = reiserfs_buffer_open (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_exit (1, "reiserfs_bitmap_fetch: " |
| "reiserfs_buffer_open failed"); |
| } |
| |
| memset (bh->b_data, 0xff, bh->b_size); |
| reiserfs_buffer_mkuptodate (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); |
| reiserfs_buffer_close (bh); |
| p += copied; |
| to_copy -= copied; |
| |
| /* next bitmap block */ |
| if (reiserfs_bitmap_spread (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; |
| } |
| |
| /* read bitmap blocks */ |
| int reiserfs_bitmap_open (reiserfs_filsys_t * fs) { |
| unsigned int bmap_nr, count; |
| |
| if (fs->fs_bitmap2) |
| reiserfs_panic ("bitmap is initiaized already"); |
| |
| count = reiserfs_sb_get_blocks (fs->fs_ondisk_sb); |
| |
| fs->fs_bitmap2 = reiserfs_bitmap_create (count); |
| |
| if (!fs->fs_bitmap2) |
| return -1; |
| |
| bmap_nr = reiserfs_bmap_nr(count, fs->fs_blocksize); |
| bmap_nr = reiserfs_bmap_over(bmap_nr) ? 0 : bmap_nr; |
| |
| if (bmap_nr != reiserfs_sb_get_bmaps (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_bitmap_fetch (fs->fs_bitmap2, fs); |
| } |
| |
| /* bitmap destructor */ |
| void reiserfs_bitmap_delete (reiserfs_bitmap_t * bm) |
| { |
| misc_freemem(bm->bm_map); |
| bm->bm_map = NULL; /* to not reuse bitmap handle */ |
| bm->bm_bit_size = 0; |
| bm->bm_byte_size = 0; |
| misc_freemem(bm); |
| } |
| |
| void reiserfs_bitmap_free (reiserfs_filsys_t * fs) |
| { |
| if (fs->fs_bitmap2) { |
| reiserfs_bitmap_delete (fs->fs_bitmap2); |
| fs->fs_bitmap2 = 0; |
| } |
| } |
| |
| void reiserfs_bitmap_close (reiserfs_filsys_t * fs) |
| { |
| if (!fs->fs_bitmap2) |
| return; |
| reiserfs_bitmap_flush (fs->fs_bitmap2, fs); |
| reiserfs_bitmap_free (fs); |
| } |
| |
| /* copy bitmap 'bm' to buffers which hold on-disk bitmap if bitmap was ever |
| changed and return 1. Otherwise - return 0 */ |
| int reiserfs_bitmap_flush (reiserfs_bitmap_t * bm, reiserfs_filsys_t * fs) |
| { |
| unsigned int last_byte_unused_bits, i; |
| unsigned long to_copy, copied, block; |
| reiserfs_bh_t * bh; |
| char * p; |
| |
| /* make sure that the device is big enough */ |
| bh = reiserfs_buffer_read (fs->fs_dev, bm->bm_bit_size - 1, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_flush: reiserfs_buffer_read " |
| "failed for block %lu\n", bm->bm_bit_size - 1); |
| /* |
| bh = reiserfs_buffer_open (fs->fs_dev, bm->bm_bit_size - 1, |
| fs->fs_blocksize); |
| if (!bh) |
| reiserfs_panic ("reiserfs_bitmap_flush: reiserfs_buffer_open failed"); |
| reiserfs_buffer_mkuptodate (bh, 1); |
| reiserfs_buffer_mkdirty (bh); |
| reiserfs_buffer_write (bh);*/ |
| } |
| reiserfs_buffer_close (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 reiserfs_buffer_read to make sure that filesystem contains |
| enough blocks */ |
| bh = reiserfs_buffer_open (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); |
| reiserfs_buffer_mkuptodate (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); |
| } |
| |
| reiserfs_buffer_mkdirty (bh); |
| reiserfs_buffer_close (bh); |
| p += copied; |
| to_copy -= copied; |
| |
| /* next bitmap block */ |
| if (reiserfs_bitmap_spread (fs)) |
| block = (block / (fs->fs_blocksize * 8) + 1) * |
| (fs->fs_blocksize * 8); |
| else |
| block ++; |
| } |
| |
| |
| return 1; |
| } |
| |
| /* 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_bitmap_expand (reiserfs_bitmap_t * bm, |
| unsigned int bit_count) |
| { |
| unsigned int byte_count = ((bit_count + 7) / 8); |
| char * new_map; |
| |
| new_map = misc_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_bitmap_shrink (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; |
| if (bm->bm_first_zero > bm->bm_bit_size) |
| bm->bm_first_zero = bm->bm_bit_size; |
| |
| bm->bm_dirty = 1; |
| |
| for (i = 0; i < bm->bm_bit_size; i++) { |
| if (reiserfs_bitmap_test_bit(bm, i)) |
| bm->bm_set_bits++; |
| } |
| } |
| |
| 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_first_zero = from->bm_first_zero; |
| 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; |
| if (bm->bm_first_zero > bit_number) |
| bm->bm_first_zero = bit_number; |
| } |
| |
| |
| 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); |
| } |
| |
| |
| int reiserfs_bitmap_find_zero_bit (reiserfs_bitmap_t * bm, |
| unsigned long * first) |
| { |
| unsigned long bit_nr; |
| int upd; |
| |
| assert(*first < bm->bm_bit_size); |
| |
| upd = (bm->bm_first_zero >= *first) ? 1 : 0; |
| bit_nr = misc_find_next_zero_bit(bm->bm_map, bm->bm_bit_size, |
| upd ? bm->bm_first_zero : *first); |
| |
| if (upd) |
| bm->bm_first_zero = bit_nr; |
| |
| if (bit_nr >= bm->bm_bit_size) |
| /* search failed */ |
| return 1; |
| |
| *first = bit_nr; |
| return 0; |
| } |
| |
| 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; |
| bm->bm_first_zero = 0; |
| } |
| |
| |
| 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; |
| bm->bm_first_zero = bm->bm_set_bits; |
| } |
| |
| 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");*/ |
| } |
| |
| 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_spread (reiserfs_filsys_t * fs) { |
| return fs->fs_super_bh->b_blocknr != 2; |
| } |
| |
| /* 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 |
| |
| 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) */ |
| |
| |
| |
| 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_bitmap_create (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; |
| } |
| |
| |
| int reiserfs_bitmap_block (reiserfs_filsys_t * fs, unsigned long block) { |
| unsigned int bmap_nr; |
| |
| if (reiserfs_bitmap_spread (fs)) { |
| if (!(block % (fs->fs_blocksize * 8))) |
| /* bitmap block */ |
| return 1; |
| return ((REISERFS_DISK_OFFSET_IN_BYTES / fs->fs_blocksize + 1) |
| == block); |
| } else { |
| bmap_nr = reiserfs_bmap_nr(reiserfs_sb_get_blocks(fs->fs_ondisk_sb), |
| fs->fs_blocksize); |
| |
| /* bitmap in */ |
| return (block > 2ul && block < 3ul + bmap_nr) ? 1 : 0; |
| } |
| |
| return 0; |
| } |
| |
| /* read bitmap of disk and print details */ |
| void reiserfs_bitmap_print (FILE * fp, reiserfs_filsys_t * fs, int silent) |
| { |
| reiserfs_sb_t * sb; |
| int bmap_nr; |
| int i; |
| int bits_per_block; |
| int blocks; |
| unsigned long block; |
| reiserfs_bh_t * bh; |
| |
| |
| sb = fs->fs_ondisk_sb; |
| bits_per_block = fs->fs_blocksize * 8; |
| blocks = bits_per_block; |
| bmap_nr = reiserfs_bmap_nr(reiserfs_sb_get_blocks(fs->fs_ondisk_sb), |
| fs->fs_blocksize); |
| |
| reiserfs_warning (fp, "Bitmap blocks are:\n"); |
| block = fs->fs_super_bh->b_blocknr + 1; |
| for (i = 0; i < bmap_nr; i ++) { |
| bh = reiserfs_buffer_read (fs->fs_dev, block, fs->fs_blocksize); |
| if (!bh) { |
| reiserfs_warning (stderr, "reiserfs_bitmap_print: reiserfs_buffer_read " |
| "failed for %d: %lu\n", i, block); |
| continue; |
| } |
| if (i == bmap_nr - 1) |
| if (reiserfs_sb_get_blocks (sb) % bits_per_block) |
| blocks = reiserfs_sb_get_blocks (sb) % bits_per_block; |
| reiserfs_print_bmap_block (fp, i, block, bh->b_data, blocks, |
| silent, fs->fs_blocksize); |
| |
| reiserfs_buffer_close (bh); |
| |
| if (reiserfs_bitmap_spread (fs)) |
| block = (block / (fs->fs_blocksize * 8) + 1) * |
| (fs->fs_blocksize * 8); |
| else { |
| block ++; |
| } |
| } |
| } |