diff options
-rw-r--r-- | fs/reiserfs/bitmap.c | 40 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 2 | ||||
-rw-r--r-- | include/linux/reiserfs_fs_sb.h | 1 |
3 files changed, 28 insertions, 15 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index 4a7dbdee1b6..1022347a211 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -50,16 +50,15 @@ static inline void get_bit_address(struct super_block *s, | |||
50 | { | 50 | { |
51 | /* It is in the bitmap block number equal to the block | 51 | /* It is in the bitmap block number equal to the block |
52 | * number divided by the number of bits in a block. */ | 52 | * number divided by the number of bits in a block. */ |
53 | *bmap_nr = block / (s->s_blocksize << 3); | 53 | *bmap_nr = block >> (s->s_blocksize_bits + 3); |
54 | /* Within that bitmap block it is located at bit offset *offset. */ | 54 | /* Within that bitmap block it is located at bit offset *offset. */ |
55 | *offset = block & ((s->s_blocksize << 3) - 1); | 55 | *offset = block & ((s->s_blocksize << 3) - 1); |
56 | return; | ||
57 | } | 56 | } |
58 | 57 | ||
59 | #ifdef CONFIG_REISERFS_CHECK | 58 | #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 i, j; | 61 | int bmap, offset; |
63 | 62 | ||
64 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 63 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
65 | reiserfs_warning(s, | 64 | reiserfs_warning(s, |
@@ -68,34 +67,45 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
68 | return 0; | 67 | return 0; |
69 | } | 68 | } |
70 | 69 | ||
71 | /* it can't be one of the bitmap blocks */ | 70 | get_bit_address(s, block, &bmap, &offset); |
72 | for (i = 0; i < SB_BMAP_NR(s); i++) | 71 | |
73 | if (block == SB_AP_BITMAP(s)[i].bh->b_blocknr) { | 72 | /* Old format filesystem? Unlikely, but the bitmaps are all up front so |
73 | * we need to account for it. */ | ||
74 | if (unlikely(test_bit(REISERFS_OLD_FORMAT, | ||
75 | &(REISERFS_SB(s)->s_properties)))) { | ||
76 | b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; | ||
77 | if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { | ||
78 | reiserfs_warning(s, "vs: 4019: is_reusable: " | ||
79 | "bitmap block %lu(%u) can't be freed or reused", | ||
80 | block, SB_BMAP_NR(s)); | ||
81 | return 0; | ||
82 | } | ||
83 | } else { | ||
84 | if (offset == 0) { | ||
74 | reiserfs_warning(s, "vs: 4020: is_reusable: " | 85 | reiserfs_warning(s, "vs: 4020: is_reusable: " |
75 | "bitmap block %lu(%u) can't be freed or reused", | 86 | "bitmap block %lu(%u) can't be freed or reused", |
76 | block, SB_BMAP_NR(s)); | 87 | block, SB_BMAP_NR(s)); |
77 | return 0; | 88 | return 0; |
78 | } | 89 | } |
90 | } | ||
79 | 91 | ||
80 | get_bit_address(s, block, &i, &j); | 92 | if (bmap >= SB_BMAP_NR(s)) { |
81 | |||
82 | if (i >= SB_BMAP_NR(s)) { | ||
83 | reiserfs_warning(s, | 93 | reiserfs_warning(s, |
84 | "vs-4030: is_reusable: there is no so many bitmap blocks: " | 94 | "vs-4030: is_reusable: there is no so many bitmap blocks: " |
85 | "block=%lu, bitmap_nr=%d", block, i); | 95 | "block=%lu, bitmap_nr=%d", block, bmap); |
86 | return 0; | 96 | return 0; |
87 | } | 97 | } |
88 | 98 | ||
89 | if ((bit_value == 0 && | 99 | if ((bit_value == 0 && |
90 | reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data)) || | 100 | reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data)) || |
91 | (bit_value == 1 && | 101 | (bit_value == 1 && |
92 | reiserfs_test_le_bit(j, SB_AP_BITMAP(s)[i].bh->b_data) == 0)) { | 102 | reiserfs_test_le_bit(offset, SB_AP_BITMAP(s)[bmap].bh->b_data) == 0)) { |
93 | reiserfs_warning(s, | 103 | reiserfs_warning(s, |
94 | "vs-4040: is_reusable: corresponding bit of block %lu does not " | 104 | "vs-4040: is_reusable: corresponding bit of block %lu does not " |
95 | "match required value (i==%d, j==%d) test_bit==%d", | 105 | "match required value (bmap==%d, offset==%d) test_bit==%d", |
96 | block, i, j, reiserfs_test_le_bit(j, | 106 | block, bmap, offset, reiserfs_test_le_bit(offset, |
97 | SB_AP_BITMAP | 107 | SB_AP_BITMAP |
98 | (s)[i].bh-> | 108 | (s)[bmap].bh-> |
99 | b_data)); | 109 | b_data)); |
100 | 110 | ||
101 | return 0; | 111 | return 0; |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index 80fc3b32802..db2c581df76 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -1818,6 +1818,8 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1818 | if (is_reiserfs_3_5(rs) | 1818 | if (is_reiserfs_3_5(rs) |
1819 | || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1)) | 1819 | || (is_reiserfs_jr(rs) && SB_VERSION(s) == REISERFS_VERSION_1)) |
1820 | set_bit(REISERFS_3_5, &(sbi->s_properties)); | 1820 | set_bit(REISERFS_3_5, &(sbi->s_properties)); |
1821 | else if (old_format) | ||
1822 | set_bit(REISERFS_OLD_FORMAT, &(sbi->s_properties)); | ||
1821 | else | 1823 | else |
1822 | set_bit(REISERFS_3_6, &(sbi->s_properties)); | 1824 | set_bit(REISERFS_3_6, &(sbi->s_properties)); |
1823 | 1825 | ||
diff --git a/include/linux/reiserfs_fs_sb.h b/include/linux/reiserfs_fs_sb.h index 31b4c0bd4fa..4f21ad388c7 100644 --- a/include/linux/reiserfs_fs_sb.h +++ b/include/linux/reiserfs_fs_sb.h | |||
@@ -414,6 +414,7 @@ struct reiserfs_sb_info { | |||
414 | /* Definitions of reiserfs on-disk properties: */ | 414 | /* Definitions of reiserfs on-disk properties: */ |
415 | #define REISERFS_3_5 0 | 415 | #define REISERFS_3_5 0 |
416 | #define REISERFS_3_6 1 | 416 | #define REISERFS_3_6 1 |
417 | #define REISERFS_OLD_FORMAT 2 | ||
417 | 418 | ||
418 | enum reiserfs_mount_options { | 419 | enum reiserfs_mount_options { |
419 | /* Mount options */ | 420 | /* Mount options */ |