aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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;