aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJeff Mahoney <jeffm@suse.com>2006-10-01 02:28:40 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-01 03:39:27 -0400
commite1fabd3ccf02901374bffa434e0af472749a5bd9 (patch)
tree66d618e98020422874a521142ca2da797c9930f3 /fs
parent8ef386092d7c2891bd7acefb2a87f878f7e9a0d6 (diff)
[PATCH] reiserfs: fix is_reusable bitmap check to not traverse the bitmap info array
There is a check in is_reusable to determine if a particular block is a bitmap block. It verifies this by going through the array of bitmap block buffer heads and comparing the block number to each one. Bitmap blocks are at defined locations on the disk in both old and current formats. Simply checking against the known good values is enough. This is a trivial optimization for a non-production codepath, but this is the first in a series of patches that will ultimately remove the buffer heads from that array. Signed-off-by: Jeff Mahoney <jeffm@suse.com> Cc: <reiserfs-dev@namesys.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/reiserfs/bitmap.c40
-rw-r--r--fs/reiserfs/super.c2
2 files changed, 27 insertions, 15 deletions
diff --git a/fs/reiserfs/bitmap.c b/fs/reiserfs/bitmap.c
index 4a7dbdee1b6d..1022347a211f 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
60int is_reusable(struct super_block *s, b_blocknr_t block, int bit_value) 59int 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 80fc3b32802f..db2c581df766 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