aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/reiserfs/bitmap.c39
-rw-r--r--fs/reiserfs/journal.c6
-rw-r--r--fs/reiserfs/resize.c7
-rw-r--r--fs/reiserfs/super.c15
-rw-r--r--include/linux/reiserfs_fs.h12
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,
61int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) 61int 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,
1269int reiserfs_init_bitmap_cache(struct super_block *sb) 1273int 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. */
288static inline u32 reiserfs_bmap_count(struct super_block *sb)
289{
290 return (SB_BLOCK_COUNT(sb) - 1) / (sb->s_blocksize * 8) + 1;
291}
292
293static 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 ) \