diff options
Diffstat (limited to 'fs/reiserfs/bitmap.c')
-rw-r--r-- | fs/reiserfs/bitmap.c | 29 |
1 files changed, 12 insertions, 17 deletions
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) | |||
273 | * to make a better decision. This favors long-term performace gain | 273 | * to make a better decision. This favors long-term performace gain |
274 | * with a better on-disk layout vs. a short term gain of skipping the | 274 | * with a better on-disk layout vs. a short term gain of skipping the |
275 | * read and potentially having a bad placement. */ | 275 | * read and potentially having a bad placement. */ |
276 | if (info->first_zero_hint == 0) { | 276 | if (info->free_count == UINT_MAX) { |
277 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); | 277 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); |
278 | brelse(bh); | 278 | brelse(bh); |
279 | } | 279 | } |
@@ -1214,27 +1214,22 @@ void reiserfs_cache_bitmap_metadata(struct super_block *sb, | |||
1214 | { | 1214 | { |
1215 | unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); | 1215 | unsigned long *cur = (unsigned long *)(bh->b_data + bh->b_size); |
1216 | 1216 | ||
1217 | info->first_zero_hint = 1 << (sb->s_blocksize_bits + 3); | 1217 | /* The first bit must ALWAYS be 1 */ |
1218 | BUG_ON(!reiserfs_test_le_bit(0, (unsigned long *)bh->b_data)); | ||
1219 | |||
1220 | info->free_count = 0; | ||
1218 | 1221 | ||
1219 | while (--cur >= (unsigned long *)bh->b_data) { | 1222 | while (--cur >= (unsigned long *)bh->b_data) { |
1220 | int base = ((char *)cur - bh->b_data) << 3; | 1223 | int i; |
1221 | 1224 | ||
1222 | /* 0 and ~0 are special, we can optimize for them */ | 1225 | /* 0 and ~0 are special, we can optimize for them */ |
1223 | if (*cur == 0) { | 1226 | if (*cur == 0) |
1224 | info->first_zero_hint = base; | ||
1225 | info->free_count += BITS_PER_LONG; | 1227 | info->free_count += BITS_PER_LONG; |
1226 | } else if (*cur != ~0L) { /* A mix, investigate */ | 1228 | else if (*cur != ~0L) /* A mix, investigate */ |
1227 | int b; | 1229 | for (i = BITS_PER_LONG - 1; i >= 0; i--) |
1228 | for (b = BITS_PER_LONG - 1; b >= 0; b--) { | 1230 | if (!reiserfs_test_le_bit(i, cur)) |
1229 | if (!reiserfs_test_le_bit(b, cur)) { | ||
1230 | info->first_zero_hint = base + b; | ||
1231 | info->free_count++; | 1231 | info->free_count++; |
1232 | } | ||
1233 | } | ||
1234 | } | ||
1235 | } | 1232 | } |
1236 | /* The first bit must ALWAYS be 1 */ | ||
1237 | BUG_ON(info->first_zero_hint == 0); | ||
1238 | } | 1233 | } |
1239 | 1234 | ||
1240 | struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | 1235 | 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, | |||
1264 | BUG_ON(!buffer_uptodate(bh)); | 1259 | BUG_ON(!buffer_uptodate(bh)); |
1265 | BUG_ON(atomic_read(&bh->b_count) == 0); | 1260 | BUG_ON(atomic_read(&bh->b_count) == 0); |
1266 | 1261 | ||
1267 | if (info->first_zero_hint == 0) | 1262 | if (info->free_count == UINT_MAX) |
1268 | reiserfs_cache_bitmap_metadata(sb, bh, info); | 1263 | reiserfs_cache_bitmap_metadata(sb, bh, info); |
1269 | } | 1264 | } |
1270 | 1265 | ||
@@ -1279,7 +1274,7 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
1279 | if (bitmap == NULL) | 1274 | if (bitmap == NULL) |
1280 | return -ENOMEM; | 1275 | return -ENOMEM; |
1281 | 1276 | ||
1282 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1277 | memset(bitmap, 0xff, sizeof(*bitmap) * SB_BMAP_NR(sb)); |
1283 | 1278 | ||
1284 | SB_AP_BITMAP(sb) = bitmap; | 1279 | SB_AP_BITMAP(sb) = bitmap; |
1285 | 1280 | ||