diff options
author | Jeff Mahoney <jeffm@suse.com> | 2007-10-19 02:39:24 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-19 14:53:35 -0400 |
commit | d4c3d19d0c10701459f16c022ea23eff5e127747 (patch) | |
tree | d0128bae0543585e8c1bfce7f3c375842c55b46c /fs/reiserfs/bitmap.c | |
parent | 8e186e454e871678c01b7eec4da5865111076095 (diff) |
reiserfs: use is_reusable to catch corruption
Build in is_reusable() unconditionally and use it to catch corruption before
it reaches the block freeing paths.
Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/reiserfs/bitmap.c')
-rw-r--r-- | fs/reiserfs/bitmap.c | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 2a5dd34649b3..28a1b06081fc 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -56,7 +56,6 @@ static inline void get_bit_address(struct super_block *s, | |||
56 | *offset = block & ((s->s_blocksize << 3) - 1); | 56 | *offset = block & ((s->s_blocksize << 3) - 1); |
57 | } | 57 | } |
58 | 58 | ||
59 | #ifdef CONFIG_REISERFS_CHECK | ||
60 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 59 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
61 | { | 60 | { |
62 | int bmap, offset; | 61 | int bmap, offset; |
@@ -106,7 +105,6 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
106 | 105 | ||
107 | return 1; | 106 | return 1; |
108 | } | 107 | } |
109 | #endif /* CONFIG_REISERFS_CHECK */ | ||
110 | 108 | ||
111 | /* searches in journal structures for a given block number (bmap, off). If block | 109 | /* searches in journal structures for a given block number (bmap, off). If block |
112 | is found in reiserfs journal it suggests next free block candidate to test. */ | 110 | is found in reiserfs journal it suggests next free block candidate to test. */ |
@@ -434,12 +432,19 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
434 | int for_unformatted) | 432 | int for_unformatted) |
435 | { | 433 | { |
436 | struct super_block *s = th->t_super; | 434 | struct super_block *s = th->t_super; |
437 | |||
438 | BUG_ON(!th->t_trans_id); | 435 | BUG_ON(!th->t_trans_id); |
439 | 436 | ||
440 | RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); | 437 | RFALSE(!s, "vs-4061: trying to free block on nonexistent device"); |
441 | RFALSE(is_reusable(s, block, 1) == 0, | 438 | if (!is_reusable(s, block, 1)) |
442 | "vs-4071: can not free such block"); | 439 | return; |
440 | |||
441 | if (block > sb_block_count(REISERFS_SB(s)->s_rs)) { | ||
442 | reiserfs_panic(th->t_super, "bitmap-4072", | ||
443 | "Trying to free block outside file system " | ||
444 | "boundaries (%lu > %lu)", | ||
445 | block, sb_block_count(REISERFS_SB(s)->s_rs)); | ||
446 | return; | ||
447 | } | ||
443 | /* mark it before we clear it, just in case */ | 448 | /* mark it before we clear it, just in case */ |
444 | journal_mark_freed(th, s, block); | 449 | journal_mark_freed(th, s, block); |
445 | _reiserfs_free_block(th, inode, block, for_unformatted); | 450 | _reiserfs_free_block(th, inode, block, for_unformatted); |
@@ -449,11 +454,11 @@ void reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
449 | static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th, | 454 | static void reiserfs_free_prealloc_block(struct reiserfs_transaction_handle *th, |
450 | struct inode *inode, b_blocknr_t block) | 455 | struct inode *inode, b_blocknr_t block) |
451 | { | 456 | { |
457 | BUG_ON(!th->t_trans_id); | ||
452 | RFALSE(!th->t_super, | 458 | RFALSE(!th->t_super, |
453 | "vs-4060: trying to free block on nonexistent device"); | 459 | "vs-4060: trying to free block on nonexistent device"); |
454 | RFALSE(is_reusable(th->t_super, block, 1) == 0, | 460 | if (!is_reusable(th->t_super, block, 1)) |
455 | "vs-4070: can not free such block"); | 461 | return; |
456 | BUG_ON(!th->t_trans_id); | ||
457 | _reiserfs_free_block(th, inode, block, 1); | 462 | _reiserfs_free_block(th, inode, block, 1); |
458 | } | 463 | } |
459 | 464 | ||