diff options
-rw-r--r-- | fs/reiserfs/bitmap.c | 39 | ||||
-rw-r--r-- | fs/reiserfs/journal.c | 6 | ||||
-rw-r--r-- | fs/reiserfs/resize.c | 7 | ||||
-rw-r--r-- | fs/reiserfs/super.c | 15 | ||||
-rw-r--r-- | include/linux/reiserfs_fs.h | 12 |
5 files changed, 56 insertions, 23 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c index f09a6f6d3ac0..16b331dd9913 100644 --- a/fs/reiserfs/bitmap.c +++ b/fs/reiserfs/bitmap.c | |||
@@ -61,6 +61,7 @@ static inline void get_bit_address(struct super_block *s, | |||
61 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | 61 | int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) |
62 | { | 62 | { |
63 | unsigned int bmap, offset; | 63 | unsigned int bmap, offset; |
64 | unsigned int bmap_count = reiserfs_bmap_count(s); | ||
64 | 65 | ||
65 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { | 66 | if (block == 0 || block >= SB_BLOCK_COUNT(s)) { |
66 | reiserfs_warning(s, | 67 | reiserfs_warning(s, |
@@ -76,25 +77,26 @@ int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) | |||
76 | if (unlikely(test_bit(REISERFS_OLD_FORMAT, | 77 | if (unlikely(test_bit(REISERFS_OLD_FORMAT, |
77 | &(REISERFS_SB(s)->s_properties)))) { | 78 | &(REISERFS_SB(s)->s_properties)))) { |
78 | b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; | 79 | b_blocknr_t bmap1 = REISERFS_SB(s)->s_sbh->b_blocknr + 1; |
79 | if (block >= bmap1 && block <= bmap1 + SB_BMAP_NR(s)) { | 80 | if (block >= bmap1 && |
81 | block <= bmap1 + bmap_count) { | ||
80 | reiserfs_warning(s, "vs: 4019: is_reusable: " | 82 | reiserfs_warning(s, "vs: 4019: is_reusable: " |
81 | "bitmap block %lu(%u) can't be freed or reused", | 83 | "bitmap block %lu(%u) can't be freed or reused", |
82 | block, SB_BMAP_NR(s)); | 84 | block, bmap_count); |
83 | return 0; | 85 | return 0; |
84 | } | 86 | } |
85 | } else { | 87 | } else { |
86 | if (offset == 0) { | 88 | if (offset == 0) { |
87 | reiserfs_warning(s, "vs: 4020: is_reusable: " | 89 | reiserfs_warning(s, "vs: 4020: is_reusable: " |
88 | "bitmap block %lu(%u) can't be freed or reused", | 90 | "bitmap block %lu(%u) can't be freed or reused", |
89 | block, SB_BMAP_NR(s)); | 91 | block, bmap_count); |
90 | return 0; | 92 | return 0; |
91 | } | 93 | } |
92 | } | 94 | } |
93 | 95 | ||
94 | if (bmap >= SB_BMAP_NR(s)) { | 96 | if (bmap >= bmap_count) { |
95 | reiserfs_warning(s, | 97 | reiserfs_warning(s, |
96 | "vs-4030: is_reusable: there is no so many bitmap blocks: " | 98 | "vs-4030: is_reusable: there is no so many bitmap blocks: " |
97 | "block=%lu, bitmap_nr=%d", block, bmap); | 99 | "block=%lu, bitmap_nr=%u", block, bmap); |
98 | return 0; | 100 | return 0; |
99 | } | 101 | } |
100 | 102 | ||
@@ -143,8 +145,8 @@ static int scan_bitmap_block(struct reiserfs_transaction_handle *th, | |||
143 | 145 | ||
144 | BUG_ON(!th->t_trans_id); | 146 | BUG_ON(!th->t_trans_id); |
145 | 147 | ||
146 | RFALSE(bmap_n >= SB_BMAP_NR(s), "Bitmap %d is out of range (0..%d)", | 148 | RFALSE(bmap_n >= reiserfs_bmap_count(s), "Bitmap %u is out of " |
147 | bmap_n, SB_BMAP_NR(s) - 1); | 149 | "range (0..%u)", bmap_n, reiserfs_bmap_count(s) - 1); |
148 | PROC_INFO_INC(s, scan_bitmap.bmap); | 150 | PROC_INFO_INC(s, scan_bitmap.bmap); |
149 | /* this is unclear and lacks comments, explain how journal bitmaps | 151 | /* this is unclear and lacks comments, explain how journal bitmaps |
150 | work here for the reader. Convey a sense of the design here. What | 152 | work here for the reader. Convey a sense of the design here. What |
@@ -249,12 +251,12 @@ static int bmap_hash_id(struct super_block *s, u32 id) | |||
249 | } else { | 251 | } else { |
250 | hash_in = (char *)(&id); | 252 | hash_in = (char *)(&id); |
251 | hash = keyed_hash(hash_in, 4); | 253 | hash = keyed_hash(hash_in, 4); |
252 | bm = hash % SB_BMAP_NR(s); | 254 | bm = hash % reiserfs_bmap_count(s); |
253 | if (!bm) | 255 | if (!bm) |
254 | bm = 1; | 256 | bm = 1; |
255 | } | 257 | } |
256 | /* this can only be true when SB_BMAP_NR = 1 */ | 258 | /* this can only be true when SB_BMAP_NR = 1 */ |
257 | if (bm >= SB_BMAP_NR(s)) | 259 | if (bm >= reiserfs_bmap_count(s)) |
258 | bm = 0; | 260 | bm = 0; |
259 | return bm; | 261 | return bm; |
260 | } | 262 | } |
@@ -328,10 +330,10 @@ static int scan_bitmap(struct reiserfs_transaction_handle *th, | |||
328 | 330 | ||
329 | get_bit_address(s, *start, &bm, &off); | 331 | get_bit_address(s, *start, &bm, &off); |
330 | get_bit_address(s, finish, &end_bm, &end_off); | 332 | get_bit_address(s, finish, &end_bm, &end_off); |
331 | if (bm > SB_BMAP_NR(s)) | 333 | if (bm > reiserfs_bmap_count(s)) |
332 | return 0; | 334 | return 0; |
333 | if (end_bm > SB_BMAP_NR(s)) | 335 | if (end_bm > reiserfs_bmap_count(s)) |
334 | end_bm = SB_BMAP_NR(s); | 336 | end_bm = reiserfs_bmap_count(s); |
335 | 337 | ||
336 | /* When the bitmap is more than 10% free, anyone can allocate. | 338 | /* When the bitmap is more than 10% free, anyone can allocate. |
337 | * When it's less than 10% free, only files that already use the | 339 | * When it's less than 10% free, only files that already use the |
@@ -397,10 +399,12 @@ static void _reiserfs_free_block(struct reiserfs_transaction_handle *th, | |||
397 | 399 | ||
398 | get_bit_address(s, block, &nr, &offset); | 400 | get_bit_address(s, block, &nr, &offset); |
399 | 401 | ||
400 | if (nr >= sb_bmap_nr(rs)) { | 402 | if (nr >= reiserfs_bmap_count(s)) { |
401 | reiserfs_warning(s, "vs-4075: reiserfs_free_block: " | 403 | reiserfs_warning(s, "vs-4075: reiserfs_free_block: " |
402 | "block %lu is out of range on %s", | 404 | "block %lu is out of range on %s " |
403 | block, reiserfs_bdevname(s)); | 405 | "(nr=%u,max=%u)", block, |
406 | reiserfs_bdevname(s), nr, | ||
407 | reiserfs_bmap_count(s)); | ||
404 | return; | 408 | return; |
405 | } | 409 | } |
406 | 410 | ||
@@ -1269,12 +1273,13 @@ struct buffer_head *reiserfs_read_bitmap_block(struct super_block *sb, | |||
1269 | int reiserfs_init_bitmap_cache(struct super_block *sb) | 1273 | int reiserfs_init_bitmap_cache(struct super_block *sb) |
1270 | { | 1274 | { |
1271 | struct reiserfs_bitmap_info *bitmap; | 1275 | struct reiserfs_bitmap_info *bitmap; |
1276 | unsigned int bmap_nr = reiserfs_bmap_count(sb); | ||
1272 | 1277 | ||
1273 | bitmap = vmalloc(sizeof (*bitmap) * SB_BMAP_NR(sb)); | 1278 | bitmap = vmalloc(sizeof(*bitmap) * bmap_nr); |
1274 | if (bitmap == NULL) | 1279 | if (bitmap == NULL) |
1275 | return -ENOMEM; | 1280 | return -ENOMEM; |
1276 | 1281 | ||
1277 | memset(bitmap, 0xff, sizeof(*bitmap) * SB_BMAP_NR(sb)); | 1282 | memset(bitmap, 0xff, sizeof(*bitmap) * bmap_nr); |
1278 | 1283 | ||
1279 | SB_AP_BITMAP(sb) = bitmap; | 1284 | SB_AP_BITMAP(sb) = bitmap; |
1280 | 1285 | ||
diff --git a/fs/reiserfs/journal.c b/fs/reiserfs/journal.c index 0e30ba0ac489..bb05a3e51b93 100644 --- a/fs/reiserfs/journal.c +++ b/fs/reiserfs/journal.c | |||
@@ -240,7 +240,7 @@ static void cleanup_bitmap_list(struct super_block *p_s_sb, | |||
240 | if (jb->bitmaps == NULL) | 240 | if (jb->bitmaps == NULL) |
241 | return; | 241 | return; |
242 | 242 | ||
243 | for (i = 0; i < SB_BMAP_NR(p_s_sb); i++) { | 243 | for (i = 0; i < reiserfs_bmap_count(p_s_sb); i++) { |
244 | if (jb->bitmaps[i]) { | 244 | if (jb->bitmaps[i]) { |
245 | free_bitmap_node(p_s_sb, jb->bitmaps[i]); | 245 | free_bitmap_node(p_s_sb, jb->bitmaps[i]); |
246 | jb->bitmaps[i] = NULL; | 246 | jb->bitmaps[i] = NULL; |
@@ -2734,7 +2734,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2734 | journal->j_persistent_trans = 0; | 2734 | journal->j_persistent_trans = 0; |
2735 | if (reiserfs_allocate_list_bitmaps(p_s_sb, | 2735 | if (reiserfs_allocate_list_bitmaps(p_s_sb, |
2736 | journal->j_list_bitmap, | 2736 | journal->j_list_bitmap, |
2737 | SB_BMAP_NR(p_s_sb))) | 2737 | reiserfs_bmap_count(p_s_sb))) |
2738 | goto free_and_return; | 2738 | goto free_and_return; |
2739 | allocate_bitmap_nodes(p_s_sb); | 2739 | allocate_bitmap_nodes(p_s_sb); |
2740 | 2740 | ||
@@ -2742,7 +2742,7 @@ int journal_init(struct super_block *p_s_sb, const char *j_dev_name, | |||
2742 | SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? | 2742 | SB_JOURNAL_1st_RESERVED_BLOCK(p_s_sb) = (old_format ? |
2743 | REISERFS_OLD_DISK_OFFSET_IN_BYTES | 2743 | REISERFS_OLD_DISK_OFFSET_IN_BYTES |
2744 | / p_s_sb->s_blocksize + | 2744 | / p_s_sb->s_blocksize + |
2745 | SB_BMAP_NR(p_s_sb) + | 2745 | reiserfs_bmap_count(p_s_sb) + |
2746 | 1 : | 2746 | 1 : |
2747 | REISERFS_DISK_OFFSET_IN_BYTES / | 2747 | REISERFS_DISK_OFFSET_IN_BYTES / |
2748 | p_s_sb->s_blocksize + 2); | 2748 | p_s_sb->s_blocksize + 2); |
diff --git a/fs/reiserfs/resize.c b/fs/reiserfs/resize.c index 66f1cda83a81..f71c3948edef 100644 --- a/fs/reiserfs/resize.c +++ b/fs/reiserfs/resize.c | |||
@@ -61,7 +61,8 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
61 | } | 61 | } |
62 | 62 | ||
63 | /* count used bits in last bitmap block */ | 63 | /* count used bits in last bitmap block */ |
64 | block_r = SB_BLOCK_COUNT(s) - (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8; | 64 | block_r = SB_BLOCK_COUNT(s) - |
65 | (reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8; | ||
65 | 66 | ||
66 | /* count bitmap blocks in new fs */ | 67 | /* count bitmap blocks in new fs */ |
67 | bmap_nr_new = block_count_new / (s->s_blocksize * 8); | 68 | bmap_nr_new = block_count_new / (s->s_blocksize * 8); |
@@ -73,7 +74,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
73 | 74 | ||
74 | /* save old values */ | 75 | /* save old values */ |
75 | block_count = SB_BLOCK_COUNT(s); | 76 | block_count = SB_BLOCK_COUNT(s); |
76 | bmap_nr = SB_BMAP_NR(s); | 77 | bmap_nr = reiserfs_bmap_count(s); |
77 | 78 | ||
78 | /* resizing of reiserfs bitmaps (journal and real), if needed */ | 79 | /* resizing of reiserfs bitmaps (journal and real), if needed */ |
79 | if (bmap_nr_new > bmap_nr) { | 80 | if (bmap_nr_new > bmap_nr) { |
@@ -200,7 +201,7 @@ int reiserfs_resize(struct super_block *s, unsigned long block_count_new) | |||
200 | free_blocks + (block_count_new - block_count - | 201 | free_blocks + (block_count_new - block_count - |
201 | (bmap_nr_new - bmap_nr))); | 202 | (bmap_nr_new - bmap_nr))); |
202 | PUT_SB_BLOCK_COUNT(s, block_count_new); | 203 | PUT_SB_BLOCK_COUNT(s, block_count_new); |
203 | PUT_SB_BMAP_NR(s, bmap_nr_new); | 204 | PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new); |
204 | s->s_dirt = 1; | 205 | s->s_dirt = 1; |
205 | 206 | ||
206 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); | 207 | journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s)); |
diff --git a/fs/reiserfs/super.c b/fs/reiserfs/super.c index b82897ae090b..57adfe90d5ae 100644 --- a/fs/reiserfs/super.c +++ b/fs/reiserfs/super.c | |||
@@ -1725,6 +1725,21 @@ static int reiserfs_fill_super(struct super_block *s, void *data, int silent) | |||
1725 | set_sb_umount_state(rs, REISERFS_ERROR_FS); | 1725 | set_sb_umount_state(rs, REISERFS_ERROR_FS); |
1726 | set_sb_fs_state(rs, 0); | 1726 | set_sb_fs_state(rs, 0); |
1727 | 1727 | ||
1728 | /* Clear out s_bmap_nr if it would wrap. We can handle this | ||
1729 | * case, but older revisions can't. This will cause the | ||
1730 | * file system to fail mount on those older implementations, | ||
1731 | * avoiding corruption. -jeffm */ | ||
1732 | if (bmap_would_wrap(reiserfs_bmap_count(s)) && | ||
1733 | sb_bmap_nr(rs) != 0) { | ||
1734 | reiserfs_warning(s, "super-2030: This file system " | ||
1735 | "claims to use %u bitmap blocks in " | ||
1736 | "its super block, but requires %u. " | ||
1737 | "Clearing to zero.", sb_bmap_nr(rs), | ||
1738 | reiserfs_bmap_count(s)); | ||
1739 | |||
1740 | set_sb_bmap_nr(rs, 0); | ||
1741 | } | ||
1742 | |||
1728 | if (old_format_only(s)) { | 1743 | if (old_format_only(s)) { |
1729 | /* filesystem of format 3.5 either with standard or non-standard | 1744 | /* filesystem of format 3.5 either with standard or non-standard |
1730 | journal */ | 1745 | journal */ |
diff --git a/include/linux/reiserfs_fs.h b/include/linux/reiserfs_fs.h index 69a3e12cb8c8..d8653bf232e3 100644 --- a/include/linux/reiserfs_fs.h +++ b/include/linux/reiserfs_fs.h | |||
@@ -283,6 +283,18 @@ static inline struct reiserfs_sb_info *REISERFS_SB(const struct super_block *sb) | |||
283 | return sb->s_fs_info; | 283 | return sb->s_fs_info; |
284 | } | 284 | } |
285 | 285 | ||
286 | /* Don't trust REISERFS_SB(sb)->s_bmap_nr, it's a u16 | ||
287 | * which overflows on large file systems. */ | ||
288 | static inline u32 reiserfs_bmap_count(struct super_block *sb) | ||
289 | { | ||
290 | return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1; | ||
291 | } | ||
292 | |||
293 | static inline int bmap_would_wrap(unsigned bmap_nr) | ||
294 | { | ||
295 | return bmap_nr > ((1LL << 16) - 1); | ||
296 | } | ||
297 | |||
286 | /** this says about version of key of all items (but stat data) the | 298 | /** this says about version of key of all items (but stat data) the |
287 | object consists of */ | 299 | object consists of */ |
288 | #define get_inode_item_key_version( inode ) \ | 300 | #define get_inode_item_key_version( inode ) \ |