This patch just removes trailing whitespace. Signed-off-by: Jeff Mahoney <jeffm@suse.com>
754 lines
17 KiB
C
754 lines
17 KiB
C
/*
|
|
* 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);
|
|
}
|