diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index f7275176305e..f09a6f6d3ac0 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c @@ -273,7 +273,7 @@ static inline int block_group_used(struct super_block *s, u32 id) * to make a better decision. This favors long-term performace gain * with a better on-disk layout vs. a short term gain of skipping the * read and potentially having a bad placement. */ - if (info->first_zero_hint == 0) { + if (info->free_count == UINT_MAX) { struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); brelse(bh); } @@ -1214,27 +1214,22 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb, { unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); - info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); + /* The first bit must ALWAYS be 1 */ + BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)); + + info->free_count = 0; while (--cur >= (unsigned long *)bh->b_data) { - int base = ((char *)cur - bh->b_data) << 3; + int i; /* 0 and ~0 are special, we can optimize for them */ - if (*cur == 0) { - info->first_zero_hint = base; + if (*cur == 0) info->free_count += BITS_PER_LONG; - } else if (*cur != ~0L) { /* A mix, investigate */ - int b; - for (b = BITS_PER_LONG - 1; b >= 0; b--) { - if (!reiserfs_test_le_bit(b, cur)) { - info->first_zero_hint = base + b; + else if (*cur != ~0L) /* A mix, investigate */ + for (i = BITS_PER_LONG - 1; i >= 0; i--) + if (!reiserfs_test_le_bit(i, cur)) info->free_count++; - } - } - } } - /* The first bit must ALWAYS be 1 */ - BUG_ON(info->first_zero_hint == 0); } struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, @@ -1264,7 +1259,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, BUG_ON(!buffer_uptodate(bh)); BUG_ON(atomic_read(&bh->b_count) == 0); - if (info->first_zero_hint == 0) + if (info->free_count == UINT_MAX) reiserfs_cache_bitmap_metadata(sb, bh, info); } @@ -1279,7 +1274,7 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) if (bitmap == NULL) return -ENOMEM; - memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); + memset(bitmap, 0xff, sizeof(*bitmap) * SB_BMAP_NR(sb)); SB_AP_BITMAP(sb) = bitmap; diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 3bec2f96242a..66f1cda83a81 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c @@ -143,7 +143,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) mark_buffer_dirty(bh); sync_dirty_buffer(bh); // update bitmap_info stuff - bitmap[i].first_zero_hint = 1; bitmap[i].free_count = sb_blocksize(sb) * 8 - 1; brelse(bh); } @@ -173,8 +172,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) for (i = block_r; i < s->s_blocksize * 8; i++) reiserfs_test_and_clear_le_bit(i, bh->b_data); info->free_count += s->s_blocksize * 8 - block_r; - if (!info->first_zero_hint) - info->first_zero_hint = block_r; journal_mark_dirty(&th, s, bh); brelse(bh); @@ -196,9 +193,6 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) brelse(bh); info->free_count -= s->s_blocksize * 8 - block_r_new; - /* Extreme case where last bitmap is the only valid block in itself. */ - if (!info->free_count) - info->first_zero_hint = 0; /* update super */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1); free_blocks = SB_FREE_BLOCKS(s); diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index ff9e9234f8ba..10fa0c832018 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h @@ -265,9 +265,7 @@ enum journal_state_bits { typedef __u32(*hashf_t) (const signed char *, int); struct reiserfs_bitmap_info { - // FIXME: Won't work with block sizes > 8K - __u16 first_zero_hint; - __u16 free_count; + __u32 free_count; }; struct proc_dir_entry;