diff options
Diffstat (limited to 'fs/reiserfs/bitmap.c')
-rw-r--r-- | fs/reiserfs/bitmap.c | 97 |
1 files changed, 44 insertions, 53 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index abdd6d9c4558..cca1dbf5458f 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -60,7 +60,6 @@ static inline void get_bit_address(struct super_block *s, | |||
60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
61 | { | 61 | { |
62 | int bmap, offset; | 62 | int bmap, offset; |
63 | struct buffer_head *bh; | ||
64 | 63 | ||
65 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 64 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
66 | reiserfs_warning(s, | 65 | reiserfs_warning(s, |
@@ -98,22 +97,6 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
98 | return 0; | 97 | return 0; |
99 | } | 98 | } |
100 | 99 | ||
101 | bh = SB_AP_BITMAP(s)[bmap].bh; | ||
102 | get_bh(bh); | ||
103 | |||
104 | if ((bit_value == 0 && reiserfs_test_le_bit(offset, bh->b_data)) || | ||
105 | (bit_value == 1 && reiserfs_test_le_bit(offset, bh->b_data) == 0)) { | ||
106 | reiserfs_warning(s, | ||
107 | "vs-4040: is_reusable: corresponding bit of block %lu does not " | ||
108 | "match required value (bmap==%d, offset==%d) test_bit==%d", | ||
109 | block, bmap, offset, | ||
110 | reiserfs_test_le_bit(offset, bh->b_data)); | ||
111 | |||
112 | brelse(bh); | ||
113 | return 0; | ||
114 | } | ||
115 | brelse(bh); | ||
116 | |||
117 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { | 100 | if (bit_value == 0 && block == SB_ROOT_BLOCK(s)) { |
118 | reiserfs_warning(s, | 101 | reiserfs_warning(s, |
119 | "vs-4050: is_reusable: this is root block (%u), " | 102 | "vs-4050: is_reusable: this is root block (%u), " |
@@ -173,13 +156,10 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
173 | bmap_n); | 156 | bmap_n); |
174 | return 0; | 157 | return 0; |
175 | } | 158 | } |
176 | bh = bi->bh; | ||
177 | get_bh(bh); | ||
178 | 159 | ||
179 | if (buffer_locked(bh)) { | 160 | bh = reiserfs_read_bitmap_block(s, bmap_n); |
180 | PROC_INFO_INC(s, scan_bitmap.wait); | 161 | if (bh == NULL) |
181 | __wait_on_buffer(bh); | 162 | return 0; |
182 | } | ||
183 | 163 | ||
184 | while (1) { | 164 | while (1) { |
185 | cont: | 165 | cont: |
@@ -285,9 +265,20 @@ static int bmap_hash_id(struct super_block *s, u32 id) | |||
285 | */ | 265 | */ |
286 | static inline int block_group_used(struct super_block *s, u32 id) | 266 | static inline int block_group_used(struct super_block *s, u32 id) |
287 | { | 267 | { |
288 | int bm; | 268 | int bm = bmap_hash_id(s, id); |
289 | bm = bmap_hash_id(s, id); | 269 | struct reiserfs_bitmap_info *info = &SB_AP_BITMAP(s)[bm]; |
290 | if (SB_AP_BITMAP(s)[bm].free_count > ((s->s_blocksize << 3) * 60 / 100)) { | 270 | |
271 | /* If we don't have cached information on this bitmap block, we're | ||
272 | * going to have to load it later anyway. Loading it here allows us | ||
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 | ||
275 | * read and potentially having a bad placement. */ | ||
276 | if (info->first_zero_hint == 0) { | ||
277 | struct buffer_head *bh = reiserfs_read_bitmap_block(s, bm); | ||
278 | brelse(bh); | ||
279 | } | ||
280 | |||
281 | if (info->free_count > ((s->s_blocksize << 3) * 60 / 100)) { | ||
291 | return 0; | 282 | return 0; |
292 | } | 283 | } |
293 | return 1; | 284 | return 1; |
@@ -413,8 +404,9 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
413 | return; | 404 | return; |
414 | } | 405 | } |
415 | 406 | ||
416 | bmbh = apbi[nr].bh; | 407 | bmbh = reiserfs_read_bitmap_block(s, nr); |
417 | get_bh(bmbh); | 408 | if (!bmbh) |
409 | return; | ||
418 | 410 | ||
419 | reiserfs_prepare_for_journal(s, bmbh, 1); | 411 | reiserfs_prepare_for_journal(s, bmbh, 1); |
420 | 412 | ||
@@ -1320,6 +1312,7 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1320 | unsigned int bitmap) | 1312 | unsigned int bitmap) |
1321 | { | 1313 | { |
1322 | b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; | 1314 | b_blocknr_t block = (sb->s_blocksize << 3) * bitmap; |
1315 | struct reiserfs_bitmap_info *info = SB_AP_BITMAP(sb) + bitmap; | ||
1323 | struct buffer_head *bh; | 1316 | struct buffer_head *bh; |
1324 | 1317 | ||
1325 | /* Way old format filesystems had the bitmaps packed up front. | 1318 | /* Way old format filesystems had the bitmaps packed up front. |
@@ -1330,9 +1323,21 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1330 | else if (bitmap == 0) | 1323 | else if (bitmap == 0) |
1331 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; | 1324 | block = (REISERFS_DISK_OFFSET_IN_BYTES >> sb->s_blocksize_bits) + 1; |
1332 | 1325 | ||
1333 | bh = sb_getblk(sb, block); | 1326 | bh = sb_bread(sb, block); |
1334 | if (!buffer_uptodate(bh)) | 1327 | if (bh == NULL) |
1335 | ll_rw_block(READ, 1, &bh); | 1328 | reiserfs_warning(sb, "sh-2029: %s: bitmap block (#%lu) " |
1329 | "reading failed", __FUNCTION__, bh->b_blocknr); | ||
1330 | else { | ||
1331 | if (buffer_locked(bh)) { | ||
1332 | PROC_INFO_INC(sb, scan_bitmap.wait); | ||
1333 | __wait_on_buffer(bh); | ||
1334 | } | ||
1335 | BUG_ON(!buffer_uptodate(bh)); | ||
1336 | BUG_ON(atomic_read(&bh->b_count) == 0); | ||
1337 | |||
1338 | if (info->first_zero_hint == 0) | ||
1339 | reiserfs_cache_bitmap_metadata(sb, bh, info); | ||
1340 | } | ||
1336 | 1341 | ||
1337 | return bh; | 1342 | return bh; |
1338 | } | 1343 | } |
@@ -1340,7 +1345,6 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1340 | int reiserfs_init_bitmap_cache(struct super_block *sb) | 1345 | int reiserfs_init_bitmap_cache(struct super_block *sb) |
1341 | { | 1346 | { |
1342 | struct reiserfs_bitmap_info *bitmap; | 1347 | struct reiserfs_bitmap_info *bitmap; |
1343 | int i; | ||
1344 | 1348 | ||
1345 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1349 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); |
1346 | if (bitmap == NULL) | 1350 | if (bitmap == NULL) |
@@ -1348,28 +1352,15 @@ int reiserfs_init_bitmap_cache(struct super_block *sb) | |||
1348 | 1352 | ||
1349 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1353 | memset(bitmap, 0, sizeof (*bitmap) * SB_BMAP_NR(sb)); |
1350 | 1354 | ||
1351 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1352 | bitmap[i].bh = reiserfs_read_bitmap_block(sb, i); | ||
1353 | |||
1354 | /* make sure we have them all */ | ||
1355 | for (i = 0; i < SB_BMAP_NR(sb); i++) { | ||
1356 | wait_on_buffer(bitmap[i].bh); | ||
1357 | if (!buffer_uptodate(bitmap[i].bh)) { | ||
1358 | reiserfs_warning(sb, "sh-2029: %s: " | ||
1359 | "bitmap block (#%lu) reading failed", | ||
1360 | __FUNCTION__, bitmap[i].bh->b_blocknr); | ||
1361 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1362 | brelse(bitmap[i].bh); | ||
1363 | vfree(bitmap); | ||
1364 | return -EIO; | ||
1365 | } | ||
1366 | } | ||
1367 | |||
1368 | /* Cache the info on the bitmaps before we get rolling */ | ||
1369 | for (i = 0; i < SB_BMAP_NR(sb); i++) | ||
1370 | reiserfs_cache_bitmap_metadata(sb, bitmap[i].bh, &bitmap[i]); | ||
1371 | |||
1372 | SB_AP_BITMAP(sb) = bitmap; | 1355 | SB_AP_BITMAP(sb) = bitmap; |
1373 | 1356 | ||
1374 | return 0; | 1357 | return 0; |
1375 | } | 1358 | } |
1359 | |||
1360 | void reiserfs_free_bitmap_cache(struct super_block *sb) | ||
1361 | { | ||
1362 | if (SB_AP_BITMAP(sb)) { | ||
1363 | vfree(SB_AP_BITMAP(sb)); | ||
1364 | SB_AP_BITMAP(sb) = NULL; | ||
1365 | } | ||
1366 | } | ||