aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorBob Peterson <rpeterso@redhat.com>2007-12-11 20:00:16 -0500
committerSteven Whitehouse <swhiteho@redhat.com>2008-01-25 03:13:31 -0500
commit5fdc2eeb5d1d3800367f471690b01fcd1fd5b963 (patch)
treed1e138b18a74541570736f933d938aa7f6e2d376 /fs
parent0d0868bde33273a200b33e54f4fad6099ad0c566 (diff)
[GFS2] Run through full bitmaps quicker in gfs2_bitfit
I eliminated the passing of an unused parameter into gfs2_bitfit called rgd. This also changes the gfs2_bitfit code that searches for free (or used) blocks. Before, the code was trying to check for bytes that indicated 4 blocks in the undesired state. The problem is, it was spending more time trying to do this than it actually was saving. This version only optimizes the case where we're looking for free blocks, and it checks a machine word at a time. So on 32-bit machines, it will check 32-bits (16 blocks) and on 64-bit machines, it will check 64-bits (32 blocks) at a time. The compiler optimizes that quite well and we save some time, especially when running through full bitmaps (like the bitmaps allocated for the journals). There's probably a more elegant or optimized way to do this, but I haven't thought of it yet. I'm open to suggestions. Signed-off-by: Bob Peterson <rpeterso@redhat.com> Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/gfs2/rgrp.c54
1 files changed, 29 insertions, 25 deletions
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index e0ee195558d3..d7ff9cf6653f 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -126,41 +126,46 @@ static unsigned char gfs2_testbit(struct gfs2_rgrpd *rgd, unsigned char *buffer,
126 * Return: the block number (bitmap buffer scope) that was found 126 * Return: the block number (bitmap buffer scope) that was found
127 */ 127 */
128 128
129static u32 gfs2_bitfit(struct gfs2_rgrpd *rgd, unsigned char *buffer, 129static u32 gfs2_bitfit(unsigned char *buffer, unsigned int buflen, u32 goal,
130 unsigned int buflen, u32 goal, 130 unsigned char old_state)
131 unsigned char old_state)
132{ 131{
133 unsigned char *byte, *end, alloc; 132 unsigned char *byte;
134 u32 blk = goal; 133 u32 blk = goal;
135 unsigned int bit; 134 unsigned int bit, bitlong;
135 unsigned long *plong, plong55;
136 static int c = 0;
136 137
137 byte = buffer + (goal / GFS2_NBBY); 138 byte = buffer + (goal / GFS2_NBBY);
139 plong = buffer + (goal / GFS2_NBBY);
138 bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE; 140 bit = (goal % GFS2_NBBY) * GFS2_BIT_SIZE;
139 end = buffer + buflen; 141 bitlong = bit;
140 alloc = (old_state == GFS2_BLKST_FREE) ? 0x55 : 0; 142#if BITS_PER_LONG == 32
141 143 plong55 = 0x55555555;
142 while (byte < end) { 144#else
143 /* If we're looking for a free block we can eliminate all 145 plong55 = 0x5555555555555555;
144 bitmap settings with 0x55, which represents four data 146#endif
145 blocks in a row. If we're looking for a data block, we can 147 while (byte < buffer + buflen) {
146 eliminate 0x00 which corresponds to four free blocks. */ 148
147 if ((*byte & 0x55) == alloc) { 149 if (bitlong == 0 && old_state == 0 && *plong == plong55) {
148 blk += (8 - bit) >> 1; 150 plong++;
149 151 byte += sizeof(unsigned long);
150 bit = 0; 152 blk += sizeof(unsigned long) * GFS2_NBBY;
151 byte++;
152
153 continue; 153 continue;
154 } 154 }
155 155 if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) {
156 if (((*byte >> bit) & GFS2_BIT_MASK) == old_state) 156 c++;
157 return blk; 157 return blk;
158 158 }
159 bit += GFS2_BIT_SIZE; 159 bit += GFS2_BIT_SIZE;
160 if (bit >= 8) { 160 if (bit >= 8) {
161 bit = 0; 161 bit = 0;
162 byte++; 162 byte++;
163 } 163 }
164 bitlong += GFS2_BIT_SIZE;
165 if (bitlong >= sizeof(unsigned long) * 8) {
166 bitlong = 0;
167 plong++;
168 }
164 169
165 blk++; 170 blk++;
166 } 171 }
@@ -1318,11 +1323,10 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
1318 /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone 1323 /* The GFS2_BLKST_UNLINKED state doesn't apply to the clone
1319 bitmaps, so we must search the originals for that. */ 1324 bitmaps, so we must search the originals for that. */
1320 if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone) 1325 if (old_state != GFS2_BLKST_UNLINKED && bi->bi_clone)
1321 blk = gfs2_bitfit(rgd, bi->bi_clone + bi->bi_offset, 1326 blk = gfs2_bitfit(bi->bi_clone + bi->bi_offset,
1322 bi->bi_len, goal, old_state); 1327 bi->bi_len, goal, old_state);
1323 else 1328 else
1324 blk = gfs2_bitfit(rgd, 1329 blk = gfs2_bitfit(bi->bi_bh->b_data + bi->bi_offset,
1325 bi->bi_bh->b_data + bi->bi_offset,
1326 bi->bi_len, goal, old_state); 1330 bi->bi_len, goal, old_state);
1327 if (blk != BFITNOENT) 1331 if (blk != BFITNOENT)
1328 break; 1332 break;